testing

Benchmark created on


Test runner

Ready to run.

Testing in
TestOps/sec
t1

/*cocktail library created at 2/3/2023 - Devloped by yousef sayed*/
export function $(element = "string") {
  return document.querySelector(element);
}

export function $a(elements = "string") {
  return document.querySelectorAll(elements);
}

export function cre({ elementType, className, id, src, href, type = "", placeholder, where = document, prepend = false, replace = false }) {
  let el = document.createElement(elementType)
  console.log(el);
  if (className) { el.className = className };
  if (id) { el.id = id };
  if (src) { el.src = src };
  if (href) { el.href = href };
  if (placeholder) { el.placeholder = placeholder };
  if (where) { where.appendChild(el) };
  if (prepend) { where.prepend(el); }
  if (type) { el.type = type; }
  return el;
}

export function setOnInObjectProto() {
  Element.prototype.on = function (type = "string", callback = () => { }) {
    this.addEventListener(type, callback)
  }
}


export class MakeAudioRecorder {
  constructor() {

    const stream = navigator.mediaDevices.getUserMedia({ audio: true });
    let record, blob, url;

    this.getStream = async function getStream() {
      return await stream;
    }

    this.startRecord = async function startRecord() {
      record = new MediaRecorder(await stream);
      record.start();
      this.isStream = record.state == 'recording' ? true : false;
    }

    async function stopStream() {
      let stream2 = await stream;
      const tracks = stream2.getTracks();
      record.addEventListener("stop", () => {
        for (let i = 0; i < tracks.length; i++) {
          tracks[i].stop();
        }
      });
    }

    this.stopRecord = async function stopRecord(arrayToSavePartsOfRecord) {
      this.isStream = record.state == 'inactive' ? false : true;
      if (record.state == 'inactive') { return false }
      record.stop();
      record.addEventListener("dataavailable", (e) => {
        if (arrayToSavePartsOfRecord) {
          arrayToSavePartsOfRecord.push(e.data);
          blob = new Blob(arrayToSavePartsOfRecord, { type: "audio/webm" });
        }
      });
      stopStream();
      this.getBlobURL(arrayToSavePartsOfRecord);
    }

    this.getBlobURL = async function getBlobURL(arrayOfpartsOfRecord) {
      if (record.state == "recording") {
        //recording
        record.stop();
        stopStream();
        this.isStream = record.state == 'inactive' ? false : true;
        record.addEventListener("dataavailable", (e) => {
          arrayOfpartsOfRecord.push(e.data);
          blob = new Blob(arrayOfpartsOfRecord, { type: "audio/webm" });
          url = URL.createObjectURL(blob);
        }); //dataavailable
        const prom = new Promise((res, rej) => {
          setTimeout(() => {
            if (url) {
              res(url);
            } else {
              rej("No Url");
            }
          }, 1);
        });
        return await prom;
      } else {
        blob = new Blob(arrayOfpartsOfRecord, { type: "audio/webm" });
        return URL.createObjectURL(blob);
      }
    }


  }
}

export class MakeLiveSoundWave {
  constructor({ canvas = document, waveColor = "String" }) {

    let audio, ctx, width, height, audCtx, analyser, srcG;

    this.loadAudio = function (src = "string", isStreamUrl = true) {
      audio = new Audio();
      audio.load();
      ctx = canvas.getContext("2d");
      ({ width, height } = canvas);
      audCtx = new AudioContext();
      analyser = audCtx.createAnalyser();

      if (isStreamUrl) {
        srcG = audCtx.createMediaStreamSource(src)
        audio.srcObject = src;
      } else {
        audio.src = src;
      }
      srcG.connect(analyser);
      // analyser.connect(audCtx.destination);
      console.log(srcG);
      return audio;
    }
    this.drawOnCanvas = function drawOnCanvas() {
      let unitArray = new Uint8Array(analyser.frequencyBinCount);
      analyser.getByteFrequencyData(unitArray);
      ctx.clearRect(0, 0, width, height);
      for (let i = 0; i < unitArray.length; i++) {
        ctx.fillStyle = waveColor;
        let unit = unitArray[i] <= 0 ? 2 : unitArray[i] - Math.trunc(unitArray[i] * 0.9);
        if (unitArray[i]) {
          ctx.fillRect(2.4 * i, height / 2, width / unitArray.length, unit);
          ctx.fillRect(2.4 * i, height / 2, width / unitArray.length, -unit);
        }
      }
      window.requestAnimationFrame(drawOnCanvas);
    }

    this.playAudio = function playAudio() {
      audio.play();
    }

    this.stopAudio = function stopAudio() {
      audio.pause();
    }
  }
}

class MakeAudioWaveOnLoad {
  constructor(loadSrc, drawCanvas) {
    this.laodSrc = loadSrc;
    this.drawCanvas = drawCanvas;

    async function loadSrc(src) {
      let buffer = (await fetch(src)).arrayBuffer(),
        audCtx = new AudioContext(),
        audioBuffer = await audCtx.decodeAudioData(await buffer),
        float32Array = audioBuffer.getChannelData(0);
      return float32Array
    }

    async function drawCanvas({ src, canvas, waveColor }) {
      let channelData = await loadSrc(src),
        ctx = canvas.getContext('2d');
      let { width, height } = canvas;
      let step = Math.ceil(channelData.length / width)
      ctx.fillStyle = waveColor;
      for (let i = 0; i < width; i++) {
        ctx.fillRect(2.4 * i, height / 2, 2, channelData[i]);
        ctx.fillRect(2.4 * i, height / 2, 2, -channelData[i]);
      }
    }
  }
}

export class MakeMinAndSecInterval {
  constructor({ minuts = document, seconds = document }) {
    let interval;
    this.startInterval = function () {
      clearInterval(interval);
      if (this.min || this.sec) { minuts.textContent = this.min; seconds.textContent = this.sec; } //becuse if user start interval while playing record
      interval = setInterval(() => {
        seconds.textContent++;
        if (seconds.textContent >= 60) {
          seconds.textContent = 0;
          minuts.textContent++;
        }
        this.min = minuts.textContent;
        this.sec = seconds.textContent;
      }, 1000);
    };

    this.stopInterval = function () {
      clearInterval(interval);
    };

    this.clearMin = function () {
      minuts.textContent = 0;
    };

    this.clearSec = function () {
      seconds.textContent = 0;
    };

    this.clearMinAndSec = function () {
      minuts.textContent = 0;
      seconds.textContent = 0;
    };

    this.makeIntervalWithAudioTime = function (audio) {
      clearInterval(interval)
      console.log(seconds.textContent);
      interval = setInterval(() => {
        let currentTime = Math.trunc(audio.getCurrentTime()) || audio.currentTime;
        if (Math.trunc(currentTime / 60) || Math.trunc(currentTime - +minuts.textContent * 60)) {
          minuts.textContent = Math.trunc(currentTime / 60);
          seconds.textContent = Math.trunc(currentTime - +minuts.textContent * 60);
        }
      }, 100)
    }
  }
}
//make component function
export function component({ type = "", attr = {}, content = "", children = {} }) {
  if(!type){throw new Error("type is undefined set type to clear error");} 
  let el = document.createElement(type);

  // set attributes for parent element
  if (attr) {
    for (const key of Object.keys(attr)) {
      if (attr.hasOwnProperty(key)) {
        el.setAttribute(key, attr[key]);
      }
    }
  }

  //set the content as textNode in parent
  if (content) {
    el.insertAdjacentHTML('beforeEnd',content);
  }
  //set childeren
  if (children) {
    for (const key of Object.keys(children)) {
      let childType = children[key].type, childAttr = children[key].attr,
        childContent = children[key].content, childrepeat = children[key].repeat, childFor = children[key].for;

      const childEl = document.createElement(childType);
      //set attributes of child
      if(childAttr){
        for (const key of Object.keys(childAttr)) {
          if (childAttr.hasOwnProperty(key)) {
            childEl.setAttribute(key, childAttr[key]);
          }
        }
      }

      if (childContent ) {
        if(Array.isArray(childContent)){
          for (let i = 0; i < childContent.length; i++) {
            childContent[i] instanceof Element? childEl.appendChild(childContent[i]): childEl.insertAdjacentHTML('beforeEnd',childContent[i]);
          }
        }else { childContent instanceof Element? childEl.appendChild(childContent): childEl.insertAdjacentHTML('beforeEnd',childContent)}
      } 

      //if some love to reapet same child
      for (let i = 0; i < childrepeat; i++) {
        if (childContent instanceof Element) {
          let cloneNode = childContent.cloneNode(true);
          childEl.appendChild(cloneNode)
        } else { childEl.innerHTML = childContent; }
      }
      el.appendChild(childEl);


      //to for on items
      if (childFor) {
        for (let i = 0; i < childFor.loop; i++) {
          let item = document.createElement(childFor.type);
          //start set attrtibutes
          if (childFor.attr) {
            for (const key of Object.keys(childFor.attr)) {
               if(!childFor.attr[key][i]){continue;}
              item.setAttribute(key, childFor.attr[key][i])
            }
          }
          //end set attrtibutes

          //start set contents
          if (childFor.content) {
            item.append(childFor.content[i])
          }
          //end set contents

          //now append the child
          childEl.appendChild(item)
        }
        //finally append child in the parent
        el.appendChild(childEl);
      }
    }
  }

  return el;
}

//set render function to render component
export class Render {
  constructor(element = document, component = "string", ...values) {
    element.appendChild(component)
  }
}

//set render dom
export function setRenderInElement() {
  Element.prototype.render = async function (component, ...values) {
    return new Render(this, component, ...values)
  }
}

//set css render dom
export function setCssInElement() {
  Element.prototype.css = function (cssStyle) {
    this.style.cssText = cssStyle.trim().slice(1, -1);
  }
}


export function transformTo(from, to = "string") {
  if (to == 'object' || to == 'Object' || to == 'obj' || to == 'Obj') {
    return { from }
  } else if (to == 'number' || to == 'Number') {
    let matching = /\d+/ig.test(from) ? from.match(/\d+/ig) : undefined;
    if (matching) { return +matching.join("") }

  } else if (to == 'boolean' || to == 'Boolean') {
    return Boolean(from)
  } else if (to == 'string' || to == 'String') {
    if (typeof from == 'object') {
      return JSON.stringify(from);
    } else {
      return String(from);
    }
  }
}

export function onMobile(func = function () { }) {
  if (navigator.userAgentData.platform == 'mobile' || navigator.userAgentData.platform == 'Mobile') {
    func()
  }
}

//send to server
export async function sendToServer(api = "string", data = {}, json = false) {
  let response = await fetch(api, { method: "POST", headers: { 'content-type': 'Application/json' }, body: JSON.stringify(data) });

  return json ? JSON.parse(await response.json()) : await response.text()
}

//Email validation
export function isValidEmail(email = "string") {
  let matching = email.trim().match(/\w+(\.\w+)?@\w+\.\w+$/ig);
  if (!matching) {
    return { valid: false, msg: "Email is not a valid" }
  } else if (matching.join("").match(/\.\w+/ig)[matching.join("").match(/\.\w+/ig).length - 1] != ".com") {
    return { valid: false, msg: "We just accept .com" }
  }
  else { return { valid: true, type: "email", data: email.trim(), msg: "Email is valid" } }
}

//Name validation
export function isValidName(name = "") {
  let specialCharMatch = name.trim().match(/[\s+|\W+]/g);
  if (specialCharMatch || name.trim() === "") {
    return { valid: false, msg: "Invalid name" };
  } else { return { valid: true, type: "name", data: name, msg: "Valid name" }; }
}

//Date validation
export function isValidDate(date = "", callback = () => { }) {
  let myDate = new Date(date), dateNow = new Date(),
    trulyDate = `${myDate.getFullYear()}/${myDate.getMonth() + 1}/${myDate.getDate()}`;
  callback(dateNow)
  if (myDate.getFullYear() <= dateNow.getFullYear() && myDate.getFullYear() > 1930 && date === trulyDate && myDate.getFullYear() > 1930) { return { valid: true, type: "date", data: date, msg: "Valid date" } } else { return { valid: false, msg: "Invalied date" } }
}

//Password validation
export function isValidPassword(password = "") {
  password = password.trim();
  let specialCharMatch = password.match(/[^a-z0-9\.\s+]/ig);
  let numsMatch = password.match(/[0-9]/ig);
  let upperCharMatch = password.match(/[A-Z]/g);
  let lowerrCharMatch = password.match(/[a-z]/g);
  let spaceMatch = password.match(/[\s+]/g);
  if (!password) { return { valid: false, msg: "Password must not be empty" }; }
  else if (!specialCharMatch) {
    return { valid: false, msg: "Password must have special characters" };
  } else if (!numsMatch || numsMatch.length < 4) {
    return { valid: false, msg: "Password must be at least 4 digits" };
  } else if (!upperCharMatch || upperCharMatch.length < 1) {
    return { valid: false, msg: "Password must be at least 1 capital letter" };
  } else if (!lowerrCharMatch || lowerrCharMatch.length < 1) {
    return { valid: false, msg: "Password must be at least 1 small letter" };
  } else if (spaceMatch) {
    return { valid: false, msg: "Password must not have spaces" };
  }
  else if (password.length < 8) { return { valid: false, msg: "Password must be at least 8 characters" }; }
  else { return { valid: true, type: "password", data: password, msg: "Password is valid" } }
}

//Re password validation
export function isValidRePassword(mainPassword, rePassword) {
  return rePassword.trim() == mainPassword.trim() ? { valid: true, data: rePassword.trim(), msg: "valid" } : { valid: false, msg: "Re password does not match" };
}

//Gender validation
export function isValidGender([...genders]) {
  for (let i = 0; i < genders.length; i++) {
    if (genders[i].checked) { return { valid: true, type: "gender", data: genders[i].id, msg: "Valid gender" }; };
  }
  return { valid: false, data: false, msg: "Please select a your gender" }
}

//transform text input value to number format
export function makeItNumsInput(input) {
  input.value = input.value.match(/\d+/ig);
  let dateNow = new Date();
  if (input.id == "year" && +input.value > dateNow.getFullYear() || input.id == "year" && +input.value < 1930) { return { valid: false, msg: "Invalid year", type: "year" } }
  if (input.id == "month" && +input.value > 12) { console.log(input);; return { valid: false, msg: "Maximum : 12", type: "month" } }
  if (input.id == "day" && +input.value > 31) { return { valid: false, msg: "Maximum : 31", type: "day" } }
  return { valid: true, msg: "All is valid", type: "All inputs" }
}


//submitting form
export function isValidForm({ fName = "", lName = "", date = [document], email, password, rePassword, genders = [document] }) {
  //check names
  let fNameValidation = isValidName(fName.value), lNameValidation = isValidName(lName.value);

  //check date
  let dateValidation = isValidDate(`${date[0].value}/${date[1].value}/${date[2].value}`);

  //check email 
  let emailValidation = isValidEmail(email);

  //check password
  let passwordValidation = isValidPassword(password);

  //check re password
  let rePasswordValidation = isValidRePassword(password, rePassword);

  //check gender
  let genderValidation = isValidGender(genders);

  //start checking
  let checker = [fNameValidation, lNameValidation, dateValidation, emailValidation, passwordValidation, rePasswordValidation, genderValidation];
  let result, ok;
  for (let i = 0; i < checker.length; i++) {
    if (!checker[i].valid) { result = checker[i].msg, ok = false; break; } else {
      result = {
        name: `${fName.value.trim()} ${lName.value.trim()}`,
        gender: genderValidation.data,
        age: dateValidation.data,
        email: email.trim(),
        password: password.trim()
      }
      ok = true;
    }
  }

  return { ok, result }
}

//encode & decode
export function encode(text = "string", password = "") {
  const complexChars = [
    "∆", "¬", "œ", "€", "®", "¨", "ø", "π", "å", "ß", "∂", "ƒ", "©",
    "˚", "¬", "µ", "+", "Ω", "œ", "®", "´", "´´", "≠", "–",
    "≤", "≥", "÷", "Ω", "µ", "∞", "¥", "§", "Π", "∫",
    "‰", "∏", "“", "”", "’", "‘", "≤", "≥", "⁄", "©",
    "~", "Π", "‹", "›", "fl", "·", "‚", "£", "„", "‰",
    "", "œ", "®", "†", "¨", "ø", "π", "å", "ß", "∂", "ƒ", "©", "∆", "˚",
    "¬", "µ", "Ω", "≠", "œ", "®", "∑", "´", "´´", "–", "≤", "≥",
    "÷", "Ω", "µ", "∞", "§", "Π", "∫", "∑", "∆", "ø", "ˆ", "¨", "‰",
    "∏", "“", "”", "’", "‘", "≤", "≥", "⁄", "∑", "ƒ", "©", "∆", "«",
    "𝕼", "𝕽", "𝕾", "𝕿", "𝖀", "𝖁", "𝖂", "𝖃", "𝖄", "𝖅", "𝖆", "𝖇", "𝖈", "𝖉", "𝖊", "𝖋",
    "𝖌", "𝖍", "𝖎", "𝖏", "𝖐", "𝖑", "𝖒", "𝖓", "𝖔", "𝖕", "𝖖", "𝖗", "𝖘", "𝖙", "𝖚", "𝖛",
    "𝖜", "𝖝", "𝖞", "𝖟", "𝛢", "𝛣", "𝛤", "𝛥", "𝛦", "𝛧", "𝛨", "𝛩", "𝛪", "𝛫", "𝛬", "𝛭",
    "𝛮", "𝛯", "𝛰", "𝛱", "𝛲", "𝛳", "𝛴", "𝛵", "𝛶", "𝛷", "𝛸", "𝛹", "𝛺", "𝛻", "𝛼", "𝛽",
    "𝛾", "𝛿", "𝜀", "𝜁", "𝜂", "𝜃", "𝜄", "𝜅", "𝜆", "𝜇", "𝜈", "𝜉", "𝜊", "𝜋", "𝜌", "𝜎",
    "𝜏", "𝜐", "𝜑", "𝜒", "𝜓", "𝜔", "ℂ", "ℍ", "𝕃", "ℕ", "ℙ", "𝕊", "𝕋", "𝕌", "𝕍", "𝕎",
    "𝕏", "𝕐", "𝕒", "𝕓", "𝕔", "𝕕", "𝕖", "𝕗", "𝕘", "𝕙", "𝕚", "𝕛", "𝕜", "𝕝", "𝕞", "𝕟",
    "𝕠", "𝕡", "𝕢", "𝕣", "𝕤", "𝕥", "𝕦", "𝕧", "𝕨", "𝕩", "𝕪", "𝕫", "𝟙", "𝟚", "𝟛", "𝟜",
    "𝟝", "𝟞", "𝟟", "𝟠", "𝟡", "𝟘", "𝟙", "𝟚", "𝟛", "𝟜", "𝟝", "𝟞", "𝟟", "𝟠", "𝟡", "ℑ",
    "ℜ", "𝒜", "ℬ", "𝒞"
  ];

  let encodedCode = [...encodeURIComponent(text) + encodeURIComponent("SSpassword:" + password)];
  for (let i = 0; i < encodedCode.length; i++) { encodedCode[i] = encodedCode[i] + complexChars[i + 3 + 4 + 1] + complexChars[i + 1 + 2] + complexChars[i + 1] + complexChars[i + 5] + complexChars[i] + complexChars[i + 3 + 1] + complexChars[i + 1 + 5]; };

  let reader = new FileReader(), textEncoder = new TextEncoder().encode(encodedCode.join("")), blob = new Blob(textEncoder);

  const myData = new Promise((res, rej) => {
    reader.readAsBinaryString(blob);
    reader.on('load', () => {
      if (reader.result) {
        let dataArray = [...reader.result.replace("data:application/octet-stream;base64,", "")]
        for (let i = 0; i < dataArray.length; i++) {
          dataArray[i] += complexChars[i + 1 + i] + complexChars[i + 2 + 3 + i] + complexChars[i + 2 + 3 + 1 + i]
          if (i >= 15) { dataArray[i] = " "; }
        }
        res(dataArray.join("").split(" ").join("") + btoa(`*^Password$#${password}`))
      } else {
        rej(new Error("Worng Data!"));
      }
    })
  })

  return myData;
};

export async function compare({ comparedText = "string", ComparedEncodedText = "string", password = "" }) {
  return await encode(comparedText, password) === ComparedEncodedText ? { ok: true, msg: "It is matched" } : { ok: false, msg: "It is not matched" }
}

//log asynchronous and synchronous
export async function log(data) {
  try {
    console.log(await data);
  } catch (error) {
    throw new Error(error.message)
  }
}
ready
t2

/*cocktail library created at 2/3/2023 - Devloped by yousef sayed*/
export function $(element = "string") {
  return document.querySelector(element);
}

export function $a(elements = "string") {
  return document.querySelectorAll(elements);
}

export function cre({ elementType, className, id, src, href, type = "", placeholder, where = document, prepend = false, replace = false }) {
  let el = document.createElement(elementType)
  console.log(el);
  if (className) { el.className = className };
  if (id) { el.id = id };
  if (src) { el.src = src };
  if (href) { el.href = href };
  if (placeholder) { el.placeholder = placeholder };
  if (where) { where.appendChild(el) };
  if (prepend) { where.prepend(el); }
  if (type) { el.type = type; }
  return el;
}

export function setOnInObjectProto() {
  Element.prototype.on = function (type = "string", callback = () => { }) {
    this.addEventListener(type, callback)
  }
}


export class MakeAudioRecorder {
  constructor() {

    const stream = navigator.mediaDevices.getUserMedia({ audio: true });
    let record, blob, url;

    this.getStream = async function getStream() {
      return await stream;
    }

    this.startRecord = async function startRecord() {
      record = new MediaRecorder(await stream);
      record.start();
      this.isStream = record.state == 'recording' ? true : false;
    }

    async function stopStream() {
      let stream2 = await stream;
      const tracks = stream2.getTracks();
      record.addEventListener("stop", () => {
        for (let i = 0; i < tracks.length; i++) {
          tracks[i].stop();
        }
      });
    }

    this.stopRecord = async function stopRecord(arrayToSavePartsOfRecord) {
      this.isStream = record.state == 'inactive' ? false : true;
      if (record.state == 'inactive') { return false }
      record.stop();
      record.addEventListener("dataavailable", (e) => {
        if (arrayToSavePartsOfRecord) {
          arrayToSavePartsOfRecord.push(e.data);
          blob = new Blob(arrayToSavePartsOfRecord, { type: "audio/webm" });
        }
      });
      stopStream();
      this.getBlobURL(arrayToSavePartsOfRecord);
    }

    this.getBlobURL = async function getBlobURL(arrayOfpartsOfRecord) {
      if (record.state == "recording") {
        //recording
        record.stop();
        stopStream();
        this.isStream = record.state == 'inactive' ? false : true;
        record.addEventListener("dataavailable", (e) => {
          arrayOfpartsOfRecord.push(e.data);
          blob = new Blob(arrayOfpartsOfRecord, { type: "audio/webm" });
          url = URL.createObjectURL(blob);
        }); //dataavailable
        const prom = new Promise((res, rej) => {
          setTimeout(() => {
            if (url) {
              res(url);
            } else {
              rej("No Url");
            }
          }, 1);
        });
        return await prom;
      } else {
        blob = new Blob(arrayOfpartsOfRecord, { type: "audio/webm" });
        return URL.createObjectURL(blob);
      }
    }


  }
}

export class MakeLiveSoundWave {
  constructor({ canvas = document, waveColor = "String" }) {

    let audio, ctx, width, height, audCtx, analyser, srcG;

    this.loadAudio = function (src = "string", isStreamUrl = true) {
      audio = new Audio();
      audio.load();
      ctx = canvas.getContext("2d");
      ({ width, height } = canvas);
      audCtx = new AudioContext();
      analyser = audCtx.createAnalyser();

      if (isStreamUrl) {
        srcG = audCtx.createMediaStreamSource(src)
        audio.srcObject = src;
      } else {
        audio.src = src;
      }
      srcG.connect(analyser);
      // analyser.connect(audCtx.destination);
      console.log(srcG);
      return audio;
    }
    this.drawOnCanvas = function drawOnCanvas() {
      let unitArray = new Uint8Array(analyser.frequencyBinCount);
      analyser.getByteFrequencyData(unitArray);
      ctx.clearRect(0, 0, width, height);
      for (let i = 0; i < unitArray.length; i++) {
        ctx.fillStyle = waveColor;
        let unit = unitArray[i] <= 0 ? 2 : unitArray[i] - Math.trunc(unitArray[i] * 0.9);
        if (unitArray[i]) {
          ctx.fillRect(2.4 * i, height / 2, width / unitArray.length, unit);
          ctx.fillRect(2.4 * i, height / 2, width / unitArray.length, -unit);
        }
      }
      window.requestAnimationFrame(drawOnCanvas);
    }

    this.playAudio = function playAudio() {
      audio.play();
    }

    this.stopAudio = function stopAudio() {
      audio.pause();
    }
  }
}

class MakeAudioWaveOnLoad {
  constructor(loadSrc, drawCanvas) {
    this.laodSrc = loadSrc;
    this.drawCanvas = drawCanvas;

    async function loadSrc(src) {
      let buffer = (await fetch(src)).arrayBuffer(),
        audCtx = new AudioContext(),
        audioBuffer = await audCtx.decodeAudioData(await buffer),
        float32Array = audioBuffer.getChannelData(0);
      return float32Array
    }

    async function drawCanvas({ src, canvas, waveColor }) {
      let channelData = await loadSrc(src),
        ctx = canvas.getContext('2d');
      let { width, height } = canvas;
      let step = Math.ceil(channelData.length / width)
      ctx.fillStyle = waveColor;
      for (let i = 0; i < width; i++) {
        ctx.fillRect(2.4 * i, height / 2, 2, channelData[i]);
        ctx.fillRect(2.4 * i, height / 2, 2, -channelData[i]);
      }
    }
  }
}

export class MakeMinAndSecInterval {
  constructor({ minuts = document, seconds = document }) {
    let interval;
    this.startInterval = function () {
      clearInterval(interval);
      if (this.min || this.sec) { minuts.textContent = this.min; seconds.textContent = this.sec; } //becuse if user start interval while playing record
      interval = setInterval(() => {
        seconds.textContent++;
        if (seconds.textContent >= 60) {
          seconds.textContent = 0;
          minuts.textContent++;
        }
        this.min = minuts.textContent;
        this.sec = seconds.textContent;
      }, 1000);
    };

    this.stopInterval = function () {
      clearInterval(interval);
    };

    this.clearMin = function () {
      minuts.textContent = 0;
    };

    this.clearSec = function () {
      seconds.textContent = 0;
    };

    this.clearMinAndSec = function () {
      minuts.textContent = 0;
      seconds.textContent = 0;
    };

    this.makeIntervalWithAudioTime = function (audio) {
      clearInterval(interval)
      console.log(seconds.textContent);
      interval = setInterval(() => {
        let currentTime = Math.trunc(audio.getCurrentTime()) || audio.currentTime;
        if (Math.trunc(currentTime / 60) || Math.trunc(currentTime - +minuts.textContent * 60)) {
          minuts.textContent = Math.trunc(currentTime / 60);
          seconds.textContent = Math.trunc(currentTime - +minuts.textContent * 60);
        }
      }, 100)
    }
  }
}
//make component function
export function component({ type = "", attr = {}, content = "", children = {} }) {
  if(!type){throw new Error("type is undefined set type to clear error");} 
  let el = document.createElement(type);

  // set attributes for parent element
  if (attr) {
    for (const key of Object.keys(attr)) {
      if (attr.hasOwnProperty(key)) {
        el.setAttribute(key, attr[key]);
      }
    }
  }

  //set the content as textNode in parent
  if (content) {
    el.insertAdjacentHTML('beforeEnd',content);
  }
  //set childeren
  if (children) {
    for (const key of Object.keys(children)) {
      let childType = children[key].type, childAttr = children[key].attr,
        childContent = children[key].content, childrepeat = children[key].repeat, childFor = children[key].for;

      const childEl = document.createElement(childType);
      //set attributes of child
      if(childAttr){
        for (const key of Object.keys(childAttr)) {
          if (childAttr.hasOwnProperty(key)) {
            childEl.setAttribute(key, childAttr[key]);
          }
        }
      }

      if (childContent ) {
        if(Array.isArray(childContent)){
          for (let i = 0; i < childContent.length; i++) {
            childContent[i] instanceof Element? childEl.appendChild(childContent[i]): childEl.insertAdjacentHTML('beforeEnd',childContent[i]);
          }
        }else { childContent instanceof Element? childEl.appendChild(childContent): childEl.insertAdjacentHTML('beforeEnd',childContent)}
      } 

      //if some love to reapet same child
      for (let i = 0; i < childrepeat; i++) {
        if (childContent instanceof Element) {
          let cloneNode = childContent.cloneNode(true);
          childEl.appendChild(cloneNode)
        } else { childEl.innerHTML = childContent; }
      }
      el.appendChild(childEl);


      //to for on items
      if (childFor) {
        for (let i = 0; i < childFor.loop; i++) {
          let item = document.createElement(childFor.type);
          //start set attrtibutes
          if (childFor.attr) {
            for (const key of Object.keys(childFor.attr)) {
               if(!childFor.attr[key][i]){continue;}
              item.setAttribute(key, childFor.attr[key][i])
            }
          }
          //end set attrtibutes

          //start set contents
          if (childFor.content) {
            item.append(childFor.content[i])
          }
          //end set contents

          //now append the child
          childEl.appendChild(item)
        }
        //finally append child in the parent
        el.appendChild(childEl);
      }
    }
  }

  return el;
}

//set render function to render component
export class Render {
  constructor(element = document, component = "string", ...values) {
    element.appendChild(component)
  }
}

//set render dom
export function setRenderInElement() {
  Element.prototype.render = async function (component, ...values) {
    return new Render(this, component, ...values)
  }
}

//set css render dom
export function setCssInElement() {
  Element.prototype.css = function (cssStyle) {
    this.style.cssText = cssStyle.trim().slice(1, -1);
  }
}


export function transformTo(from, to = "string") {
  if (to == 'object' || to == 'Object' || to == 'obj' || to == 'Obj') {
    return { from }
  } else if (to == 'number' || to == 'Number') {
    let matching = /\d+/ig.test(from) ? from.match(/\d+/ig) : undefined;
    if (matching) { return +matching.join("") }

  } else if (to == 'boolean' || to == 'Boolean') {
    return Boolean(from)
  } else if (to == 'string' || to == 'String') {
    if (typeof from == 'object') {
      return JSON.stringify(from);
    } else {
      return String(from);
    }
  }
}

export function onMobile(func = function () { }) {
  if (navigator.userAgentData.platform == 'mobile' || navigator.userAgentData.platform == 'Mobile') {
    func()
  }
}

//send to server
export async function sendToServer(api = "string", data = {}, json = false) {
  let response = await fetch(api, { method: "POST", headers: { 'content-type': 'Application/json' }, body: JSON.stringify(data) });

  return json ? JSON.parse(await response.json()) : await response.text()
}

//Email validation
export function isValidEmail(email = "string") {
  let matching = email.trim().match(/\w+(\.\w+)?@\w+\.\w+$/ig);
  if (!matching) {
    return { valid: false, msg: "Email is not a valid" }
  } else if (matching.join("").match(/\.\w+/ig)[matching.join("").match(/\.\w+/ig).length - 1] != ".com") {
    return { valid: false, msg: "We just accept .com" }
  }
  else { return { valid: true, type: "email", data: email.trim(), msg: "Email is valid" } }
}

//Name validation
export function isValidName(name = "") {
  let specialCharMatch = name.trim().match(/[\s+|\W+]/g);
  if (specialCharMatch || name.trim() === "") {
    return { valid: false, msg: "Invalid name" };
  } else { return { valid: true, type: "name", data: name, msg: "Valid name" }; }
}

//Date validation
export function isValidDate(date = "", callback = () => { }) {
  let myDate = new Date(date), dateNow = new Date(),
    trulyDate = `${myDate.getFullYear()}/${myDate.getMonth() + 1}/${myDate.getDate()}`;
  callback(dateNow)
  if (myDate.getFullYear() <= dateNow.getFullYear() && myDate.getFullYear() > 1930 && date === trulyDate && myDate.getFullYear() > 1930) { return { valid: true, type: "date", data: date, msg: "Valid date" } } else { return { valid: false, msg: "Invalied date" } }
}

//Password validation
export function isValidPassword(password = "") {
  password = password.trim();
  let specialCharMatch = password.match(/[^a-z0-9\.\s+]/ig);
  let numsMatch = password.match(/[0-9]/ig);
  let upperCharMatch = password.match(/[A-Z]/g);
  let lowerrCharMatch = password.match(/[a-z]/g);
  let spaceMatch = password.match(/[\s+]/g);
  if (!password) { return { valid: false, msg: "Password must not be empty" }; }
  else if (!specialCharMatch) {
    return { valid: false, msg: "Password must have special characters" };
  } else if (!numsMatch || numsMatch.length < 4) {
    return { valid: false, msg: "Password must be at least 4 digits" };
  } else if (!upperCharMatch || upperCharMatch.length < 1) {
    return { valid: false, msg: "Password must be at least 1 capital letter" };
  } else if (!lowerrCharMatch || lowerrCharMatch.length < 1) {
    return { valid: false, msg: "Password must be at least 1 small letter" };
  } else if (spaceMatch) {
    return { valid: false, msg: "Password must not have spaces" };
  }
  else if (password.length < 8) { return { valid: false, msg: "Password must be at least 8 characters" }; }
  else { return { valid: true, type: "password", data: password, msg: "Password is valid" } }
}

//Re password validation
export function isValidRePassword(mainPassword, rePassword) {
  return rePassword.trim() == mainPassword.trim() ? { valid: true, data: rePassword.trim(), msg: "valid" } : { valid: false, msg: "Re password does not match" };
}

//Gender validation
export function isValidGender([...genders]) {
  for (let i = 0; i < genders.length; i++) {
    if (genders[i].checked) { return { valid: true, type: "gender", data: genders[i].id, msg: "Valid gender" }; };
  }
  return { valid: false, data: false, msg: "Please select a your gender" }
}

//transform text input value to number format
export function makeItNumsInput(input) {
  input.value = input.value.match(/\d+/ig);
  let dateNow = new Date();
  if (input.id == "year" && +input.value > dateNow.getFullYear() || input.id == "year" && +input.value < 1930) { return { valid: false, msg: "Invalid year", type: "year" } }
  if (input.id == "month" && +input.value > 12) { console.log(input);; return { valid: false, msg: "Maximum : 12", type: "month" } }
  if (input.id == "day" && +input.value > 31) { return { valid: false, msg: "Maximum : 31", type: "day" } }
  return { valid: true, msg: "All is valid", type: "All inputs" }
}


//submitting form
export function isValidForm({ fName = "", lName = "", date = [document], email, password, rePassword, genders = [document] }) {
  //check names
  let fNameValidation = isValidName(fName.value), lNameValidation = isValidName(lName.value);

  //check date
  let dateValidation = isValidDate(`${date[0].value}/${date[1].value}/${date[2].value}`);

  //check email 
  let emailValidation = isValidEmail(email);

  //check password
  let passwordValidation = isValidPassword(password);

  //check re password
  let rePasswordValidation = isValidRePassword(password, rePassword);

  //check gender
  let genderValidation = isValidGender(genders);

  //start checking
  let checker = [fNameValidation, lNameValidation, dateValidation, emailValidation, passwordValidation, rePasswordValidation, genderValidation];
  let result, ok;
  for (let i = 0; i < checker.length; i++) {
    if (!checker[i].valid) { result = checker[i].msg, ok = false; break; } else {
      result = {
        name: `${fName.value.trim()} ${lName.value.trim()}`,
        gender: genderValidation.data,
        age: dateValidation.data,
        email: email.trim(),
        password: password.trim()
      }
      ok = true;
    }
  }

  return { ok, result }
}

//encode & decode
export function encode(text = "string", password = "") {
  const complexChars = [
    "∆", "¬", "œ", "€", "®", "¨", "ø", "π", "å", "ß", "∂", "ƒ", "©",
    "˚", "¬", "µ", "+", "Ω", "œ", "®", "´", "´´", "≠", "–",
    "≤", "≥", "÷", "Ω", "µ", "∞", "¥", "§", "Π", "∫",
    "‰", "∏", "“", "”", "’", "‘", "≤", "≥", "⁄", "©",
    "~", "Π", "‹", "›", "fl", "·", "‚", "£", "„", "‰",
    "", "œ", "®", "†", "¨", "ø", "π", "å", "ß", "∂", "ƒ", "©", "∆", "˚",
    "¬", "µ", "Ω", "≠", "œ", "®", "∑", "´", "´´", "–", "≤", "≥",
    "÷", "Ω", "µ", "∞", "§", "Π", "∫", "∑", "∆", "ø", "ˆ", "¨", "‰",
    "∏", "“", "”", "’", "‘", "≤", "≥", "⁄", "∑", "ƒ", "©", "∆", "«",
    "𝕼", "𝕽", "𝕾", "𝕿", "𝖀", "𝖁", "𝖂", "𝖃", "𝖄", "𝖅", "𝖆", "𝖇", "𝖈", "𝖉", "𝖊", "𝖋",
    "𝖌", "𝖍", "𝖎", "𝖏", "𝖐", "𝖑", "𝖒", "𝖓", "𝖔", "𝖕", "𝖖", "𝖗", "𝖘", "𝖙", "𝖚", "𝖛",
    "𝖜", "𝖝", "𝖞", "𝖟", "𝛢", "𝛣", "𝛤", "𝛥", "𝛦", "𝛧", "𝛨", "𝛩", "𝛪", "𝛫", "𝛬", "𝛭",
    "𝛮", "𝛯", "𝛰", "𝛱", "𝛲", "𝛳", "𝛴", "𝛵", "𝛶", "𝛷", "𝛸", "𝛹", "𝛺", "𝛻", "𝛼", "𝛽",
    "𝛾", "𝛿", "𝜀", "𝜁", "𝜂", "𝜃", "𝜄", "𝜅", "𝜆", "𝜇", "𝜈", "𝜉", "𝜊", "𝜋", "𝜌", "𝜎",
    "𝜏", "𝜐", "𝜑", "𝜒", "𝜓", "𝜔", "ℂ", "ℍ", "𝕃", "ℕ", "ℙ", "𝕊", "𝕋", "𝕌", "𝕍", "𝕎",
    "𝕏", "𝕐", "𝕒", "𝕓", "𝕔", "𝕕", "𝕖", "𝕗", "𝕘", "𝕙", "𝕚", "𝕛", "𝕜", "𝕝", "𝕞", "𝕟",
    "𝕠", "𝕡", "𝕢", "𝕣", "𝕤", "𝕥", "𝕦", "𝕧", "𝕨", "𝕩", "𝕪", "𝕫", "𝟙", "𝟚", "𝟛", "𝟜",
    "𝟝", "𝟞", "𝟟", "𝟠", "𝟡", "𝟘", "𝟙", "𝟚", "𝟛", "𝟜", "𝟝", "𝟞", "𝟟", "𝟠", "𝟡", "ℑ",
    "ℜ", "𝒜", "ℬ", "𝒞"
  ];

  let encodedCode = [...encodeURIComponent(text) + encodeURIComponent("SSpassword:" + password)];
  for (let i = 0; i < encodedCode.length; i++) { encodedCode[i] = encodedCode[i] + complexChars[i + 3 + 4 + 1] + complexChars[i + 1 + 2] + complexChars[i + 1] + complexChars[i + 5] + complexChars[i] + complexChars[i + 3 + 1] + complexChars[i + 1 + 5]; };

  let reader = new FileReader(), textEncoder = new TextEncoder().encode(encodedCode.join("")), blob = new Blob(textEncoder);

  const myData = new Promise((res, rej) => {
    reader.readAsBinaryString(blob);
    reader.on('load', () => {
      if (reader.result) {
        let dataArray = [...reader.result.replace("data:application/octet-stream;base64,", "")]
        for (let i = 0; i < dataArray.length; i++) {
          dataArray[i] += complexChars[i + 1 + i] + complexChars[i + 2 + 3 + i] + complexChars[i + 2 + 3 + 1 + i]
          if (i >= 15) { dataArray[i] = " "; }
        }
        res(dataArray.join("").split(" ").join("") + btoa(`*^Password$#${password}`))
      } else {
        rej(new Error("Worng Data!"));
      }
    })
  })

  return myData;
};

export async function compare({ comparedText = "string", ComparedEncodedText = "string", password = "" }) {
  return await encode(comparedText, password) === ComparedEncodedText ? { ok: true, msg: "It is matched" } : { ok: false, msg: "It is not matched" }
}

//log asynchronous and synchronous
export async function log(data) {
  try {
    console.log(await data);
  } catch (error) {
    throw new Error(error.message)
  }
}
ready

Revisions

You can edit these tests or add more tests to this page by appending /edit to the URL.