UNPKG

ziko

Version:

a versatile javaScript framework offering a rich set of UI components, advanced mathematical utilities, reactivity, animations, client side routing and graphics capabilities

8,600 lines 262 kB
/*
  Project: ziko.js
  Author: Zakaria Elalaoui
  Date : Tue Aug 12 2025 11:00:20 GMT+0100 (UTC+01:00)
  Git-Repo : https://github.com/zakarialaoui10/ziko.js
  Git-Wiki : https://github.com/zakarialaoui10/ziko.js/wiki
  Released under MIT License
*/

'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

function composeClass(Class, mixin) {
  const descriptors = Object.getOwnPropertyDescriptors(mixin);

  class Composed extends Class {
    constructor(...args) {
      super(...args);
      for (const key of Reflect.ownKeys(descriptors)) {
        const desc = descriptors[key];

        if (typeof desc.value === 'function') {
          this[key] = desc.value.bind(this);
        }
      }
    }
  }

  for (const key of Reflect.ownKeys(descriptors)) {
    const desc = descriptors[key];

    if ('get' in desc || 'set' in desc) {
      Object.defineProperty(Composed.prototype, key, desc);
    } else if (typeof desc.value !== 'function') {
      Object.defineProperty(Composed.prototype, key, desc);
    }
  }

  return Composed;
}

function composeInstance(instance, mixin) {
  const descriptors = Object.getOwnPropertyDescriptors(mixin);

  for (const key of Reflect.ownKeys(descriptors)) {
    const desc = descriptors[key];

    if ('get' in desc || 'set' in desc) {
      Object.defineProperty(instance, key, desc);
    } else if (typeof desc.value === 'function') {
      instance[key] = desc.value.bind(instance);
    } else {
      instance[key] = desc.value;
    }
  }
}

function compose(target, ...mixin) {
  if (typeof target === 'function') {
    return mixin.forEach(item =>composeClass(target, item));
  } else if (typeof target === 'object') {
    mixin.forEach(item =>composeInstance(target, item));
  } else {
    throw new TypeError("compose: target must be a class or instance");
  }
}

const __ExtractAll__ =(obj)=> {
    const keys = Object.keys(obj);
    for (let i = 0; i < keys.length; i++) {
        const key = keys[i];
        if (!["__ExtractAll__","__RemoveAll__","ExtractAll","RemoveAll"].includes(key)) {
            globalThis[key] = obj[key];
        }
    }
};
const __RemoveAll__ =(obj)=> {
    const keys = Object.keys(obj);
    for (let i = 0; i < keys.length; i++) {
        const key = keys[i];
        if (key !== '__RemoveAll__') {
            delete globalThis[key];
        }
    }
};

const { PI: PI$1, E } = Math;
const EPSILON=Number.EPSILON;

var __Const__ = /*#__PURE__*/Object.freeze({
  __proto__: null,
  E: E,
  EPSILON: EPSILON,
  PI: PI$1
});

const {PI, cos: cos$1, sin: sin$1, tan: tan$1, acos: acos$1, asin: asin$1, atan: atan$1, cosh: cosh$1, sinh: sinh$1, tanh: tanh$1, acosh: acosh$1, asinh: asinh$1, atanh: atanh$1, log} = Math;
let Fixed={
    cos: cos$1,
    sin: sin$1,
    tan: tan$1,
    sinc: x => sin$1(PI*x)/(PI*x),
    sec: x => 1/cos$1(x),
    csc: x => 1/sin$1(x),
    cot: x => 1/tan$1(x),
    acos: acos$1,
    asin: asin$1,
    atan: atan$1,
    acot: x => PI/2-atan$1(x),
    cosh: cosh$1,
    sinh: sinh$1,
    tanh: tanh$1,
    coth: n => (1/2*log((1+n)/(1-n))),
    acosh: acosh$1,
    asinh: asinh$1,
    atanh: atanh$1,
};

Fixed = new Proxy(Fixed, {
    get(target, prop) {
        if(prop in target){
            return x => + target[prop](x).toFixed(15);
        }
        return undefined;
    }
});

class ZikoMath {}

/** @module Math */
 /**
 * map a function to ...X
 * @param {function} fun
 * @param {...any} X
 * @returns {any|any[]}
 */
const mapfun$1=(fun,...X)=>{
    const Y=X.map(x=>{
        if(x===null)return fun(null);
        if(["number","string","boolean","bigint","undefined"].includes(typeof x))return fun(x);
        if(x instanceof Array)return x.map(n=>mapfun$1(fun,n));
        if(ArrayBuffer.isView(x))return x.map(n=>fun(n));
        if(x instanceof Set)return new Set(mapfun$1(fun,...[...x]));
        if(x instanceof Map)return new Map([...x].map(n=>[n[0],mapfun$1(fun,n[1])]));
        if(x instanceof Matrix){
            return new Matrix(x.rows,x.cols,mapfun$1(x.arr.flat(1)))
        }
        if(x instanceof Complex){
            const [a,b,z,phi]=[x.a,x.b,x.z,x.phi];
            switch(fun){
                case Math.log:return complex(ln(z),phi); // Done
                case Math.exp:return complex(e(a)*cos(b),e(a)*sin(b)); // Done
                case Math.abs:return z; // Done
                case Math.sqrt:return complex(sqrt(z)*cos(phi/2),sqrt(z)*sin(phi/2)); // Done
                case Fixed.cos:return complex(cos(a)*cosh(b),-(sin(a)*sinh(b)));
                case Fixed.sin:return complex(sin(a)*cosh(b),cos(a)*sinh(b));
                case Fixed.tan:{
                    const DEN=cos(2*a)+cosh(2*b);
                    return complex(sin(2*a)/DEN,sinh(2*b)/DEN);
                }
                case Fixed.cosh:return complex(cosh(a)*cos(b),sinh(a)*sin(b));
                case Fixed.sinh:return complex(sinh(a)*cos(b),cosh(a)*sin(b));
                case Fixed.tanh:{
                    const DEN=cosh(2*a)+cos(2*b);
                    return complex(sinh(2*a)/DEN,sin(2*b)/DEN)
                }
                default : return fun(x)
            }
        }
        else if(x instanceof Object){
            return fun(Object) || Object.fromEntries(Object.entries(x).map(n=>n=[n[0],mapfun$1(fun,n[1])]))
        }
    });
   return Y.length==1?Y[0]:Y; 
};

const _add=(a,b)=>{
    if(typeof(a)==="number"){
        if (typeof b == "number") return a + b;
        else if (b instanceof Complex)return complex(a + b.a, b.b);
        else if (b instanceof Matrix) return Matrix.nums(b.rows, b.cols, a).add(b);
        else if (b instanceof Array)return b.map(n=>add(n,a));                 
    }
    else if(a instanceof Complex||a instanceof Matrix){
        if(b instanceof Array)return b.map(n=>a.clone.add(n));
        return a.clone.add(b);
    }
    else if(a instanceof Array){
        if(b instanceof Array){
            if(a.length === b.length)return a.map((n,i)=>add(n,b[i]))
        }
        else {
            return a.map(n=>add(n,b));
        }
    }
};
const _sub=(a,b)=>{
    if(typeof(a)==="number"){
        if (typeof b == "number") return a - b;
        else if (b instanceof Complex)return complex(a - b.a, -b.b);
        else if (b instanceof Matrix) return Matrix.nums(b.rows, b.cols, a).sub(b);
        else if (b instanceof Array)return b.map(n=>sub(n,a));                 
    }
    else if(a instanceof Complex||a instanceof Matrix){
        if(b instanceof Array)return b.map(n=>a.clone.sub(n));
        return a.clone.sub(b);
    }
    else if(a instanceof Array){
        if(b instanceof Array){
            if(b instanceof Array){
                if(a.length === b.length)return a.map((n,i)=>sub(n,b[i]))
            }
        }
        else {
            return a.map(n=>sub(n,b));
        }
    }
};
const _mul=(a,b)=>{
    if(typeof(a)==="number"){
    if (typeof b == "number") return a * b;
        else if (b instanceof Complex)return complex(a * b.a,a * b.b);
        else if (b instanceof Matrix) return Matrix.nums(b.rows, b.cols, a).mul(b);
        else if (b instanceof Array)return b.map(n=>mul(a,n)); 
    }
    else if(a instanceof Complex||a instanceof Matrix){
        if(b instanceof Array)return b.map(n=>a.clone.mul(n));
        return a.clone.mul(b);
    }
    else if(a instanceof Array){
        if(b instanceof Array){
            if(b instanceof Array){
                if(a.length === b.length)return a.map((n,i)=>mul(n,b[i]))
            }
        }
        else {
            return a.map(n=>mul(n,b));
        }
    }
};
const _div=(a,b)=>{
    if(typeof(a)==="number"){
    if (typeof b == "number") return a / b;
        else if (b instanceof Complex)return complex(a / b.a,a / b.b);
        else if (b instanceof Matrix) return Matrix.nums(b.rows, b.cols, a).div(b);
        else if (b instanceof Array)return b.map(n=>div(a,n));
    }
    else if(a instanceof Complex||a instanceof Matrix){
        if(b instanceof Array)return b.map(n=>a.clone.div(n));
        return a.clone.div(b);
    }
    else if(a instanceof Array){
        if(b instanceof Array){
            if(b instanceof Array){
                if(a.length === b.length)return a.map((n,i)=>div(n,b[i]))
            }
        }
        else {
            return a.map(n=>div(n,b));
        }
    }
};
const _modulo=(a,b)=>{
    if(typeof(a)==="number"){
        if (typeof b == "number") return a % b;
            else if (b instanceof Complex)return complex(a % b.a,a % b.b);
            else if (b instanceof Matrix) return Matrix.nums(b.rows, b.cols, a).modulo(b);
            else if (b instanceof Array)return b.map(n=>div(a,n));
        }
        else if(a instanceof Complex||a instanceof Matrix){
            if(b instanceof Array)return b.map(n=>a.clone.div(n));
            return a.clone.div(b);
        }
        else if(a instanceof Array){
            if(b instanceof Array);
            else {
                return a.map(n=>add(n,b));
            }
        }
};
const add=(a,...b)=>{
    var res=a;
    for(let i=0;i<b.length;i++)res=_add(res,b[i]);
    return res;
};
const sub=(a,...b)=>{
    var res=a;
    for(let i=0;i<b.length;i++)res=_sub(res,b[i]);
    return res;
};
const mul=(a,...b)=>{
    var res=a;
    for(let i=0;i<b.length;i++)res=_mul(res,b[i]);
    return res;
};
const div=(a,...b)=>{
    var res=a;
    for(let i=0;i<b.length;i++)res=_div(res,b[i]);
    return res;
};
const modulo=(a,...b)=>{
    var res=a;
    for(let i=0;i<b.length;i++)res=_modulo(res,b[i]);
    return res;
};

const zeros=(n)=>new Array(n).fill(0);
const ones=(n)=>new Array(n).fill(1);
const nums=(num,n)=>new Array(n).fill(num);
const norm=(value, min, max)=>{
    if (typeof value === "number") return min !== max ? (value - min) / (max - min) : 0;
    else if (value instanceof Matrix) return new Matrix(value.rows, value.cols, norm(value.arr.flat(1), min, max));
    else if (value instanceof Complex) return new Complex(norm(value.a, min, max), norm(value.b, min, max));
    else if (value instanceof Array) {
        if (value.every((n) => typeof (n === "number"))) {
            return value.map((n) => norm(n, min, max));
        } else {
            let y = new Array(value.length);
            for (let i = 0; i < value.length; i++) {
                y[i] = norm(value[i]);
            }
        }
    }
};
const lerp=(value, min, max)=>{
    if (typeof value === "number") return (max - min) * value + min;
    else if (value instanceof Matrix) return new Matrix(value.rows, value.cols, lerp(value.arr.flat(1), min, max));
    else if (value instanceof Complex) return new Complex(lerp(value.a, min, max), lerp(value.b, min, max));
    else if (value instanceof Array) {
        if (value.every((n) => typeof (n === "number"))) {
            return value.map((n) => lerp(n, min, max));
        } else {
            let y = new Array(value.length);
            for (let i = 0; i < value.length; i++) {
                y[i] = lerp(value[i]);
            }
        }
    }
};
const map=(value, a, b, c, d)=>{
    if (typeof value === "number") return lerp(norm(value, a, b), c, d);
    else if (value instanceof Matrix) return new Matrix(value.rows, value.cols, map(value.arr.flat(1), a, b, c, d));
    else if (value instanceof Complex) return new Complex(map(value.a, b, c, d), map(value.b, a, b, c, d));
    else if (value instanceof Array) {
        if (value.every((n) => typeof (n === "number"))) {
            return value.map((n) => map(n, a, b, c, d));
        } else {
            let y = new Array(value.length);
            for (let i = 0; i < value.length; i++) {
                y[i] = map(value[i], a, b, c, d);
            }
        }
    }
};
const clamp=(x, a , b)=>{
    const [min_value,max_value]=[min(a,b),max(a,b)];
    if (typeof x === "number") return min(max(x, min_value), max_value);
    else if (x instanceof Matrix) return new Matrix(x.rows, x.cols, clamp(x.arr.flat(1), min_value, max_value));
    else if (x instanceof Complex) return new Complex(clamp(x.a, min_value, max_value), clamp(x.b, min_value, max_value));
    else if (x instanceof Array) {
        if (x.every((n) => typeof (n === "number"))) {
            return x.map((n) => clamp(n, min_value, max_value));
        } else {
            let y = new Array(x.length);
            for (let i = 0; i < x.length; i++) {
                y[i] = clamp(x[i], min_value, max_value);
            }
        }
    }
};
const arange=(a, b, step , include = false)=>{
    let tab = [];
    if(a<b){
        for (let i = a; include?i<=b:i<b; i += step) tab.push((i * 10) / 10);
    }
    else {
        for(let i = a; include?i>=b:i>b; i -= step) tab.push((i * 10) / 10);
    }
    return tab;
};
const linspace=(a,b,n=abs(b-a)+1,endpoint=true)=>{
    if(Math.floor(n)!==n)return;
    if([a,b].every(n=>typeof n==="number")){
        const [max,min]=[a,b].sort((a,b)=>b-a);
        var Y = [];
        let step ;
        endpoint ? step = (max - min) / (n - 1) : step = (max - min) / n;
        for (var i = 0; i < n; i++) {
            a<b?Y.push(min+step*i):Y.push(max-step*i);
        }
        return Y
    }

    if([a,b].some(n=>n instanceof Complex)){
        const z1=complex(a);
        const z2=complex(b);
        n=n||Math.abs(z1.a-z2.a)+1;
        const X=linspace(z1.a,z2.a,n,endpoint);
        const Y=linspace(z1.b,z2.b,n,endpoint);
        let Z=new Array(n).fill(null);
        Z=Z.map((n,i)=>complex(X[i],Y[i]));
        return Z;
    }
};
const logspace=(a,b,n=b-a+1,base=E,endpoint=true)=>{
    return linspace(a,b,n,endpoint).map(n=>pow(base,n))
};
const geomspace=(a,b,n=abs(b-a)+1,endpoint=true)=>{
    if(Math.floor(n)!==n)return;
    if([a,b].every(n=>typeof n==="number")){
        const [max,min]=[a,b].sort((a,b)=>b-a);
        let base;
        endpoint ? base = sqrtn(max/min,n-1) : base = sqrtn(max/min,n) ;
        const Y = [min];
        for (let i = 1; i < n; i++) {
            Y.push(Y[i-1]*base);
        }
        return a<b?Y:Y.reverse()
    }

    if([a,b].some(n=>n instanceof Complex)){
        const z1=complex(a);
        const z2=complex(b);
        n=n||Math.abs(z1.a-z2.a)+1;
        let base;
        endpoint ? base = sqrtn(z2.div(z1),n-1) : base = sqrtn(z2.div(z1),n) ;
        const Y = [z1];
        for (let i = 1; i < n; i++) {
            Y.push(mul(Y[i-1],base));
        } 
        return Y;
    }
};

/** @module Math */
/**
 * Converts degrees to radians.
 * @param {...number} deg - Degrees to convert.
 * @returns {number|number[]} Returns an array of radians corresponding to the input degrees.
 */
const deg2rad = (...deg) => mapfun(x => x * Math.PI / 180, ...deg);

/**
 * Converts radians to degrees.
 * @param {...number} rad - Radians to convert.
 * @returns {number|number[]} Returns an array of degrees corresponding to the input radians.
 */
const rad2deg = (...rad) => mapfun(x => x / Math.PI * 180, ...rad);

// Mixed calcul
const sum=(...x)=>{
    if(x.every(n=>typeof n==="number")){
        let s = x[0];
        for (let i = 1; i < x.length; i++) s += x[i];
        return s;
    }
    const Y=[];
    for(let i=0;i<x.length;i++){
        if(x[i] instanceof Array)Y.push(sum(...x[i]));
        else if(x[i] instanceof Object){
            Y.push(sum(...Object.values(x[i])));
        }
    }
    return Y.length===1?Y[0]:Y;
};
const prod=(...x)=>{
    if(x.every(n=>typeof n==="number")){
        let p = x[0];
        for (let i = 1; i < x.length; i++) p *= x[i];
        return p;
    }
    const Y=[];
    for(let i=0;i<x.length;i++){
        if(x[i] instanceof Array)Y.push(prod(...x[i]));
        else if(x[i] instanceof Object){
            Y.push(prod(...Object.values(x[i])));
        }
    }
    return Y.length===1?Y[0]:Y;
};
const min=(...num)=>{
    if(num.every(n=>typeof n==="number"))return Math.min(...num);
    const Y=[];
    for(let i=0;i<num.length;i++){
        if(num[i] instanceof Array)Y.push(min(...num[i]));
        else if(num[i] instanceof Object){
            Y.push(
                    Object.fromEntries(
                        [Object.entries(num[i]).sort((a,b)=>a[1]-b[1])[0]]
                    )
                );
        }
    }
    return Y.length===1?Y[0]:Y;
};
const max=(...num)=>{
    if(num.every(n=>typeof n==="number"))return Math.max(...num);
    const Y=[];
    for(let i=0;i<num.length;i++){
        if(num[i] instanceof Array)Y.push(min(...num[i]));
        else if(num[i] instanceof Object){
            Y.push(
                    Object.fromEntries(
                        [Object.entries(num[i]).sort((a,b)=>b[1]-a[1])[0]]
                    )
                );
        }
    }
    return Y.length===1?Y[0]:Y;
};
const accum=(...num)=>{
    if(num.every(n=>typeof n==="number")){
        let acc = num.reduce((x, y) => [...x, x[x.length - 1] + y], [0]);
        acc.shift();
        return acc;
    }
    const Y=[];
    for(let i=0;i<num.length;i++){
        if(num[i] instanceof Array)Y.push(accum(...num[i]));
        else if(num[i] instanceof Object){
            Y.push(null
                    // Object.fromEntries(
                    //     [Object.entries(num[i]).sort((a,b)=>b[1]-a[1])[0]]
                    // )
                );
        }
    }
    return Y.length===1?Y[0]:Y;
};

//moy
//med
//variance
//std
//mode
//acccum
//min2max
//max2min
//percentile

/** @module Math */
/**
 * Checks if a value is within the specified range.
 * @function
 * @param {number} x - The value to check.
 * @param {number} a - The start of the range.
 * @param {number} b - The end of the range.
 * @returns {boolean} Returns true if the value is within the range [a, b], otherwise false.
 */
const inRange = (x, a, b) => {
    const [min, max] = [Math.min(a, b), Math.max(a, b)];
    return x >= min && x <= max;
};

/**
 * Checks if two numbers are approximately equal within a given error margin.
 * @param {number} a - The first number.
 * @param {number} b - The second number.
 * @param {number} [Err=0.0001] - The maximum acceptable difference between the two numbers.
 * @returns {boolean} Returns true if the two numbers are approximately equal within the specified error margin, otherwise false.
 */
const isApproximatlyEqual = (a, b, Err = 0.0001) => {
    return Math.abs(a - b) <= Err;
};

/** @module Math */

/**
 * Computes the cartesian product of two arrays.
 * @param {Array} a - The first array.
 * @param {Array} b - The second array.
 * @returns {Array} Returns an array representing the cartesian product of the input arrays.
 */
const cartesianProduct = (a, b) => a.reduce((p, x) => [...p, ...b.map((y) => [x, y])], []);

/**
 * Computes the greatest common divisor (GCD) of two numbers.
 * @param {number} n1 - The first number.
 * @param {number} n2 - The second number.
 * @returns {number} Returns the greatest common divisor of the two input numbers.
 */
const pgcd = (n1, n2) => {
    let i,
        pgcd = 1;
    if (n1 == floor(n1) && n2 == floor(n2)) {
        for (i = 2; i <= n1 && i <= n2; ++i) {
            if (n1 % i == 0 && n2 % i == 0) pgcd = i;
        }
        return pgcd;
    } else console.log("error");
};

/**
 * Computes the least common multiple (LCM) of two numbers.
 * @param {number} n1 - The first number.
 * @param {number} n2 - The second number.
 * @returns {number} Returns the least common multiple of the two input numbers.
 */
const ppcm = (n1, n2) => {
    let ppcm;
    if (n1 == floor(n1) && n2 == floor(n2)) {
        ppcm = n1 > n2 ? n1 : n2;
        while (true) {
            if (ppcm % n1 == 0 && ppcm % n2 == 0) break;
            ++ppcm;
        }
        return ppcm;
    } else console.log("error");
};

const Utils$1={
    add,
    sub,
    mul,
    div,
    modulo,

    zeros,
    ones,
    nums,
    norm,
    lerp,
    map,
    clamp,
    arange,
    linspace,
    logspace,
    geomspace,

    sum,
    prod,
    accum,

    cartesianProduct,
    ppcm,
    pgcd,

    deg2rad,
    rad2deg,

    inRange,
    isApproximatlyEqual
};

var __Utils__ = /*#__PURE__*/Object.freeze({
  __proto__: null,
  Utils: Utils$1,
  add: add,
  arange: arange,
  cartesianProduct: cartesianProduct,
  clamp: clamp,
  deg2rad: deg2rad,
  div: div,
  geomspace: geomspace,
  inRange: inRange,
  isApproximatlyEqual: isApproximatlyEqual,
  lerp: lerp,
  linspace: linspace,
  logspace: logspace,
  map: map,
  mapfun: mapfun$1,
  modulo: modulo,
  mul: mul,
  norm: norm,
  nums: nums,
  ones: ones,
  pgcd: pgcd,
  ppcm: ppcm,
  prod: prod,
  rad2deg: rad2deg,
  sub: sub,
  sum: sum,
  zeros: zeros
});

const powerSet=originalSet=>{
    const subSets = [];
    const NUMBER_OF_COMBINATIONS = 2 ** originalSet.length;
    for (let i = 0; i < NUMBER_OF_COMBINATIONS; i += 1) {
        const subSet = [];
        for (let j = 0; j < originalSet.length; j += 1) {
            if (i & (1 << j)) {
                subSet.push(originalSet[j]);
            }
        }
        subSets.push(subSet);
    }
    return subSets;
};

// const subSet = (...arr) => {
//     let list = arange(0, 2 ** arr.length, 1);
//     let bin = list.map((n) => n.toString(2).padStart(arr.length, '0')).map((n) => n.split("").map((n) => +n));
//     let sub = bin.map((n) => n.map((m, i) => (m === 1 ? arr[i] : null))).map((n) => n.filter((x) => x !== null));
//     return sub;
// };
const subSet = null;

const Base={
    _mode:Number,
    _map:function(func,number,toBase){
        if (number instanceof Matrix)
            return new Matrix(
                number.rows,
                number.cols,
                number.arr.flat(1).map(n=>func(n,toBase))
            );
        else if (number instanceof Complex) return new Complex(func(number.a,toBase),func(number.b,toBase));
        else if (number instanceof Array) return number.map((n) =>func(n,toBase));
    },
    dec2base(dec,base){
        base<=10?this._mode=Number:this._mode=String;
        //this._mode=String
        if (typeof dec === "number") return this._mode((dec >>> 0).toString(base));
          return this._map(this.dec2base,dec,base)
    },
    dec2bin(dec){
        return this.dec2base(dec,2);
    },
    dec2oct(dec){
        return this.dec2base(dec,8);
    },
    dec2hex(dec){
        return this.dec2base(dec,16);
    },
    bin2base(bin, base) {
        return this.dec2base(this.bin2dec(bin),base)
    },
    bin2dec(bin){
        return this._mode("0b"+bin);
    },
    bin2oct(bin){
        return this.bin2base(bin,8);
    },
    bin2hex(bin){
        return this.bin2base(bin,16);
    },
    oct2dec(oct){
        return this._mode("0o"+oct);
    },
    oct2bin(oct){
        return this.dec2bin(this.oct2dec(oct))
    },
    oct2hex(oct){
        return this.dec2hex(this.oct2dec(oct))
    },
    oct2base(oct, base) {
        return this.dec2base(this.oct2dec(oct),base)
    },
    hex2dec(hex){
        return this._mode("0x"+hex);
    },
    hex2bin(hex){
        return this.dec2bin(this.hex2dec(hex))
    },
    hex2oct(hex){
        return this.dec2oct(this.hex2dec(hex))
    },
    hex2base(hex, base) {
        return this.dec2base(this.hex2dec(hex),base)
    },
    IEEE32toDec(Bin){
        let IEEE32=Bin.split(" ").join("").padEnd(32,"0");
        let s=IEEE32[0];
        let e=2**(+("0b"+IEEE32.slice(1,9))-127);
        let m=IEEE32.slice(9,32).split("").map(n=>+n);
        let M=m.map((n,i)=>n*(2**(-i-1))).reduce((a,b)=>a+b,0);
        let dec=(-1)**s*(1+M)*e;
        return dec
    },
    IEEE64toDec(Bin){
        let IEEE64=Bin.split(" ").join("").padEnd(64,"0");
        let s=IEEE64[0];
        let e=2**(+("0b"+IEEE64.slice(1,12))-1023);
        let m=IEEE64.slice(13,64).split("").map(n=>+n);
        let M=m.map((n,i)=>n*(2**(-i-1))).reduce((a,b)=>a+b,0);
        let dec=(-1)**s*(1+M)*e;
        return dec;
    }
};

const Logic$1={
    _mode:Number,
    _map:function(func,a,b){
        if (a instanceof Matrix)
            return new Matrix(
                a.rows,
                a.cols,
                a.arr.flat(1).map((n) => func(n, b))
            );
        else if (a instanceof Complex) return new Complex(func(a.a, b), func(a.b, b));
        else if (a instanceof Array) return a.map((n) => func(n, b));      
    },
    not:function(input){
        if(["number","boolean"].includes(typeof input)) return Logic$1._mode(!input);
        else return this._map(this.not,input)
    },
    and:function(a, ...b){
        if(["number","boolean"].includes(typeof a))return Logic$1._mode(b.reduce((n, m) => (n &= m), a));
        else return this._map(this.and,a,b)
    },
    or:function(a, ...b) {
        if(["number","boolean"].includes(typeof a)) return Logic$1._mode(b.reduce((n, m) => (n |= m), a));
        else return this._map(this.or,a,b);
    },
    nand:function(a, ...b) {
        return this.not(this.and(a, b));
    },
    nor:function(a, ...b) {
        return this.not(this.or(a, b));
    },
    xor:function(a,...b){
        let arr=[a,...b];
        if(["number","boolean"].includes(typeof a))return this._mode(arr.reduce((length,cur)=>{
            if(+cur===1)length+=1;
            return length;
        },0)===1);
        else return this._map(this.xor,a,b);
    },
    xnor:function(a,...b){
        return Logic$1.not(Logic$1.xor(a,b))
    }
    
};

class Permutation {
    static withDiscount(arr, l = arr.length) {
        if (l === 1) return arr.map((n) => [n]);
        const permutations = [];
        let smallerPermutations;
        smallerPermutations = this.withDiscount(arr, l - 1);
        arr.forEach((currentOption) => {
            smallerPermutations.forEach((smallerPermutation) => {
                permutations.push([currentOption].concat(smallerPermutation));
            });
        });
        return permutations;
    }
    static withoutDiscount(arr) {
        const l = arr.length;
        if (l === 1) return arr.map((n) => [n]);
        const permutations = [];
        const smallerPermutations = this.withoutDiscount(arr.slice(1));
        const firstOption = arr[0];
        for (let i = 0; i < smallerPermutations.length; i++) {
            const smallerPermutation = smallerPermutations[i];
            for (let j = 0; j <= smallerPermutation.length; j++) {
                const permutationPrefix = smallerPermutation.slice(0, j);
                const permutationSuffix = smallerPermutation.slice(j);
                permutations.push(permutationPrefix.concat([firstOption], permutationSuffix));
            }
        }
        return permutations;
    }
}

class Combinaison {
    static withDiscount(comboOptions, comboLength) {
        if (comboLength === 1) {
            return comboOptions.map((comboOption) => [comboOption]);
        }
        const combos = [];
        comboOptions.forEach((currentOption, optionIndex) => {
            const smallerCombos = this.withDiscount(comboOptions.slice(optionIndex), comboLength - 1);
            smallerCombos.forEach((smallerCombo) => {
                combos.push([currentOption].concat(smallerCombo));
            });
        });
        return combos;
    }
    static withoutDiscount(comboOptions, comboLength) {
        if (comboLength === 1) {
            return comboOptions.map((comboOption) => [comboOption]);
        }
        const combos = [];
        comboOptions.forEach((currentOption, optionIndex) => {
            const smallerCombos = this.withoutDiscount(comboOptions.slice(optionIndex + 1), comboLength - 1);
            smallerCombos.forEach((smallerCombo) => {
                combos.push([currentOption].concat(smallerCombo));
            });
        });

        return combos;
    }
}
const combinaison=(comboOptions, comboLength, discount=false)=>Combinaison[discount?"withDiscount":"withoutDiscount"](comboOptions, comboLength);

var __Discrect__ = /*#__PURE__*/Object.freeze({
  __proto__: null,
  Base: Base,
  Combinaison: Combinaison,
  Logic: Logic$1,
  Permutation: Permutation,
  combinaison: combinaison,
  powerSet: powerSet,
  subSet: subSet
});

class Random {
    static float(a = 1, b) {
        return b ? Math.random() * (b - a) + a : a * Math.random();
    }
    static int(a, b) {
        return Math.floor(this.float(a, b));
    }
    static char(upperCase){
        upperCase=upperCase??this.bool();
        const Char=String.fromCharCode(this.int(97,120));
        return upperCase?Char.toUpperCase():Char;
    }
    static bool(){
        return [false,true][Math.floor(Math.random()*2)];
    }
    static string(length,upperCase){
        return length instanceof Array?
            new Array(this.int(...length)).fill(0).map(() => this.char(upperCase)).join(""):
            new Array(length).fill(0).map(() => this.char(upperCase)).join("");
    }
    static bin() {
        return this.int(2);
    }
    static oct() {
        return this.int(8);
    }
    static dec() {
        return this.int(8);
    }
    static hex() {
        return this.int(16);
    }
    static choice(choices = [1, 2, 3], p = new Array(choices.length).fill(1 / choices.length)) {
        let newchoice = new Array(100);
        p=Utils$1.accum(...p).map(n=>n*100);
        newchoice.fill(choices[0], 0, p[0]);
        for (let i = 1; i < choices.length; i++) newchoice.fill(choices[i], p[i - 1], p[i]);
        return newchoice[this.int(newchoice.length - 1)];
    }
    static shuffleArr(arr){
        return arr.sort(()=>0.5-Math.random())    
    }
    static shuffleMatrix(M){
            const {rows,cols,arr}=M;
            return matrix(rows,cols,arr.flat().sort(()=>0.5-Math.random()))
    }
    static floats(n, a, b) {
        return new Array(n).fill(0).map(() => this.float(a, b));
    }
    static ints(n, a, b) {
        return new Array(n).fill(0).map(() => this.int(a, b));
    }
    static bools(n){
        return  new Array(n).fill(0).map(() => this.bool());
    }
    static bins(n) {
        return new Array(n).fill(0).map(() => this.int(2));
    }
    static octs(n) {
        return new Array(n).fill(0).map(() => this.int(8));
    }
    static decs(n) {
        return new Array(n).fill(0).map(() => this.int(10));
    }
    static hexs(n) {
        return new Array(n).fill(0).map(() => this.int(16));
    }
    static choices(n, choices, p) {
        return new Array(n).fill(0).map(() => this.choice(choices, p));
    }
    static perm(...arr) {
        // permutation
        return arr.permS[this.int(arr.length)];
    }
    static color() {
        return "#" + Base.dec2hex(this.float(16777216)).padStart(6,0);
    }
    static colors(n) {
        return new Array(n).fill(null).map(()=>this.color());
    }
    static complex(a = [0,1], b = [0,1]) {
        return a instanceof Array?
        new Complex(
            this.float(a[0], a[1]),
            this.float(b[0], b[1])
        ):
        new Complex(
            ...this.floats(2,a,b)
        )
        
    }
    static complexInt(a = [0,1], b = [0,1]) {
        return new Complex(
            this.int(a[0], a[1]),
            this.int(b[0], b[1])
            );
    }
    static complexBin() {
        return new Complex(...this.bins(2));
    }
    static complexOct() {
        return new Complex(...this.octs(2));
    }
    static complexDec() {
        return new Complex(...this.decs(10));
    }
    static complexHex() {
        return new Complex(...this.octs(2));
    }
    static complexes(n, a = 0, b = 1) {
        return new Array(n).fill(0).map(() => this.complex(a, b));
    }
    static complexesInt(n, a = 0, b = 1) {
        return new Array(n).fill(0).map(() => this.complexInt(a, b));
    }
    static complexesBin(n) {
        return new Array(n).fill(0).map(() => this.complexBin());
    }
    static complexesOct(n) {
        return new Array(n).fill(0).map(() => this.complexOct());
    }
    static complexesDec(n) {
        return new Array(n).fill(0).map(() => this.complexDec());
    }
    static complexesHex(n) {
        return new Array(n).fill(0).map(() => this.complexHex());
    }
    static matrix(r,c,min,max){
        return matrix(r,c,this.floats(r*c,min,max))
    }
    static matrixInt(r,c,min,max){
        return matrix(r,c,this.ints(r*c,min,max))
    }
    static matrixBin(r,c){
        return matrix(r,c,this.bins(r*c))
    }
    static matrixOct(r,c){
        return matrix(r,c,this.octs(r*c))
    }
    static matrixDec(r,c){
        return matrix(r,c,this.decs(r*c))
    }
    static matrixHex(r,c){
        return matrix(r,c,this.hex(r*c))
    }
    static matrixColor(r,c){
        return matrix(r,c,this.colors(r*c))
    }
    static matrixComplex(r,c,a,b){
        return matrix(r,c,this.complexes(r*c,a,b))
    }
    static matrixComplexInt(r,c,a,b){
        return matrix(r,c,this.complexesInt(r*c,a,b))
    }
    static matrixComplexBin(r,c){
        return matrix(r,c,this.complexesBin(r*c))
    }
    static matrixComplexOct(r,c){
        return matrix(r,c,this.complexesBin(r*c))
    }
    static matrixComplexDec(r,c){
        return matrix(r,c,this.complexesBin(r*c))
    }
    static matrixComplexHex(r,c){
        return matrix(r,c,this.complexesBin(r*c))
    }
}

var __Random__ = /*#__PURE__*/Object.freeze({
  __proto__: null,
  Random: Random
});

const preload=(url)=>{
    const xhr = new XMLHttpRequest();
    xhr.open("GET", url, false); 
    xhr.send();
    if (xhr.status === 200) {
      return xhr.responseText;
    } else {
      throw new Error(`Failed to fetch data from ${url}. Status: ${xhr.status}`);
    }
};

async function fetchdom(url='https://github.com/zakarialaoui10'){
  const data=await fetch(url);
  const html=await data.text();
  const dom= new DOMParser().parseFromString(html,'text/xml');
  return dom.documentElement
}
function fetchdomSync(url='https://github.com/zakarialaoui10'){
  const data=preload(url);
  const dom= new DOMParser().parseFromString(data,'text/xml');
  return dom.documentElement;
}

globalThis.fetchdom=fetchdom;
globalThis.fetchdomSync=fetchdomSync;

var Api = /*#__PURE__*/Object.freeze({
  __proto__: null,
  preload: preload
});

const csv2arr = (csv, delimiter = ",")=>csv.trim().trimEnd().split("\n").map(n=>n.split(delimiter));
const csv2matrix = (csv, delimiter = ",")=>new Matrix(csv2arr(csv,delimiter));
const csv2object = (csv, delimiter = ",") => {
    const [header, ...rows] = csv2arr(csv,delimiter);
    const result = rows.map(row => {
        const obj = {};
        header.forEach((key, index) => {
            obj[key] = row[index];
        });
        return obj;
    });
    return result;
};
const csv2json = (csv, delimiter = ",") => JSON.stringify(csv2object(csv,delimiter));
const csv2sql=(csv, Table)=>{
    const lines = csv.trim().trimEnd().split('\n').filter(n=>n);
    const columns = lines[0].split(',');
    let sqlQuery = `INSERT INTO ${Table} (${columns.join(', ')}) Values `;
    let sqlValues = [];
    for (let i = 1; i < lines.length; i++) {
      const values = lines[i].split(',');
      sqlValues.push(`(${values})`);
    }
    return sqlQuery+sqlValues.join(",\n");
  };

const _objects2arr=data=>data instanceof Array?[Object.keys(data[0]),...data.map(n=>Object.values(n))]:[Object.keys(data)];
const _objects2csv=(data,delimiter)=>_objects2arr(data).map(n=>n.join(delimiter)).join("\n");
const json2arr=json=>json instanceof Object?_objects2arr(json):_objects2arr(JSON.parse(json));
const json2csv=(json,delimiter=",")=>json instanceof Object?_objects2csv(json,delimiter):_objects2csv(JSON.parse(json),delimiter);
const json2csvFile=(json,delimiter)=>{
    const str=json2csv(json,delimiter);
    const blob=new Blob([str], { type: 'text/csv;charset=utf-8;' });
    return {
       str,
       blob,
       url:URL.createObjectURL(blob)
    }
};
const _processObject=(obj, indent)=>{
    const yml = [];
    if (Array.isArray(obj)) {
        obj.forEach(item => {
            if (typeof item === 'object' && item !== null) {
                yml.push(`${indent}-`);
                const nestedLines = _processObject(item, `${indent}  `);
                yml.push(...nestedLines);
            } else yml.push(`${indent}- ${item}`);
        });
    } else {
        for (const key in obj) {
            if (obj.hasOwnProperty(key)) {
                const value = obj[key];
                if (typeof value === 'object' && value !== null) {
                    yml.push(`${indent}${key}:`);
                    const nestedLines = _processObject(value, `${indent}  `);
                    yml.push(...nestedLines);
                } else {
                    yml.push(`${indent}${key}: ${value}`);
                }
            }
        }
    }
    return yml;
};
const _object2yml=(object,indent="")=>_processObject(object,indent).join('\n');
const json2yml=(json,indent)=>json instanceof Object?_object2yml(json,indent):_object2yml(JSON.parse(json),indent);
const json2ymlFile=(json,indent)=>{
    const str=json2yml(json,indent);
    const blob=new Blob([str], { type: 'text/yml;charset=utf-8;' });
    return {
       str,
       blob,
       url:URL.createObjectURL(blob)
    }
};
const json2xml=(json, indent = 1)=>{
    let xml = '';
    for (const key in json) {
      if (json.hasOwnProperty(key)) {
        const value = json[key];
        xml += '\n' + ' '.repeat(indent) + `<${key}>`;
        (typeof value === 'object') ? xml += json2xml(value, indent + 2) : xml += `${value}`;
        xml += `</${key}>`;
      }
    }
    return xml.trim();
  };
const json2xmlFile=(json,indent)=>{
    const str=json2xml(json,indent);
    const blob=new Blob([str], { type: 'text/xml;charset=utf-8;' });
    return {
       str,
       blob,
       url:URL.createObjectURL(blob)
    }
};

class ZikoUINode {
    constructor(node){
        this.cache = {
            node
        };
    }
    isZikoUINode(){
        return true
    }
    get node(){
        return this.cache.node;
    } 
}

globalThis.node = (node) => new ZikoUINode(node);

const DomMethods = {
  append(...ele) {
    __addItem__.call(this, "append", "push", ...ele);
    return this;
  },
  prepend(...ele) {
    this.__addItem__.call(this, "prepend", "unshift", ...ele);
    return this;
  },
  insertAt(index, ...ele) {
    if (index >= this.element.children.length) this.append(...ele);
    else
      for (let i = 0; i < ele.length; i++) {
        if (["number", "string"].includes(typeof ele[i])) ele[i] = text(ele[i]);
        this.element?.insertBefore(ele[i].element, this.items[index].element);
        this.items.splice(index, 0, ele[i]);
      }
    return this;
  },
  remove(...ele) {
    const remove = (ele) => {
      if (typeof ele === "number") ele = this.items[ele];
      if (ele?.isZikoUIElement) this.element?.removeChild(ele.element);
      this.items = this.items.filter((n) => n !== ele);
    };
    for (let i = 0; i < ele.length; i++) remove(ele[i]);
    for (let i = 0; i < this.items.length; i++)
      Object.assign(this, { [[i]]: this.items[i] });
    // Remove from item
    return this;
  },
  clear(){
    this?.items?.forEach(n=>n.unrender());
    this.element.innerHTML = "";
    return this;
  },
  render(target = this.target) {
    if(this.isBody)return ;
    if(target?.isZikoUIElement)target=target.element;
    this.target=target;
    this.target?.appendChild(this.element);
    return this;
  },
  unrender(){
    if(this.cache.parent)this.cache.parent.remove(this);
    else if(this.target?.children?.length && [...this.target?.children].includes(this.element)) this.target.removeChild(this.element);
    return this;
  },
  renderAfter(t = 1) {
    setTimeout(() => this.render(), t);
    return this;
  },
  unrenderAfter(t = 1) {
    setTimeout(() => this.unrender(), t);
    return this;
  },
  after(ui){
    if(ui?.isZikoUIElement) ui=ui.element;
    this.element?.after(ui);
    return this;
  },
  before(ui){
    if(ui?.isZikoUIElement) ui=ui.element;
    this.element?.before(ui);
    return this;
  }

};

function __addItem__(adder, pusher, ...ele) {
  if (this.cache.isFrozzen) {
    console.warn("You can't append new item to frozzen element");
    return this;
  }
  for (let i = 0; i < ele.length; i++) {
    if (["number", "string"].includes(typeof ele[i])) ele[i] = text(ele[i]);
    if (
      typeof globalThis?.Node === "function" &&
      ele[i] instanceof globalThis?.Node
    )
      ele[i] = new this.constructor(ele[i]);
    if (ele[i]?.isZikoUIElement) {
      ele[i].cache.parent = this;
      this.element[adder](ele[i].element);
      ele[i].target = this.element;
      this.items[pusher](ele[i]);
    } else if (ele[i] instanceof Object) {
      if (ele[i]?.style) this.style(ele[i]?.style);
      if (ele[i]?.attr) {
        Object.entries(ele[i].attr).forEach((n) =>
          this.setAttr("" + n[0], n[1]),
        );
      }
    }
  }
  this.maintain();
  return this;
}

const IndexingMethods = {
  at(index) {
    return this.items.at(index);
  },
  forEach(callback) {
    this.items.forEach(callback);
    return this;
  },
  map(callback) {
    return this.items.map(callback);
  },
  find(condition) {
    return this.items.filter(condition);
  },
};

const Events$1 = {
    'Click' : [
        'Click',
        'DblClick'
    ],
    'Ptr' : [
        'PtrMove',
        'PtrDown',
        'PtrUp',
        'PtrLeave',
        'PtrEnter',
        'PtrOut',
        'PtrCancel'
    ],
    'Mouse' : [
        'MouseMove',
        'MouseDown',
        'MouseUp',
        'MouseEnter',
        'MouseLeave',
        'MouseOut'
    ],
    // 'Touch' : [],
    'Key' : [
        'KeyDown',
        'KeyPress',
        'KeyUp'
    ],
    'Clipboard':[
        'Copy',
        'Cut',
        'Paste'
    ],
    'Focus':[
        'focus',
        'blur'
    ],
    'Drag':[
        "Drag",
        "DragStart",
        "DragEnd",
        "Drop"
    ],
    'Wheel': [
        'Wheel'
    ]
    // 'Media':[

    // ],
    // 'Hash':[
    //     "HashChange"
    // ]
};

const getEvent=(event = "")=>{
    if(event.startsWith("Ptr"))return `pointer${event.split("Ptr")[1].toLowerCase()}`;
    return event.toLowerCase()
};

function event_controller(e, event_name, details_setter, customizer, push_object){
    this.cache.currentEvent = event_name;
    this.cache.event = e;
    details_setter?.call(this);
    customizer?.hasOwnProperty("prototype") ? customizer?.call(this) : customizer?.call(null, this);
    // if(customizer?.hasOwnProperty("prototype")) customizer?.call(this)
    // else customizer?.call(null, this)
    if(this.cache.preventDefault[event_name]) e.preventDefault();
    if(this.cache.stopPropagation[event_name]) e.stopPropagation();
    if(this.cache.stopImmediatePropagation[event_name]) e.stopImmediatePropagation();
    
    if(this.cache.stream.enabled[event_name]&&push_object)this.cache.stream.history[event_name].push(push_object);
    this.cache.callbacks[event_name]?.map(n=>n(this));
}
class __ZikoEvent__ {
    constructor(target = null, Events = [], details_setter, customizer){
        this.target = target;
        this.cache = {
            currentEvent : null,
            event: null,
            options : {},
            preventDefault : {},
            stopPropagation : {},
            stopImmediatePropagation : {},
            event_flow : {},
            paused : {},
            stream : {
                enabled : {},
                clear : {},
                history : {}
            },
            callbacks : {},
            __controllers__:{}
        };
        if(Events)this._register_events(Events, details_setter, customizer);
    }
    _register_events(Events, details_setter, customizer, REGISTER_METHODES = true){
        const events = Events?.map(n=>getEvent(n));
        events?.forEach((event,i)=>{
            Object.assign(this.cache.preventDefault, {[event] : false});
            Object.assign(this.cache.options, {[event] : {}});
            Object.assign(this.cache.paused, {[event] : false});
            Object.assign(this.cache.stream.enabled, {[event] : false});
            Object.assign(this.cache.stream.clear, {[event] : false});
            Object.assign(this.cache.stream.history, {[event] : []});
            Object.assign(this.cache.__controllers__, {[event] : e=>event_controller.call(this, e, event, details_setter, customizer)});
            if(REGISTER_METHODES)Object.assign(this, { [`on${Events[i]}`] : (...callbacks)=> this.__onEvent(event, this.cache.options[event], {}, ...callbacks)});
        });
        return this;
    }
    get targetElement(){
        return this.target?.element;
    }
    get isParent(){
        return this.target?.element === this.event.srcElement;
    }
    get item(){
        return this.target.find(n=>n.element == this.event?.srcElement)?.[0];
    }
    get currentEvent(){
        return this.cache.currentEvent;
    }
    get event(){
        return this.cache.event;
    }
    setTarget(UI){
        this.target=UI;
        return this;
    }
    __handle(event, handler, options, dispose){
        this.targetElement?.addEventListener(event, handler, options);
        return this;
    }
    __onEvent(event, options, dispose, ...callbacks){
        if(callbacks.length===0){
            console.log("00");
            if(this.cache.callbacks[event]){
                console.log("Call");
                // this.cache.callbacks.map(n=>e=>n.call(this,e));
                this.cache.callbacks[event].map(n=>e=>n.call(this,e));
            }   
            else {
                return this;
            }
        }
        else this.cache.callbacks[event] = callbacks.map(n=>e=>n.call(this,e));
        this.__handle(event, this.cache.__controllers__[event],options, dispose);
        return this;  
    }
    #override(methode, overrides, defaultValue){
        if(defaultValue === "default") Object.assign(this.cache[methode], {...this.cache[methode], ...overrides});
        const all = defaultValue === "default" 
        ? this.cache[methode]
        : Object.fromEntries(Object.keys(this.cache.preventDefault).map(n=>[n,defaultValue]));
        Object.assign(this.cache[methode], {...all,...overrides});
        return this       
    }
    preventDefault(overrides = {}, defaultValue = "default"){
        this.#override("preventDefault", overrides, defaultValue);
        // const all=Object.fromEntries(Object.keys(this.cache.preventDefault).map(n=>[n,defaultValue]))
        // Object.assign(this.cache.preventDefault, {...all,...overrides});
        return this;
    }
    stopPropagation(overrides = {}, defaultValue = "default"){
        this.#override("stopPropagation", overrides, defaultValue);
        return this;
    }
    stopImmediatePropagation(overrides = {}, defaultValue = "default"){
        this.#override("stopImmediatePropagation", overrides, defaultValue);
        return this;
    }
    setEventOptions(event, options){
        this.pause({[event] : true, }, "default");
        Object.assign(this.cache.options[getEvent(event)], options);
        this.resume({[event] : true, }, "default");
        return this;
    }
    pause(overrides = {}, defaultValue = "default"){
        const all = defaultValue === "default" 
          ? this.cache.stream.enabled
          : Object.entries(Object.keys(this.cache.stream.enabled).map(n=>[n,defaultValue]));
        overrides={...all,...overrides};
        for(let key in overrides){
            if(overrides[key]){
                this.targetElement?.removeEventListener(key, this.cache.__controllers__[key], this.cache.options[key]);
                this.cache.paused[key]=true;
            }
        }
        return this;
    }
    resume(overrides = {}, defaultValue = "default"){
        const all = defaultValue === "default" 
          ? this.cache.stream.enabled
          : Object.entries(Object.keys(this.cache.stream.enabled).map(n=>[n,defaultValue]));
        overrides={...all,...overrides};
        for(let key in overrides){
            if(overrides[key]){
                this.targetElement?.addEventListener(key,this.cache.__controllers__[key], this.cache.options[key]);
                this.cache.paused[key]=false;
            }
        }
        return this;
     }
    stream(overrides = {}, defaultValue = "default"){
        this.cache.stream.t0=Date.now();
        const all=Object.fromEntries(Object.keys(this.cache.stream.enabled).map(n=>[n,defaultValue]));
        overrides={...all,...overrides};
        Object.assign(this.cache.stream.enabled,overrides);
        return this;
     }
    clear(){
        return this;
    }
    dispose(overrides = {}, defaultValue = "default"){
        this.pause(overrides, defaultValue);

        return this;
    }
}

class ZikoEventClick extends __ZikoEvent__{
    constructor(target, customizer){
        super(target, Events$1.Click, details_setter$a, customizer);
    }
}
function details_setter$a(){
    if(this.currentEvent==="click") this.dx = 0;
    else this.dx = 1;
    // console.log(this.currentEvent)
}
const bindClickEvent = (target, customizer) => new ZikoEventClick(target, customizer);

class ZikoEventClipboard extends __ZikoEvent__{
    constructor(target, customizer){
        super(target, Events$1.Clipboard, details_setter$9, customizer);
    }
}
function details_setter$9(){

}
const bindClipboardEvent = (target, customizer) => new ZikoEventClipboard(target, customizer);

class ZikoEventCustom extends __ZikoEvent__{
    constructor(target, events, customizer){
        super(target, events, details_setter$8, customizer);
    }
    _register_events(events){
        super._register_events(events, null, null, false);
        return this;
    }
    emit(event_name, details = {}){
        const event=new Event(event_name);
        this.targetElement.dispatchEvent(event);
        return this;
    }
    on(event_name, ...callbacks){
        if(!this.cache.options.hasOwnProperty(event_name)) this._register_events([event_name]);
        this.__onEvent(event_name, this.cache.options[event_name], {}, ...callbacks);
        return this;
    }
}
function details_setter$8(){

}
const bindCustomEvent = (target, events, customizer) => new ZikoEventCustom(target, events, customizer);

class ZikoEventDrag extends __ZikoEvent__{
    constructor(target, customizer){
        super(target, Events$1.Drag, details_setter$7, customizer);
    }
}
function details_setter$7(){

}
const bindDragEvent = (target, customizer) => new ZikoEventDrag(target, customizer);

class ZikoEventFocus extends __ZikoEvent__{
    constructor(target, customizer){
        super(target, Events$1.Focus, details_setter$6, customizer);
    }
}
function details_setter$6(){

}
const bindFocusEvent = (target, customizer) => new ZikoEventFocus(target, customizer);

let ZikoEventHash$1 = class ZikoEventHash extends __ZikoEvent__{
    constructor(target, customizer){
        super(target, Events$1.Hash, details_setter$5, customizer);
    }
};
function details_setter$5(){

}
const bindHashEvent = (target, customizer) => new ZikoEventHash$1(target, customizer);

class ZikoEventKey extends __ZikoEvent__{
    constructor(target, customizer){
        super(target, Events$1.Key, details_setter$4, customizer);
    }
}
function details_setter$4(){
    switch(this.currentEvent){
        case "keydown" : {
            this.kd = this.event.key;
        } break;
        case "keypress" : {
            this.kp = this.event.key;
        } break;
        case "keyup" : {
            this.ku = this.event.key;
        } break;

    }
}
const bindKeyEvent = (target, customizer) => new ZikoEventKey(target, customizer);

class ZikoEventMouse extends __ZikoEvent__{
    constructor(target, customizer){
        super(target, Events$1.Mouse, details_setter$3, customizer);
    }
}
function details_setter$3(){

}
const bindMouseEvent = (target, customizer) => new ZikoEventMouse(target, customizer);

class ZikoEventPointer extends __ZikoEvent__{
    constructor(target, customizer){
        super(target, Events$1.Ptr, details_setter$2, customizer);
        this.isDown = false;
    }
}
function details_setter$2(){
    switch(this.currentEvent){
        case "pointerdown" : {
            this.dx = parseInt(this.event.offsetX);
            this.dy = parseInt(this.event.offsetY);
            this.isDown = true;
        } break;
        case "pointermove" : {
            this.mx = parseInt(this.event.offsetX);
            this.my = parseInt(this.event.offsetY);
            this.isMoving = true;
        } break;
        case "pointerup" : {
            this.ux = parseInt(this.event.offsetX);
            this.uy = parseInt(this.event.offsetY);
            this.isDown = false;
            console.log(this.target.width);
            const delta_x=(this.ux-this.dx)/this.target.width;
            const delta_y=(this.dy-this.uy)/this.target.height;
            const HORIZONTAL_SWIPPE=(delta_x<0)?"left":(delta_x>0)?"right":"none";
            const VERTICAL_SWIPPE=(delta_y<0)?"bottom":(delta_y>0)?"top":"none";
            this.swippe={
                h:HORIZONTAL_SWIPPE,
                v:VERTICAL_SWIPPE,
                delta_x,
                delta_y
            };
        } break;
    }
    // if(this.currentEvent==="click") this.dx = 0
    // else this.dx = 1
    // console.log(this.currentEvent)
}
const bindPointerEvent = (target, customizer) => new ZikoEventPointer(target, customizer);

class ZikoEventTouch extends __ZikoEvent__{
    constructor(target, customizer){
        super(target, Events$1.Touch, details_setter$1, customizer);
    }
}
function details_setter$1(){

}
const bindTouchEvent = (target, customizer) => new ZikoEventTouch(target, customizer);

class ZikoEventWheel extends __ZikoEvent__{
    constructor(target, customizer){
        super(target, Events$1.Wheel, details_setter, customizer);
    }
}
function details_setter(){

}
const bindWheelEvent = (target, customizer) => new ZikoEventWheel(target, customizer);

const binderMap = {
  ptr: bindPointerEvent,
  mouse : bindMouseEvent,
  key: bindKeyEvent,
  click : bindClickEvent,
  drag : bindDragEvent,
  clipboard : bindClipboardEvent,
  focus : bindFocusEvent,
  wheel : bindWheelEvent
};

const EventsMethodes = {};

Object.entries(Events$1).forEach(([name, eventList]) => {
  eventList.forEach(event => {
    const methodName = `on${event}`;
    EventsMethodes[methodName] = function (...callbacks) {
      if (!this.events[name]) this.events[name] = binderMap[name.toLowerCase()](this);
      this.events[name][methodName](...callbacks);
      return this;
    };
  });
});

class ZikoUseStyle {
  constructor(style = {}, use = style.hasOwnProperty("default")? "default" : Object.keys(style)[0], id = 0) {
    this.id = "Ziko-Style-" + id;
    this.keys = new Set();
    this.styles = {
      default: {
        fontSize: "1em",
        color : "green"
      },
      other: {
        fontSize : "2em",
        color : "cyan" 
      }
    };
    style && this.add(style);
    use && this.use(use);
  }

  get current() {
    return [...this.keys].reduce((key, value) => {
      key[value] = `var(--${value}-${this.id})`;
      return key;
    }, {});
  }

  add(name, style = {}) {
    if (name && typeof name === 'object' && !Array.isArray(name)) {
      Object.assign(this.styles, name);
    } else if (typeof name === 'string') {
      Object.assign(this.styles, { [name]: style });
    }
    return this;
  }

  #useStyleIndex(index) {
    const keys = Object.keys(this.styles);
    for (let a in this.styles[keys[index]]) {
      if (Object.prototype.hasOwnProperty.call(this.styles[keys[index]], a)) {
        document.documentElement.style.setProperty(`--${a}-${this.id}`, this.styles[keys[index]][a]);
        this.keys.add(a);
      }
    }
    return this;
  }

  #useStyleName(name) {
    if (!this.styles[name]) return this;
    for (let a in this.styles[name]) {
      if (Object.prototype.hasOwnProperty.call(this.styles[name], a)) {
        document.documentElement.style.setProperty(`--${a}-${this.id}`, this.styles[name][a]);
        this.keys.add(a);
      }
    }
    return this;
  }

  #useStyleObject(style) {
    for (let a in style) {
      if (Object.prototype.hasOwnProperty.call(style, a)) {
        document.documentElement.style.setProperty(`--${a}-${this.id}`, style[a]);
        this.keys.add(a);
      }
    }
    return this;
  }

  use(style) {
    if (typeof style === "number") return this.#useStyleIndex(style);
    if (typeof style === "string") return this.#useStyleName(style);
    if (style && typeof style === "object") return this.#useStyleObject(style);
    return this;
  }
}

const useStyle = (styles, use, id) => new ZikoUseStyle(styles, use, id);

const addSuffixeToNumber=(value,suffixe="px")=>{
  if(typeof value === "number") value+=suffixe;
  if(value instanceof Array)value=value.map(n=>typeof n==="number"?n+=suffixe:n).join(" ");
  return value;
};

class ZikoUIElementStyle{
    constructor(defaultStyle={}){
        this.target=null;
        this.styles=new Map(
            [["default",defaultStyle]]
        );
        this.cache={
            isHidden:false,
            isFaddedOut:false,
            transformation:{
                Flip:[0,0,0],
                matrix:new Matrix([
                    [1,0,0,0],
                    [0,1,0,0],
                    [0,0,1,0],
                    [0,0,0,1]
                ])
            }
        };
    }
    style(styles){
        for(const [key, value] of Object.entries(styles)){
            if(Str.isCamelCase(key)){
                delete styles[key];
                Object.assign(styles,{[Str.camel2hyphencase(key)]:value});
            }
        }
        if(this?.target?.element?.style)Object.assign(this?.target?.element?.style, styles);
        return this;
    }
    linkTo(target){
        this.target=target;
        return this;
    }
    use(name="default"){
        this.style(this.styles.get(name));
        return this;
    }
    update(name,styles){
        const old=this.styles.get(name);
        old?this.styles.set(name,Object.assign(old,styles)):this.styles.set(name,styles);
        return this;
    }
    add(name,styles){
        this.styles.set(name,styles);
        return this;
    }
    replace(name,styles){
        this.styles.set(name,styles);
        return this;
    }
    delete(...names){
        names.forEach(n=>this.styles.delete(n));
        return this;
    }
    updateDefaultStyle(){
        const defaultStyle=Object.fromEntries(
            Object.entries(this.target.element.style).filter(n=>isNaN(+n[0]))
        );   
        this.update("default",defaultStyle);
        return this;
    }
    hover(styles){
        //this.updateDefaultStyle()
        if(styles)this.add("hover",styles);
        this.target?.element?.addEventListener("pointerenter",()=>this.use("hover"));
        this.target?.element?.addEventListener("pointerleave",()=>this.use("default"));
        return this;
    }
    // Checkers 
    isInline(){
        return getComputedStyle(this.target.element).display.includes("inline");
    }
    isBlock(){
        return !(this.isInline());
    }
    // Size
    size(width,height){
        this.style({
            width,
            height
        });
        return this;
    }
    width(w){
        if(w instanceof Object){
          if(w instanceof Array)w={min:w[0],max:w[1]};
          if("min" in w || "max" in w){
            let min= w.min ?? w.max;
            let max= w.max ?? w.min;
            min=addSuffixeToNumber(min,"px");
            max=addSuffixeToNumber(max,"px"); 
            this.style({ minWidth: min, maxWidth: max }, { target, maskVector });
          }
        }
        else {
          w=addSuffixeToNumber(w,"px");
          this.style({width:w});
        }
        return this
    }
    height(h){
        if(h instanceof Object){
          if(h instanceof Array)h={min:h[0],max:h[1]};
          if("min" in h || "max" in h){
            let min= h.min ?? h.max;
            let max= h.max ?? h.min;
            min=addSuffixeToNumber(min,"px");
            max=addSuffixeToNumber(max,"px"); 
            this.style({ minHeight: min, maxHeight: max }, { target, maskVector });
          }
        }
        else {
          h=addSuffixeToNumber(h,"px");
          this.style({height:h});
        }
        return this
    } 
    enableResize(h=false,v=false){
        let resize="none";
        if(h)v?resize="both":resize="horizontal";
        else v?resize="vertical":resize="none";
        this.style({
            resize,
            overflow:"hidden"
        });
        if(this.isInline()){
            console.group("Ziko Issue : Temporarily Incompatible Method");
            console.warn(".enableResize has no effect on inline elements!");
            console.info("%cConsider using other display types such as block, inline-block, flex, or grid for proper resizing behavior.","color:gold;background-color:#3333cc;padding:5px");
            console.groupEnd();
        }
        return this;
    }   
    // Apparence
    hide({after, target, maskVector } = {}){
        if(typeof after==="number"){
            const wrapper=()=>this.hide({target,maskVector});
            setTimeout(wrapper, after);
            clearTimeout(wrapper);
        }
        else {
          this.cache.isHidden=true;
          this.style({display:"none"},{target,maskVector});
        }
        return this;
    }
    show({after, target, maskVector } = {}){
        if(typeof after==="number"){
            const wrapper=()=>this.show({target,maskVector});
            setTimeout(wrapper, after);
            clearTimeout(wrapper);
        }
        else {
          this.cache.isHidden=false;
          this.style({display:""},{target,maskVector});
        }
        return this;
    }
    color(color){
        this.style({color});
        return this;
    }
    background(background){
        this.style({background});
        return this;
    }
    backgroundColor(backgroundColor){
        this.style({backgroundColor});
        return this;
    }
    opacity(opacity, { target, maskVector } = {}) {
        this.style({ opacity }, { target, maskVector });
        return this;
    }
    // Placement
    position(position){
        this.style({position});
        return this
    }
    display(disp, { target, maskVector } = {}) {
        this.style({ display: disp }, { target, maskVector });
        return this;
    }
    zIndex(z){
        this.style({zIndex:z});
        return this;
    }
    float(float, { target, maskVector } = {}) {
        this.style({ float: float }, { target, maskVector });
        return this;
    }
    // Box Model 
    border(border = "1px solid red", { target, maskVector } = {}){
        this.style({border}, { target, maskVector });
        return this;
    }
    borderTop(borderTop = "1px solid red", { target, maskVector } = {}){
        this.style({borderTop}, { target, maskVector });
        return this;
    }
    borderRight(borderRight = "1px solid red", { target, maskVector } = {}){
        this.style({borderRight}, { target, maskVector });
        return this;
    }
    borderBottom(borderBottom = "1px solid red", { target, maskVector } = {}){
        this.style({borderBottom}, { target, maskVector });
        return this;
    }
    borderLeft(borderLeft = "1px solid red", { target, maskVector } = {}){
        this.style({borderLeft}, { target, maskVector });
        return this;
    }
    borderRadius(radius){
        radius=addSuffixeToNumber(radius,"px");
        this.style({ borderRadius: radius }, { target, maskVector });
        return this;
    }
    margin(margin){
        margin=addSuffixeToNumber(margin,"px");
        this.style({ margin }, { target, maskVector });
        return this;
    }
    marginTop(marginTop){
        marginTop=addSuffixeToNumber(marginTop,"px");
        this.style({marginTop});
        return this;
    }
    marginRight(marginRight){
        marginRight=addSuffixeToNumber(marginRight,"px");
        this.style({marginRight});
        return this;
    }
    marginBootom(marginBootom){
        marginBootom=addSuffixeToNumber(marginBootom,"px");
        this.style({marginBootom});
        return this;
    }
    marginLeft(marginLeft){
        marginLeft=addSuffixeToNumber(marginLeft,"px");
        this.style({marginLeft});
        return this;
    }
    padding(padding){
        padding=addSuffixeToNumber(padding,"px");
        this.style({padding});
        return this;
    }
    paddingTop(paddingTop){
        paddingTop=addSuffixeToNumber(paddingTop,"px");
        this.style({paddingTop});
        return this;
    }
    paddingRight(paddingRight){
        paddingRight=addSuffixeToNumber(paddingRight,"px");
        this.style({paddingRight});
        return this;
    }
    paddingBootom(paddingBootom){
        paddingBootom=addSuffixeToNumber(paddingBootom,"px");
        this.style({paddingBootom});
        return this;
    }
    paddingLeft(paddingLeft){
        paddingLeft=addSuffixeToNumber(paddingLeft,"px");
        this.style({paddingLeft});
        return this;
    }
    // Typographie
    font(font){
        this.style({font});
        return this;
    }
    fontFamily(fontFamily=""){
        this.style({fontFamily});
        return this;
    }
    fontSize(fontSize){
        this.style({fontSize});
        return this;
    }
    // Misc
    cursor(type="pointer"){
        this.style({ cursor: type });
        return this;
    }  
    overflow(x,y){
        const values=["hidden","auto"];
        this.style({
          overflowX:typeof x==="number"?values[x]:x,
          overflowY:typeof y==="number"?values[y]:y
        },{target,maskVector});
        return this;
    }
    clip(polygon, { target, maskVector } = {}) {
        if (typeof polygon === "string") polygon = "polygon(" + polygon + ")";
        this.style({ clipPath: polygon }, { target, maskVector });
        return this;
    }
    // Transfromations
    fadeOut(transitionTimming = 1) {
        this.style({ 
          transition:`opacity ${transitionTimming/1000}s`, 
          opacity: 0 
        });
        this.cache.isFaddedOut=true;
        return this;
    }
    fadeIn(transitionTimming = 1) {
        this.style({ 
          transition: `opacity ${transitionTimming/1000}s`, 
          opacity: 1 
        });
        this.cache.isFaddedOut=false;
        return this;
    }
    toggleFade(t_in = 1000,t_out=t_in){
        this.cache.isFaddedOut?this.fadeIn(t_in):this.fadeOut(t_out);
        return this;
    }
    morphBorderRadius(newValue, transitionTimming){
        this.style({ 
            borderRadius: newValue,
            transition: `borderRadius ${transitionTimming/1000}s`, 
        });
        return this;
    }
    #applyTransformMatrix(transitionTimming){
        const transformMatrix = this.cache.transformation.matrix.arr.join(",");
        this.style({
            transform: `matrix3d(${transformMatrix})`,
            "-webkit-transform": `matrix3d(${transformMatrix})`,
            "-moz-transform": `matrix3d(${transformMatrix})`, 
            "-ms-transform": `matrix3d(${transformMatrix})`, 
            "-o-transform": `matrix3d(${transformMatrix})` 
        });
        if (transitionTimming != 0) this.style({ transition: `transform ${transitionTimming/1000}s ease` });
    }
    translate(dx, dy = dx ,dz = 0, transitionTimming = 0) {
        this.cache.transformation.matrix.set(3,0,dx);
        this.cache.transformation.matrix.set(3,1,dy);
        this.cache.transformation.matrix.set(3,2,dz);
        this.#applyTransformMatrix(transitionTimming);
        return this;
    }
    translateX(dx, transitionTimming = 0) {
        this.cache.transformation.matrix.set(3,0,dx);
        this.#applyTransformMatrix(transitionTimming);
        return this;
    }
    translateY(dy, transitionTimming = 0) {
        this.cache.transformation.matrix.set(3,1,dy);
        this.#applyTransformMatrix(transitionTimming);
        return this;
    }
    translateZ(dz, transitionTimming = 0) {
        const d=-1/this.cache.transformation.matrix[2][2];
        this.cache.transformation.matrix.set(3,2,z);
        this.cache.transformation.matrix.set(3,3,1-(dz/d));
        this.#applyTransformMatrix(transitionTimming);
        return this;
    }
    perspective(distance,transitionTimming=0){
        const z=this.cache.transformation.matrix[3][2];
        this.cache.transformation.matrix.set(2,2,-1/d);
        this.cache.transformation.matrix.set(3,3,1-(z/distance));
        this.#applyTransformMatrix(transitionTimming);
        return this; 
    }
    scale(sx, sy = sx, transitionTimming = 0) {
        this.cache.transformation.matrix.set(0,0,sx);
        this.cache.transformation.matrix.set(1,1,sy);
        // const transformMatrix = this.cache.transformation.matrix.arr.join(",");
        this.#applyTransformMatrix(transitionTimming);
        return this;
    }
    scaleX(x = 1 , transitionTimming = 0) {
        this.cache.transformation.matrix.set(0,0,x);
        // const transformMatrix = this.cache.transformation.matrix.arr.join(",");
        this.#applyTransformMatrix(transitionTimming);
        return this;
    }
    scaleY(y = 1, transitionTimming = 0) {
        this.cache.transformation.matrix.set(1,1,y);
        this.cache.transformation.matrix.arr.join(",");
        this.#applyTransformMatrix(transitionTimming);
        return this;
    }
    skew(x, y = x, transitionTimming = 0) {
        this.cache.transformation.matrix.set(0,1,x);
        this.cache.transformation.matrix.set(1,0,y);
        this.cache.transformation.matrix.arr.join(",");
        this.#applyTransformMatrix(transitionTimming);
        return this;
    }
    skewX(x = 1 , transitionTimming = 0) {
        this.cache.transformation.matrix.set(0,1,x);
        this.cache.transformation.matrix.arr.join(",");
        this.#applyTransformMatrix(transitionTimming);
        return this;
    }
    skewY(y = 1, transitionTimming = 0) {
        this.cache.transformation.matrix.set(1,0,y);
        this.cache.transformation.matrix.arr.join(",");
        this.#applyTransformMatrix(transitionTimming);
        return this;
    }
    rotateX(rx, transitionTimming = 0) {
        this.cache.transformation.matrix.set(1,1,cos(rx));
        this.cache.transformation.matrix.set(1,2,-sin(rx));
        this.cache.transformation.matrix.set(2,1,sin(rx));
        this.cache.transformation.matrix.set(1,2,cos(rx));
        this.#applyTransformMatrix(transitionTimming);   
        return this;
    }
    rotateY(ry, transitionTimming = 0) {
        this.cache.transformation.matrix.set(0,0,cos(ry));
        this.cache.transformation.matrix.set(0,2,sin(ry));
        this.cache.transformation.matrix.set(2,0,-sin(ry));
        this.cache.transformation.matrix.set(2,2,cos(ry));
        this.#applyTransformMatrix(transitionTimming);   
        return this;
    }
    rotateZ(rz, transitionTimming = 0) {
        this.cache.transformation.matrix.set(0,0,cos(rz));
        this.cache.transformation.matrix.set(0,1,-sin(rz));
        this.cache.transformation.matrix.set(1,0,sin(rz));
        this.cache.transformation.matrix.set(1,1,cos(rz)); 
        this.#applyTransformMatrix(transitionTimming);  
        return this;
    }
    flipeX(transitionTimming = 1) {
        this.cache.transformation.Flip[0] += 180;
        this.cache.transformation.Flip[0] %= 360;
        this.rotateX(this.cache.transformation.Flip[0], transitionTimming);
        return this;
    }
    flipeY(transitionTimming = 1) {
        this.cache.transformation.Flip[1] += 180 ;
        this.cache.transformation.Flip[1] %= 360;
        this.rotateY(this.cache.transformation.Flip[1], transitionTimming);
        return this;
      }
    flipeZ(transitionTimming = 1) {
        this.cache.transformation.Flip[2] += 180;
        this.cache.transformation.Flip[2] %= 360;
        this.rotateZ(this.cache.transformation.Flip[2], transitionTimming);
        return this;
    }
    slideHeightIn(transitionTimming = 1, h = this.h) {
        this.style({ transition: transitionTimming + "s", height: h });
        return this;
    }
    slideHeightOut(transitionTimming = 1) {
        this.style({ transition: transitionTimming + "s", height: 0 });
        this.target?.element?.n("transitionend", () =>
          this.style({ opacity: "none" }),
        );
        return this;
      }
    slideWidthIn(transitionTimming = 1, w = this.w) {
        this.style({ transition: transitionTimming + "s", width: w });
        return this;
    }
    slideWidthOut(transitionTimming = 1) {
        this.style({ transition: transitionTimming + "s", width: 0 });
        const wrapper=()=>{
            this.style({ opacity: "none" });
        };
        this.target?.element?.addEventListener("transitionend",wrapper);
        this.target?.element?.removeEventListener("transitionend",wrapper);
        return this;
    }
    slideIn({ transitionTimming = 1, w = "100%", h = "auto" } = {}) {
        this.style({
          transition: transitionTimming + "s",
          width: w,
          height: h,
          visibility: "visible",
        });
        return this;
    }
    slideOut({ transitionTimming = 1, width = 0, heightransitionTimming = 0 } = {}) {
        this.style({
          visibility: "hidden",
          transition: transitionTimming + "s",
          opacity: "none",
          width: width,
          height: height,
        });
        const wrapper=()=>{
            this.style({ opacity: "none" });
        };
        this.target?.element?.addEventListener("transitionend",wrapper);
        this.target?.element?.removeEventListener("transitionend",wrapper);
        return this;
    }
      
}

function EVENT_CONTROLLER(e,EVENT,setter,push_object){
    this.event=e;
    if(this.cache.preventDefault[EVENT])e.preventDefault();
    console.log({setter});
    if(setter)setter();
    if(this.cache.stream.enabled[EVENT]&&push_object)this.cache.stream.history[EVENT].push(push_object);
    this.cache.callbacks[EVENT].map(n=>n(this));
    return this;
}
class ZikoEvent{
    constructor(target){
        this.target=null;
        this.setTarget(target);
        this.__dispose=this.dispose.bind(this);
        // this.EventIndex=Garbage.Pointer.data.length;
        // Garbage.Pointer.data.push({event:this,index:this.EventIndex});
    }
    get targetElement(){
        return this.target.element
    }
    setTarget(UI){
        this.target=UI;
        return this;
    }
    __handle(event,handler,dispose){
        const EVENT=(event==="drag")?event:`${this.cache.prefixe}${event}`;
        this.dispose(dispose);
        this.targetElement?.addEventListener(EVENT,handler);
        return this;   
    }
    __onEvent(event,dispose,...callbacks){
        if(callbacks.length===0){
            if(this.cache.callbacks.length>1){
                this.cache.callbacks.map(n=>e=>n.call(this,e));
            }   
            else {
                return this;
            }
        }
        else this.cache.callbacks[event]=callbacks.map(n=>e=>n.call(this,e));
        this.__handle(event,this.__controller[event],dispose);
        return this;  
    }
    preventDefault(config={}){
        Object.assign(this.cache.preventDefault,config);
        return this;
    }
    pause(config={}){
        const all=Object.fromEntries(Object.keys(this.cache.stream.enabled).map(n=>[n,true]));
        config={...all,...config};
        for(let key in config){
            if(config[key]){
                this.targetElement?.removeEventListener(`${this.cache.prefixe}${key}`,this.__controller[`${this.cache.prefixe}${key}`]);
                this.cache.paused[`${this.cache.prefixe}${key}`]=true;
            }
        }
        return this;
     }
    resume(config={}){
        const all=Object.fromEntries(Object.keys(this.cache.stream.enabled).map(n=>[n,true]));
        config={...all,...config};
        for(let key in config){
            if(config[key]){
                this.targetElement?.addEventListener(`${this.cache.prefixe}${key}`,this.__controller[`${this.cache.prefixe}${key}`]);
                this.cache.paused[`${this.cache.prefixe}${key}`]=false;
            }
        }
        return this;
     }
    dispose(config={}){
        this.pause(config);
        return this;
     }
    stream(config={}){
        this.cache.stream.t0=Date.now();
        const all=Object.fromEntries(Object.keys(this.cache.stream.enabled).map(n=>[n,true]));
        config={...all,...config};
        Object.assign(this.cache.stream.enabled,config);
        return this;
     }
    clear(config={}){
        const all=Object.fromEntries(Object.keys(this.cache.stream.clear).map(n=>[n,true]));
        config={...all,...config};
        for(let key in config){
            if(config[key]){
                this.cache.stream.history[key]=[];
            }
        }
        return this;
    }
}

function input_controller(e){
    EVENT_CONTROLLER.call(this,e,"input",null,null);
}
function change_controller(e){
    EVENT_CONTROLLER.call(this,e,"change",null,null);
}
class ZikoEventInput extends ZikoEvent{
    constructor(target){
        super(target);
        this.event=null;
        this.cache={
            prefixe:"",
            preventDefault:{
                input:false,
                change:false,
            },
            paused:{
                input:false,
                change:false,      
            },
            stream:{
                enabled:{
                    input:false,
                    change:false,
                },
                clear:{
                    input:false, 
                    change:false,         
                },
                history:{
                    input:[],
                    change:[],
                }
            },
            callbacks:{
                input:[],
                change:[],
            }
        };
        this.__controller={
            input:input_controller.bind(this),
            change:change_controller.bind(this),
        };
    }
    get value(){
        return this.target.value;
    }
    onInput(...callbacks){
        this.__onEvent("input",{},...callbacks);
        return this;
     }
    onChange(...callbacks){
        this.__onEvent("change",{},...callbacks);
        return this;
     }     
}
const useInputEvent=target=>new ZikoEventInput(target);

function hashchange_controller(e){
    EVENT_CONTROLLER.call(this,e,"hashchange",null,null);
}
class ZikoEventHash extends ZikoEvent{
    constructor(target){
        super(target);
        this.event=null;
        this.cache={
            prefixe:"",
            preventDefault:{
                hashchange:false,
            },
            paused:{
                hashchange:false,      
            },
            stream:{
                enabled:{
                    hashchange:false,

                },
                clear:{
                    hashchange:false, 
         
                },
                history:{
                    hashchange:[],
                }
            },
            callbacks:{
                hashchange:[],
            }
        };
        this.__controller={
            hashchange:hashchange_controller.bind(this),
        };
    }
    onChange(...callbacks){
        this.__onEvent("hashchange",{},...callbacks);
        return this;
     }    
}
const useHashEvent=target=>new ZikoEventHash(target);

const custom_event_controller=event_name=>function(e){
    EVENT_CONTROLLER.call(this,e,event_name,null,null);
};
class ZikoCustomEvent extends ZikoEvent{
    constructor(target){
        super(target);
        this.event=null;
        this.cache={
            prefixe:"",
            preventDefault:{
            },
            paused:{
            },
            stream:{
                enabled:{
                },
                clear:{
                },
                history:{
                }
            },
            callbacks:{
            }
        };
        this.__controller={
        };
    }
    #init(event_name){
        this.cache.preventDefault[event_name]=false;
        this.cache.paused[event_name]=false;
        this.cache.stream.enabled=false;
        this.cache.stream.clear=false;
        this.cache.stream.history=[];
        this.cache.callbacks[event_name]=[];
        this.__controller[event_name]=custom_event_controller(event_name).bind(this);
        return this;
    }
    on(event_name,...callbacks){
        if(!(this.__controller[event_name]))this.#init(event_name);
        this.__onEvent(event_name,{},...callbacks);
        return this;
     }  
    emit(event_name,detail={}){
        if(!(this.__controller[event_name]))this.#init(event_name);
        this.detail=detail;
        const event=new Event(event_name);
        this.targetElement.dispatchEvent(event);
        return this;
    }
}
const useCustomEvent=target=>new ZikoCustomEvent(target);

class ZikoEventSwipe extends ZikoEvent {
  constructor(target, width_threshold = 0.3, height_threshold = 0.3) {
    super(target);
    const { removeListener, setWidthThreshold, setHeightThreshold } = init_swipe_event_handler(
      this.target?.element,
      width_threshold,
      height_threshold,
      this.target.width,
      this.target.height,
    );
    this.cache = {
      width_threshold,
      height_threshold,
      removeListener,
      setWidthThreshold,
      setHeightThreshold,
      legacyTouchAction : globalThis?.document?.body?.style?.touchAction,
      prefixe: "",
      preventDefault: {
        swipe: false,
      },
      paused: {
        swipe: false,
      },
      stream: {
        enabled: {
          swipe: false,
        },
        clear: {
          swipe: false,
        },
        history: {
          swipe: [],
        },
      },
      callbacks: {
        swipe: [],
      },
    };
    this.__controller = {
      swipe: swipe_controller.bind(this),
    };
  }
  onSwipe(...callbacks) {
    Object.assign(globalThis?.document?.body?.style,{touchAction:"none"});
    this.__onEvent("swipe", {}, ...callbacks);
    return this;
  }
  updateThresholds(width_threshold = this.cache.width_threshold, height_threshold = this.cache.height_threshold) {
    if (width_threshold !== undefined) {
      this.cache.setWidthThreshold(width_threshold);
    }
    if (height_threshold !== undefined) {
      this.cache.setHeightThreshold(height_threshold);
    }
    return this;
  }
  destroy() {
    this.cache.removeListener();
    Object.assign(globalThis?.document?.body?.style,{touchAction:this.cache.legacyTouchAction});
    return this;
  }
}
function init_swipe_event_handler(element, width_threshold = 0.50, height_threshold = 0.5, width, height) {
  let Interpolated_width_threshold = lerp(width_threshold, 0, width);
  let Interpolated_height_threshold = lerp(height_threshold, 0, height);
  let startX = 0, startY = 0, endX = 0, endY = 0;
  const pointerDownHandler = (event) => {
    startX = event.clientX;
    startY = event.clientY;
  };
  const pointerUpHandler = (event) => {
    endX = event.clientX;
    endY = event.clientY;
    handleSwipe();
  };
  element?.addEventListener('pointerdown', pointerDownHandler);
  element?.addEventListener('pointerup', pointerUpHandler);
  function handleSwipe() {
    const deltaX = endX - startX;
    const deltaY = endY - startY;
    if (Math.abs(deltaX) > Interpolated_width_threshold || Math.abs(deltaY) > Interpolated_height_threshold) {
      dispatchSwipeEvent(deltaX, deltaY);
    }
  }
  function dispatchSwipeEvent(deltaX, deltaY) {
    const event = globalThis?.CustomEvent ? new CustomEvent('swipe', {
      detail: {
        deltaX: abs(deltaX) < Interpolated_width_threshold ? 0 : sign(deltaX) * norm(abs(deltaX), 0, width),
        deltaY: abs(deltaY) < Interpolated_height_threshold ? 0 : sign(deltaY) * norm(abs(deltaY), 0, height),
        direction: {
          x : abs(deltaX) < Interpolated_width_threshold ? "none" : deltaX > 0 ? "right" : "left",
          y : abs(deltaY) < Interpolated_height_threshold ? "none" : deltaY > 0 ? 'down' : 'up',
        },
      },
    }) : null;
    element?.dispatchEvent(event);
  }
  function setWidthThreshold(new_width_threshold) {
    Interpolated_width_threshold = lerp(new_width_threshold, 0, width);
  }
  function setHeightThreshold(new_height_threshold) {
    Interpolated_height_threshold = lerp(new_height_threshold, 0, height);
  }
  return {
    removeListener() {
      element?.removeEventListener('pointerdown', pointerDownHandler);
      element?.removeEventListener('pointerup', pointerUpHandler);
      console.log('Swipe event listeners removed');
    },
    setWidthThreshold,
    setHeightThreshold,
  };
}
function swipe_controller(e) {
  EVENT_CONTROLLER.call(this, e, "swipe", null, null);
}
const useSwipeEvent = (target, width_threshold, height_threshold) => new ZikoEventSwipe(target, width_threshold, height_threshold);
/*
a=p("ALLL").size("300px","300px").style({background:"red",userSelect:"none"})
t=text("")
ev=useSwipeEvent(a, .1, .3)
ev.onSwipe(e=>{
// t.setValue(`
//  vertical direction : ${e.event.detail.direction.y}
//  horizontal direction : ${e.event.detail.direction.x}
//  deltaX : ${e.event.detail.deltaX}
//  deltaY : ${e.event.detail.deltaY}
// `)
e.target.st.translate(e.event.detail.deltaX * 200, e.event.detail.deltaY * 200,0, 500)
})
*/
/*
a=p("ALLL")
.size("300px","300px")
.style({background:"red",userSelect:"none"})
.onSwipe(
.3,
.3,
e=>{
  e.target.st.translate(e.event.detail.deltaX * 200, e.event.detail.deltaY * 200,0, 500)
})
*/

// export * from "./click.js";
// export * from "./pointer.js";
// export * from "./mouse.js";
// export * from "./wheel.js";
// export * from "./key.js";
// export * from "./drag.js";
// export * from "./clipboard.js";
// export * from "./focus.js";

var Events = /*#__PURE__*/Object.freeze({
  __proto__: null,
  ZikoCustomEvent: ZikoCustomEvent,
  ZikoEventHash: ZikoEventHash,
  ZikoEventInput: ZikoEventInput,
  ZikoEventSwipe: ZikoEventSwipe,
  useCustomEvent: useCustomEvent,
  useHashEvent: useHashEvent,
  useInputEvent: useInputEvent,
  useSwipeEvent: useSwipeEvent
});

class ZikoMutationObserver {
    constructor(targetUIElement, options) {
      this.target = targetUIElement;
      this.observer = null;
      this.cache = {
        options : options || { attributes: true, childList: true, subtree: true },
        streamingEnabled : true,
        lastMutation : null,
        mutationHistory : {
          // attributes: [],
          // childList: [],
          // subtree: [],
        },
      };
  // children to Items : a.items.filter(n=>n.element === a[0].element)
      this.observeCallback = (mutationsList, observer) => {
        // if(this.cache.lastUpdatedAttr){
        //   this.cache.lastUpdatedAttr = mutation.target.getAttribute(mutation.attributeName)
        // }
        if (this.cache.streamingEnabled) {
          for (const mutation of mutationsList) {
            switch(mutation.type){
              case 'attributes':this.cache.mutationHistory.attributes.push(mutation.target.getAttribute(mutation.attributeName));break;
              case 'childList':this.cache.mutationHistory.childList.push(mutation);break;
              case 'subtree':this.cache.mutationHistory.subtree.push(mutation);break;
            }
          }
        }
        if (this.callback) {
          this.callback(mutationsList, observer);
        }
      };
    }
  
    observe(callback) {
      if(!this.observer) {
        if(!globalThis.MutationObserver) {
          console.log("MutationObserver Nor Supported");
          return;
        }
        this.observer = new MutationObserver(this.cache.observeCallback);
        this.observer.observe(this.target.element, this.cache.options);
        // this.callback = ([e]) => callback.call(e,this.target);
        this.callback = ([e]) => callback.call(e, this);
        this.cache.streamingEnabled = true;
      }
    }
  
    pause(options) {
      if (this.observer) {
        this.observer.disconnect();
        if (options) {
          this.observer.observe(this.target, options);
        }
      }
    }
  
    reset(options) {
      if (this.observer) {
        this.observer.disconnect();
        this.observer.observe(this.target, options || this.cache.options);
      }
    }
  
    clear() {
      if (this.observer) {
        this.observer.disconnect();
        this.observer = null;
        this.cache.mutationHistory = {
          attributes: [],
          childList: [],
          subtree: [],
        };
      }
      this.cache.streamingEnabled = false;
      return this;
    }
  
    getMutationHistory() {
      return this.cache.mutationHistory;
    }
  
    enableStreaming() {
      this.cache.streamingEnabled = true;
      return this;
    }
  
    disableStreaming() {
      this.cache.streamingEnabled = false;
      return this;
    }
  }



const watch=(targetUIElement,options={},callback=null)=>{
    const Observer= new ZikoMutationObserver(targetUIElement,options);
    if(callback)Observer.observe(callback);
    return Observer
};

class ZikoWatchAttr extends ZikoMutationObserver{
    constructor(targetUIElement,callback){
      super(targetUIElement,{ attributes: true, childList: false, subtree: false });
      Object.assign(this.cache,{
        observeCallback : (mutationsList, observer) =>{
          for (const mutation of mutationsList) {
            this.cache.lastMutation = {
              name : mutation.attributeName,
              value : mutation.target.getAttribute(mutation.attributeName)
            };
            if (this.cache.streamingEnabled) this.cache.mutationHistory.attributes.push(this.cache.lastMutation);
        }
        if (this.callback) this.callback(mutationsList, observer);  
      }  
      });
      this.cache.mutationHistory.attributes = [];
      if(callback)this.observe(callback);
    }
    get history(){
      return this.cache.mutationHistory.attributes;
    }
  }
const watchAttr=(targetUIElement, callback)=>new ZikoWatchAttr(targetUIElement, callback);

class ZikoWatchChildren extends ZikoMutationObserver{
    constructor(targetUIElement,callback){
      super(targetUIElement,{ attributes: false, childList: true, subtree: false });
      Object.assign(this.cache,{
        observeCallback : (mutationsList, observer) =>{
          for (const mutation of mutationsList) {
            if(mutation.addedNodes)this.cache.lastMutation = {
              type : "add",
              item : this.target.find(n=>n.element === mutation.addedNodes[0])[0],
              previous : this.target.find(n=>n.element === mutation.previousSibling)[0]
            };
            else if(mutation.addedNodes)this.cache.lastMutation = {
              type : "remove",
              item : this.target.find(n=>n.element === mutation.removedNodes[0])[0],
              previous : this.target.find(n=>n.element === mutation.previousSibling)[0]
            };
            if (this.cache.streamingEnabled) this.cache.mutationHistory.children.push(this.cache.lastMutation);
        }
        if (this.callback) this.callback(mutationsList, observer);  
      }  
      });
      this.cache.mutationHistory.children = [];
      if(callback)this.observe(callback);
    }
    get item(){
      return this.cache.lastMutation.item;
    }
    get history(){
      return this.cache.mutationHistory.children;
    }
  }

const watchChildren=(targetUIElement, callback)=>new ZikoWatchChildren(targetUIElement, callback);

class ZikoIntersectionObserver{
    constructor(UIElement,callback,{threshold=0,margin=0}={}){
        this.target=UIElement;
        this.config={
            threshold,
            margin
        };
        if(!globalThis.IntersectionObserver){
            console.log("IntersectionObserver Not Supported");
            return;
        }
        this.observer=new IntersectionObserver((entries)=>{
            this.entrie=entries[0];
            callback(this);
        },{
            threshold:this.threshold,
        });
    }
    get ratio(){
        return this.entrie.intersectionRatio;
    }
    get isIntersecting(){
        return this.entrie.isIntersecting;
    }
    setThreshould(threshold){
        this.config.threshold=threshold;
        return this;
    }
    setMargin(margin){
        margin=(typeof margin === "number")?margin+"px":margin;
        this.config.margin=margin;
        return this;
    }
    start(){
        this.observer.observe(this.target.element);
        return this;
    }
    stop(){
        return this;
    }
}

const watchIntersection=(UI,callback,config)=>new ZikoIntersectionObserver(UI,callback,config);

class ZikoResizeObserver{
    constructor(UIElement,callback){
        this.target=UIElement;
        this.contentRect=null;
        this.observer=new ResizeObserver(()=>{
           callback(this);
        });
    }
    get BoundingRect(){
        return this.target.element.getBoundingClientRect();
    }
    get width(){
        return this.BoundingRect.width;
    }
    get height(){
        return this.BoundingRect.height;
    }
    get top(){
        return this.BoundingRect.top;
    }
    get bottom(){
        return this.BoundingRect.bottom;
    }
    get right(){
        return this.BoundingRect.right;
    }
    get left(){
        return this.BoundingRect.left;
    }
    get x(){
        return this.BoundingRect.x;
    }
    get y(){
        return this.BoundingRect.y;
    }
    start(){
        this.observer.observe(this.target.element);
        return this;
    }
    stop(){
        this.observer.unobserve(this.target.element);
        return this;
    }
}

const watchSize=(UI,callback)=>new ZikoResizeObserver(UI,callback);

class ZikoScreenObserver {
    constructor(callback=e=>console.log({x:e.x,y:e.y})) {
      this.cache={};
      this.previousX = globalThis?.screenX;
      this.previousY = globalThis?.screenY;
    }
    update(){
        Object.assign(this.cache,{
            screenXLeft : globalThis?.screenX, // CORRECT
            screenXRight : globalThis?.screen.availWidth - globalThis?.screenX, // CORRECT
            screenYTop : globalThis?.screenY, // CORRECT
            screenYBottom : globalThis?.screen.availHeight - globalThis?.screenY - globalThis?.outerHeight, // TO TEST
            screenCenterX : globalThis?.screen.availWidth/2, // CORRECT
            screenCenterY : globalThis?.screen.availHeight/2,// CORRECT
            windowCenterX : globalThis?.outerWidth/2+globalThis?.screenX, // CORRECT
            windowCenterY : globalThis?.outerHeight/2+ globalThis?.screenY, // FALSE
            deltaCenterX : globalThis?.screen.availWidth/2-globalThis?.outerWidth/2+globalThis?.screenX, // CORRECT
            deltaCenterY : null //
        });
    }
    get x0(){
        return map(globalThis?.screenX, 0, globalThis.screen.availWidth, -1, 1);
    }
    get y0(){
        return - map(globalThis?.screenY, 0, globalThis.screen.availHeight, -1, 1);
    }
    get x1(){
        return map(globalThis?.screenX + globalThis?.outerWidth, 0, globalThis.screen.availWidth, -1, 1);
    }
    get y1(){
        return - map(globalThis?.screenY + globalThis?.outerHeight, 0, globalThis.screen.availHeight, -1, 1);
    }
    get cx(){
        return map(globalThis?.outerWidth/2+globalThis?.screenX, 0, globalThis.screen.availWidth, -1, 1);
    }
    get cy(){
        return - map(globalThis?.outerHeight/2+ globalThis?.screenY, 0, globalThis.screen.availHeight, -1, 1);
    }
}

const watchScreen=(callback)=>new ZikoScreenObserver(callback);

var Observer = /*#__PURE__*/Object.freeze({
  __proto__: null,
  ZikoMutationObserver: ZikoMutationObserver,
  watch: watch,
  watchAttr: watchAttr,
  watchChildren: watchChildren,
  watchIntersection: watchIntersection,
  watchScreen: watchScreen,
  watchSize: watchSize
});

const useSuccesifKeys=(self,keys=[],callback=()=>{})=>{
    self.cache.stream.enabled.down=true;
    const length=keys.length;
    const LastKeysDown=self.cache.stream.history.down.slice(-length).map(n=>n.key);
    
        if(keys.join("")===LastKeysDown.join("")){
            self.event.preventDefault();
            callback.call(self,self);
        }
    
};

class ZikoUseEventEmitter {
    constructor() {
      this.events = {};
      this.maxListeners = 10; 
    }
    on(event, listener) {
      if (!this.events[event]) {
        this.events[event] = [];
      }
      this.events[event].push(listener);  
      if (this.events[event].length > this.maxListeners) {
        console.warn(`Warning: Possible memory leak. Event '${event}' has more than ${this.maxListeners} listeners.`);
      }
    }
    once(event, listener) {
      const onceListener = (data) => {
        this.off(event, onceListener); // Remove the listener after it's been called
        listener(data);
      };
      this.on(event, onceListener);
    }
  
    off(event, listener) {
      const listeners = this.events[event];
      if (listeners) {
        const index = listeners.indexOf(listener);
        if (index !== -1) {
          listeners.splice(index, 1);
        }
      }
    }
  
    emit(event, data) {
      const listeners = this.events[event];
      if (listeners) {
        listeners.forEach(listener => {
          listener(data);
        });
      }
    }
  
    clear(event) {
      if (event) {
        delete this.events[event];
      } else {
        this.events = {};
      }
    }
  
    setMaxListener(event, max) {
      this.maxListeners = max;
    }
  
    removeAllListeners(event) {
      if (event) {
        this.events[event] = [];
      } else {
        this.events = {};
      }
    }
  }

const useEventEmitter=()=>new ZikoUseEventEmitter();

let ZikoUseFavIcon$1 = class ZikoUseFavIcon{
    constructor(FavIcon,useEventEmitter=true){
        this.#init();
        this.cache={
            Emitter:null
        };
        if(useEventEmitter)this.useEventEmitter();
        this.set(FavIcon);
    }
    #init(){     
        this.__FavIcon__ = document.querySelector("link[rel*='icon']") || document?.createElement('link');   
        this.__FavIcon__.type = 'image/x-icon';
        this.__FavIcon__.rel = 'shortcut icon';
        return this;
    }
    set(href){
        if(href!==this.__FavIcon__.href){
            this.__FavIcon__.href=href;
            if(this.cache.Emitter)this.cache.Emitter.emit("ziko:favicon-changed");
        }
        return this;
    }
    get current(){
        return document.__FavIcon__.href;
    }
    onChange(callback){
        if(this.cache.Emitter)this.cache.Emitter.on("ziko:favicon-changed",callback);
        return this;
    }
    useEventEmitter(){
        this.cache.Emitter=useEventEmitter();
        return this;
    }

};
const useFavIcon$1=(FavIcon,useEventEmitter)=>new ZikoUseFavIcon$1(FavIcon,useEventEmitter);

let ZikoMeta$1 = class ZikoMeta{
    constructor({viewport,charset,description,author,keywords}){
        this.document = globalThis?.document; 
        this.meta={};
        this.init({viewport,charset,description,author,keywords});
    }
    init({viewport,charset,description,author,keywords}){
        viewport && this.setViewport(viewport);
        charset && this.setCharset(charset);
        description && this.describe(description);
        author && this.setAuthor(author);
        keywords && this.setKeywords(keywords);
    }
    set(key,value){
        key = key.toLowerCase();
        const isCharset = (key === "charset");
        const meta = isCharset ? document.querySelector("meta[charset]"):document.querySelector(`meta[name=${key}]`);
        this.meta=meta?? document?.createElement("meta");
        if(isCharset) this.meta.setAttribute("charset",value);
        else {
            this.meta.setAttribute("name",key);
            this.meta.setAttribute("content",value);
        }
        if(!meta)this.document.head.append(this.meta);
        return this;     
    }
    setCharset(charset="utf-8"){
        this.set("charset",charset);
        return this;
    }
    describe(description){
        this.set("description",description);
        return this;    
    }
    setViewport(viewport="width=device-width, initial-scale=1.0"){
        this.set("viewport",viewport);
        return this;    
    }
    setKeywords(...keywords){
        // keywords.push("zikojs");
        keywords=[...new Set(keywords)].join(", ");
        this.set("keywords",keywords);
        return this;
    }
    setAuthor(author){
        this.set("author",author);
        return this;
    }
};
const useMeta$1=({viewport,charset,description,author,keywords})=>new ZikoMeta$1({viewport,charset,description,author,keywords});

let ZikoUseTitle$1 = class ZikoUseTitle{
    constructor(title=document.title,useEventEmitter=true){
        this.cache={
            Emitter:null
        };
        if(useEventEmitter)this.useEventEmitter();
        this.set(title);
    }
    useEventEmitter(){
        this.cache.Emitter=useEventEmitter();
        return this;
    }
    set(title){
        if(title!==document.title){
            document.title=title;
            if(this.cache.Emitter)this.cache.Emitter.emit("ziko:title-changed");
        }
        return this;
    }
    get current(){
        return document.title;
    }
    onChange(callback){
        if(this.cache.Emitter)this.cache.Emitter.on("ziko:title-changed",callback);
        return this;
    }
};
const useTitle$1=(title, useEventEmitter)=>new ZikoUseTitle$1(title, useEventEmitter);

// import {useLink} from "./";
let ZikoHead$1 = class ZikoHead{
    constructor({title,lang,icon,meta,noscript}){
        this.html = globalThis?.document?.documentElement;
        this.head = globalThis?.document?.head;

        title && useTitle$1(title);
        lang && this.setLang(lang);
        icon && useFavIcon$1(icon);
        meta && useMeta$1(meta);
        noscript && this.setNoScript();
    }
    setLang(lang){
        this.html.setAttribute("lang",lang);
    }
    setNoScript(content){

    }
};

const useHead$1=({ title, lang, icon, meta, noscript })=>new ZikoHead$1({ title, lang, icon, meta, noscript });

/*
 [
            {
                query: '(min-width: 600px)',
                callback: () => console.log(1)
            },
            {
                query: '(max-width: 300px)',
                callback: () => console.log(2)
            }
        ]
*/
class ZikoUseMediaQuery {
    constructor(mediaQueryRules=[],fallback=()=>{}) {
        this.mediaQueryRules = mediaQueryRules;
        this.fallback = fallback;
        this.lastCalledCallback = null;
        this.init();
    }

    init() {
        this.mediaQueryRules.forEach(({ query, callback }) => {
            const mediaQueryList = globalThis.matchMedia(query);
            const checkMatches = () => {
                const anyMatch = this.mediaQueryRules.some(({ query }) => globalThis.matchMedia(query).matches);
                if (mediaQueryList.matches) {
                    callback();
                    this.lastCalledCallback = callback;
                } else if (!anyMatch && this.lastCalledCallback !== this.fallback) {
                    this.fallback();
                    this.lastCalledCallback = this.fallback;
                }
            };
            checkMatches();
            mediaQueryList.addListener(checkMatches);
        });
    }
}

const useMediaQuery = (mediaQueryRules,fallback) => new ZikoUseMediaQuery(mediaQueryRules,fallback);

class ZikoUseRoot{
    constructor(props){
        this.props={};
        props && this.set(props);
    }
    get(prop){
        return this.props[prop]
    }
    // getStaticValue(){
    //     return document.documentElement.style.getPropertyValue("--primary-col")
    // }
    set(props){
        Object.entries(props).forEach(([key,value])=>this.#setOneProp(key, value));
        return this;
    }
    #setOneProp(prop, value){
        const CssProp = `--${Str.camel2hyphencase(prop)}`;
        document.documentElement.style.setProperty(CssProp,value);
        Object.assign(this.props, {[prop]: `var(${CssProp})`});
        Object.assign(this, {[prop] : `var(${CssProp})`});
    }
}

const useRootValue=CssVar=>{
    if(!CssVar.startsWith("--")) CssVar = `--${Str.camel2hyphencase(CssVar)}`;
    return `var(${CssVar})`
};
// const useRootStaticValue=CssVar=>{
//     if(!CssVar.startsWith("--")) CssVar = `--${Str.camel2hyphencase(CssVar)}`
//     return globalThis.document.documentElement.style.getPropertyValue(CssVar)  
// }
const useRoot=(props)=>new ZikoUseRoot(props);

// export * from "./window"

var Hooks = /*#__PURE__*/Object.freeze({
  __proto__: null,
  ZikoHead: ZikoHead$1,
  ZikoUseRoot: ZikoUseRoot,
  ZikoUseStyle: ZikoUseStyle,
  useFavIcon: useFavIcon$1,
  useHead: useHead$1,
  useMediaQuery: useMediaQuery,
  useMeta: useMeta$1,
  useRoot: useRoot,
  useRootValue: useRootValue,
  useStyle: useStyle,
  useSuccesifKeys: useSuccesifKeys,
  useTitle: useTitle$1
});

const Reactivity={
    ...Events,
    ...Observer,
    ...Hooks,
};

class ZikoUIElement extends ZikoUINode{
  constructor(element, name="", {el_type="html", useDefaultStyle=false}={}){
    super();
    this.target = globalThis.__Ziko__.__Config__.default.target||globalThis?.document?.body;
    if(typeof element === "string") {
      switch(el_type){
        case "html" : element = globalThis?.document?.createElement(element); break;
        case "svg" : element = globalThis?.document?.createElementNS("http://www.w3.org/2000/svg", element);
        default : throw Error("Not supported")
      }
    }
    else {
      this.target = element.parentElement;
    }
    // if(element)this.__ele__ = element;
    compose(
      this, 
      DomMethods,
      IndexingMethods,
      EventsMethodes
    );
    // if(false){
    //   import("../methods/tree.js").then(({ default: ExternalMethods }) => {
    //     compose(this, ExternalMethods);
    //   });
    // }
    Object.assign(this.cache, {
      name,
      isInteractive : [true, false][Math.floor(2*Math.random())],
      parent:null,
      isBody:false,
      isRoot:false,
      isHidden: false,
      isFrozzen:false,
      legacyParent : null,
      style: new ZikoUIElementStyle({}),
      attributes: {},
      filters: {},
      temp:{}
    });
    this.events = {
      ptr:null,
      mouse:null,
      wheel:null,
      key:null,
      drag:null,
      drop:null,
      click:null,
      clipboard:null,
      focus:null,
      swipe:null,
      custom:null,
    };
    this.observer={
      resize:null,
      intersection:null
    };
    if(element)Object.assign(this.cache,{element});
    this.uuid = `${this.cache.name}-${Random.string(16)}`;
    this.ui_index = globalThis.__Ziko__.__CACHE__.get_ui_index();
    this.cache.style.linkTo(this);
    useDefaultStyle && this.style({ 
      position: "relative",
      boxSizing:"border-box",
      margin:0,
      padding:0,
      width : "auto",
      height : "auto"
     });
    this.items = [];
    globalThis.__Ziko__.__UI__[this.cache.name]?globalThis.__Ziko__.__UI__[this.cache.name]?.push(this):globalThis.__Ziko__.__UI__[this.cache.name]=[this];
    element && globalThis.__Ziko__.__Config__.default.render && this?.render?.();
    if(
      // globalThis.__Ziko__.__Config__.renderingMode !== "spa" 
      // && 
      // !globalThis.__Ziko__.__Config__.isSSC
      // && 
      this.isInteractive()
    ){
      this.setAttr("ziko-hydration-index", globalThis.__Ziko__.__HYDRATION__.index);
      globalThis.__Ziko__.__HYDRATION__.map.set(globalThis.__Ziko__.__HYDRATION__.index, ()=>this);
      globalThis.__Ziko__.__HYDRATION__.increment();
    }
  }
  get element(){
    return this.cache.element;
  }
  isInteractive(){
    return this.cache.isInteractive;
  }
  // Remove get
  isZikoUIElement(){
    return true;
  }
  register(){

    return this;
  }
  get st(){
    return this.cache.style;
  }
  get attr(){
    return this.cache.attributes;
  }
  get evt(){
    return this.events;
  }
  get html(){
    return this.element.innerHTML;
  }
  get text(){
    return this.element.textContent;
  }
  get isBody(){
    return this.element === globalThis?.document.body;
  }
  get parent(){
    return this.cache.parent;
  }
  get width(){
    return this.element.getBoundingClientRect().width;
  }
  get height(){
    return this.element.getBoundingClientRect().height;
  }
  get top(){
    return this.element.getBoundingClientRect().top;
  }
  get right(){
    return this.element.getBoundingClientRect().right;
  }
  get bottom(){
    return this.element.getBoundingClientRect().bottom;
  }
  get left(){
    return this.element.getBoundingClientRect().left;
  }
  clone(render=false) {
    const UI = new this.constructor();
    UI.__proto__=this.__proto__;
    if(this.items.length){
      const items = [...this.items].map(n=>n.clone());
      UI.append(...items);
    }
    else UI.element=this.element.cloneNode(true);
    return UI.render(render);
  }
  style(styles){
    styles instanceof ZikoUseStyle ? this.st.style(styles.current): this.st.style(styles);
    return this;
  }
  size(width,height){
    this.st.size(width,height);
    return this; 
  }
  [Symbol.iterator]() {
    return this.items[Symbol.iterator]();
  }
  maintain() {
  for (let i = 0; i < this.items.length; i++) {
    Object.defineProperty(this, i, {
      value: this.items[i],
      writable: true,
      configurable: true,
      enumerable: false 
      });
    }
  }
  filter(condition_callback, if_callback = () => {}, else_callback = () => {}) {
    const FilterItems = this.items.filter(condition_callback);
    FilterItems.forEach(if_callback);
    this.items
      .filter((item) => !FilterItems.includes(item))
      .forEach(else_callback);
    return this;
  }
  filterByTextContent(text, exactMatch = false) {
    this.items.forEach((n) => n.render());
    this.filter(
      (n) => !(exactMatch ? n.text === text : n.text.includes(text)),
      (e) => e.unrender(),
    );
    // this.items.filter(n=>{
    //   const content=n.element.textContent;
    //   return !(exactMatch?content===text:content.includes(text))
    // }).map(n=>n.unrender());
    //  return this;
  }
  filterByClass(value) {
    this.items.map((n) => n.render());
    this.items
      .filter((n) => !n.classes.includes(value))
      .map((n) => n.unrender());
    return this;
  }
  sortByTextContent(value, displays) {
    let item = this.children;
    item
      .filter((n) => !n.textContent.toLowerCase().includes(value.toLowerCase()))
      .map((n) => {
        n.style.display = "none";
      });
    item
      .filter((n) => n.textContent.toLowerCase().includes(value.toLowerCase()))
      .map((n, i) => (n.style.display = displays[i]));
    //return item.filter(n=>n.style.display!="none")
    item.filter((n) => n.style.display != "none");
    return this;
  }
  get #SwitchedStyleRTL_LTR(){
    const CalculedStyle = globalThis.getComputedStyle(this.element); 
    const SwitchedStyle = {};
    if(CalculedStyle.marginRight!=="0px")Object.assign(SwitchedStyle, {marginLeft: CalculedStyle.marginRight});
    if(CalculedStyle.marginLeft!=="0px")Object.assign(SwitchedStyle, {marginRight: CalculedStyle.marginLeft});
    if(CalculedStyle.paddingRight!=="0px")Object.assign(SwitchedStyle, {paddingLeft: CalculedStyle.paddingRight});
    if(CalculedStyle.paddingLeft!=="0px")Object.assign(SwitchedStyle, {paddingRight: CalculedStyle.paddingLeft});
    if(CalculedStyle.left!=="0px")Object.assign(SwitchedStyle, {right: CalculedStyle.left});
    if(CalculedStyle.right!=="0px")Object.assign(SwitchedStyle, {left: CalculedStyle.right});
    if(CalculedStyle.textAlign === "right")Object.assign(SwitchedStyle, {textAlign: "left"});
    if(CalculedStyle.textAlign === "left")Object.assign(SwitchedStyle, {textAlign: "right"});
    if(CalculedStyle.float === "right")Object.assign(SwitchedStyle, {float: "left"});
    if(CalculedStyle.float === "left")Object.assign(SwitchedStyle, {float: "right"});
    if(CalculedStyle.borderRadiusLeft!=="0px")Object.assign(SwitchedStyle, {right: CalculedStyle.borderRadiusRight});
    if(CalculedStyle.borderRadiusRight!=="0px")Object.assign(SwitchedStyle, {right: CalculedStyle.borderRadiusLeft});
    if(["flex","inline-flex"].includes(CalculedStyle.display)){
      if(CalculedStyle.justifyContent === "flex-end")Object.assign(SwitchedStyle, {justifyContent: "flex-start"});
      if(CalculedStyle.justifyContent === "flex-start")Object.assign(SwitchedStyle, {justifyContent: "flex-end"});
    }
    return SwitchedStyle;
  }
  useRtl(switchAll = false){
    switchAll ? this.style({
      ...this.#SwitchedStyleRTL_LTR,
      direction : "rtl"
    }) : this.style({direction : "rtl"}); 
    return this;
  }
  useLtr(switchAll = false){
    switchAll ? this.style({
      ...this.#SwitchedStyleRTL_LTR,
      direction : "ltr"
    }) : this.style({direction : "ltr"}); 
    return this;
  }
  freeze(freeze){
    this.cache.isFrozzen=freeze;
    return this;
  }
  setTarget(tg) {
    if(this.isBody) return ;
    if (tg?.isZikoUIElement) tg = tg.element;
    this.unrender();
    this.target = tg;
    this.render();
    return this;
  }
  describe(label){
    if(label)this.setAttr("aria-label",label);
  }
  animate(keyframe, {duration=1000, iterations=1, easing="ease"}={}){
    this.element?.animate(keyframe,{duration, iterations, easing});
    return this;
  }
    // Attributes
  #setAttr(name, value){
    if(this.element.tagName !== "svg") name = Str.isCamelCase(name) ? Str.camel2hyphencase(name) : name;
    if(this?.attr[name] && this?.attr[name]===value) return;
    this.element.setAttribute(name, value);
    Object.assign(this.cache.attributes, {[name]:value});
  }
  setAttr(name, value) {
    if(name instanceof Object){
      const [names,values]=[Object.keys(name),Object.values(name)];
      for(let i=0;i<names.length;i++){
        if(values[i] instanceof Array)value[i] = values[i].join(" ");
        this.#setAttr(names[i], values[i]);
      }
    }
    else {
      if(value instanceof Array)value = value.join(" ");
      this.#setAttr(name, value);
    }
    return this;
  }
  removeAttr(...names) {
    for(let i=0;i<names.length;i++)this.element?.removeAttribute(names[i]);
    return this;
  }
  getAttr(name){
    name = Str.isCamelCase(name) ? Str.camel2hyphencase(name) : name;
    return this.element.attributes[name].value;
  }
  setContentEditable(bool = true) {
    this.setAttr("contenteditable", bool);
    return this;
  }
  get children() {
    return [...this.element.children];
  }
  get cloneElement() {
    return this.element.cloneNode(true);
  }
  setClasses(...value) {
    this.setAttr("class", value.join(" "));
    return this;
  }
  get classes(){
    const classes=this.element.getAttribute("class");
    return classes===null?[]:classes.split(" ");
  }
  addClass() {
    /*this.setAttr("class", value);
        return this;*/
  }
  setId(id) {
    this.setAttr("id", id);
    return this;
  }
  get id() {
    return this.element.getAttribute("id");
  }
  onSwipe(width_threshold, height_threshold,...callbacks){
    if(!this.events.swipe)this.events.swipe = useSwipeEvent(this, width_threshold, height_threshold);
    this.events.swipe.onSwipe(...callbacks);
    return this;
  }
  // To Fix
  // onKeysDown({keys=[],callback}={}){
  //   if(!this.events.key)this.events.key = useKeyEvent(this);
  //   this.events.key.handleSuccessifKeys({keys,callback});
  //   return this;
  // }
  // onSelect(...callbacks){
  //   if(!this.events.clipboard)this.events.clipboard = useClipboardEvent(this);
  //   this.events.clipboard.onSelect(...callbacks);
  //   return this;
  // }
  on(event_name,...callbacks){
    if(!this.events.custom)this.events.custom = useCustomEvent(this);
    this.events.custom.on(event_name,...callbacks);
    return this;
  }
  emit(event_name,detail={}){
    if(!this.events.custom)this.events.custom = useCustomEvent(this);
    this.events.custom.emit(event_name,detail);
    return this;
  }
  watchAttr(callback){
    if(!this.observer.attr)this.observer.attr = watchAttr(this,callback);
    return this;
  }
  watchChildren(callback){
    if(!this.observer.children)this.observer.children = watchChildren(this,callback);
    return this;
  }
  watchSize(callback){
    if(!this.observer.resize)this.observer.resize = watchSize(this,callback);
    this.observer.resize.start();
    return this;
  }
  watchIntersection(callback,config){
    if(!this.observer.intersection)this.observer.intersection = watchIntersection(this,callback,config);
    this.observer.intersection.start();
    return this;
  }
  // setFullScreen(set = true, e) {
  //   if(!this.element.requestFullscreen){
  //     console.error("Fullscreen API is not supported in this browser.");
  //     return this;
  //   }
  //   if (set) this.element.requestFullscreen(e);
  //   else globalThis.document.exitFullscreen();
  //   return this;
  // }
  // toggleFullScreen(e) {
  //   if (!globalThis.document.fullscreenElement) this.element.requestFullscreen(e);
  //   else globalThis.document.exitFullscreen();
  //   return this;
  // }
}

class __ZikoUIText__ extends ZikoUIElement {
    constructor(tag, name, lineBreak,...value) {
      super(tag, name);
      this.addValue(...value);
      this.style({margin:0,padding:0});
      Object.assign(this.cache,{
        lineBreak,
      });
    }
    get isText(){
      return true;
    }
    get value(){
      return this.element.textContent;
    }
    clear() {
      this.element.childNodes.forEach((e) => e.remove());
      this.element.textContent = "";
      return this;
    }
    addValue(...value) {
      value.forEach((item,i) => {
        if (typeof item === "string" || typeof item === "number") this.element?.appendChild(globalThis?.document.createTextNode(item));
        else if (item instanceof ZikoUIElement) this.element?.appendChild(item.element);
        else if (item instanceof Complex || item instanceof Matrix) this.element?.appendChild(new Text(item.toString()));
        else if (item instanceof Array) this.element?.appendChild(new Text(arr2str(item)));
        else if (item instanceof Object) this.element?.appendChild(new Text(obj2str(item)));
        
        // if(
        //   (item !== value[value.length - 1]) 
        //   && !(value[i+1] instanceof ZikoUIElement)
        //   && !(value[i-1] instanceof ZikoUIElement)
        // ) this.element?.appendChild(new Text(" "))
        
        if(this.cache.lineBreak)this.element?.appendChild(globalThis.document?.createElement("br"));
      });
      // if(this.element?.innerHTML){
      //   this.element.innerHTML = this.element.innerHTML.replace(/\n/g, '<br>').replace(/(?<!<[^>]+) /g, '&nbsp;');
      // }
      return this
    }
    setValue(...value) {
      this.clear();
      this.addValue(...value);
      return this;
    }
  }

class ZikoUIText extends __ZikoUIText__ {
    constructor(...value) {
      super("span", "text", false, ...value);
    }
}
class ZikoUIQuote extends __ZikoUIText__ {
  constructor(...value) {
    super("q", "quote", false, ...value);
    this.style({
      fontStyle: "italic"
    });
  }
  get isQuote(){
    return true
  }
}
class ZikoUIDefintion extends __ZikoUIText__ {
  constructor(...value) {
    super("dfn", "dfnText", false, ...value);
  }
  get isDfnText(){
    return true
  }
}
class ZikoUISupText extends __ZikoUIText__ {
  constructor(sup) {
    super("sup", "supText", false, sup);
  }
  get isSupText(){
    return true
  }
}
class ZikoUISubText extends __ZikoUIText__ {
  constructor(...value) {
    super("sub", "subText", false, ...value);
  }
  get isSubText(){
    return true
  }
}
class ZikoUICodeText extends __ZikoUIText__ {
  constructor(...value) {
    super("code", "codeText", false, ...value);
  }
  get isCodeText(){
    return true
  }
}
class ZikoUIAbbrText extends __ZikoUIText__ {
  constructor(abbr, title) {
    super("abbr", "abbrText", false, abbr);
    this.setAttr("title", title);
  }
  get isAbbrText(){
    return true
  }
}
const text = (...str) => new ZikoUIText(...str);
const quote = (...str) => new ZikoUIQuote(...str);
const dfnText = (...str) => new ZikoUIDefintion(...str);
const supText = (...str) => new ZikoUISupText(...str);
const subText = (...str) => new ZikoUISubText(...str);
const codeText = (...str) => new ZikoUICodeText(...str);
const abbrText = (abbr, title) => new ZikoUIAbbrText(abbr, title);

class ZikoUIParagraphe extends __ZikoUIText__ {
    constructor(...value) {
      super("p", "p", true, ...value);
    }
    get isPara(){
      return true;
    }
}
class ZikoUIBlockQuote extends __ZikoUIText__ {
    constructor(cite,quote) {
      super("blockquote", "blockquote", true, quote);
      this.setAttr("cite", cite);
    }
    get isBlockQuote(){
      return true;
    }
}
const p = (...ZikoUIElement) => new ZikoUIParagraphe(...ZikoUIElement);
const blockQuote = (cite, quote) => new ZikoUIBlockQuote(cite, quote);

class ZikoUIHeading extends ZikoUIElement {
    constructor(type = 1, value = "") {
      super(`h${type}`,`h${type}`);
      this.element.textContent = value;
    }
    get isHeading(){
      return true;
    }
    get value() {
      return this.element.innerText;
    }
    setValue(text = "") {
      this.element.innerText = text;
      return;
    }
    addValue(text = "") {
      this.element.innerText += text;
      return this;
    }
  }
const h1=(text="")=>new ZikoUIHeading(1, text);
const h2=(text="")=>new ZikoUIHeading(2, text);
const h3=(text="")=>new ZikoUIHeading(3, text);
const h4=(text="")=>new ZikoUIHeading(4, text);
const h5=(text="")=>new ZikoUIHeading(5, text);
const h6=(text="")=>new ZikoUIHeading(6, text);

var Text$1 = /*#__PURE__*/Object.freeze({
  __proto__: null,
  ZikoUIAbbrText: ZikoUIAbbrText,
  ZikoUIBlockQuote: ZikoUIBlockQuote,
  ZikoUICodeText: ZikoUICodeText,
  ZikoUIDefintion: ZikoUIDefintion,
  ZikoUIHeading: ZikoUIHeading,
  ZikoUIParagraphe: ZikoUIParagraphe,
  ZikoUIQuote: ZikoUIQuote,
  ZikoUISubText: ZikoUISubText,
  ZikoUISupText: ZikoUISupText,
  ZikoUIText: ZikoUIText,
  abbrText: abbrText,
  blockQuote: blockQuote,
  codeText: codeText,
  dfnText: dfnText,
  h1: h1,
  h2: h2,
  h3: h3,
  h4: h4,
  h5: h5,
  h6: h6,
  p: p,
  quote: quote,
  subText: subText,
  supText: supText,
  text: text
});

class ZikoUILI extends ZikoUIElement{
  constructor(UI){
    super("li","li");
    this.append(UI);
  }
  get isLi(){
    return true;
  }
}
class ZikoUIList extends ZikoUIElement {
    constructor(element,name) {
      super(element,name);
      delete this.append;
      this.style({ listStylePosition: "inside" });
    }
    get isList(){
      return true;
    }
    append(...arr){
      for (let i = 0; i < arr.length; i++) {
        let li = null;
        if(["string","number"].includes(typeof arr[i]))arr[i]=text(arr[i]);
        if (arr[i] instanceof ZikoUIElement)li=new ZikoUILI(arr[i]);
        li.setTarget(this.element);
        this.items.push(li[0]);
        this.maintain();
      }
    }
    remove(...ele) {
      if(ele.length==0){
        if(this.target.children.length) this.target.removeChild(this.element);
      }
      else {
        const remove = (ele) => {
          if(typeof ele === "number") ele=this.items[ele];
          if(ele instanceof ZikoUIElement)this.element?.removeChild(ele.parent.element);
            this.items=this.items.filter(n=>n!==ele);
        };
        for (let i = 0; i < ele.length; i++) remove(ele[i]);
        for (let i = 0; i < this.items.length; i++)
          Object.assign(this, { [[i]]: this.items[i] });
      }
      return this;
    }
    insertAt(index, ...ele) {
      if (index >= this.element.children.length) this.append(...ele);
      else
        for (let i = 0; i < ele.length; i++) {
          let li = null;
          if(["number","string"].includes(typeof ele[i]))ele[i]=text(ele[i]);
          if (ele[i] instanceof ZikoUIElement)li=new ZikoUILI(ele[i]);
          this.element?.insertBefore(li.element, this.items[index].parent.element);
          this.items.splice(index, 0, ele[i][0]);
        }
      return this;
    }
    filterByTextContent(text,exactMatch=false){
      this.items.map(n=>n.parent.render());
      this.items.filter(n=>{
        const content=n.element.textContent;
        return !(exactMatch?content===text:content.includes(text))
      }).map(n=>n.parent.render(false));
       return this;
    }
    sortByTextContent(order=1){
      this.items.map(n=>n.parent.render(false));
      // To Fix
      this.sortedItems=this.items.sort((a,b)=>order*a.element.textContent.localeCompare(b.element.textContent));
      this.append(...this.sortedItems);
      return this;
    }
    filterByClass(value) {
      this.items.map(n=>n.parent.render(true));
      this.items.filter(n=>!n.Classes.includes(value)).map(n=>n.parent.render(false));
      return this; 
    }
    delete(value) {
      const valueIndex = [...this.element.children].indexOf(value);
      return valueIndex;
      /*if(valueIndex >= 0) {
        return this.list.splice(valueIndex, 1);
      }*/
    }
    push(){

    }
    pop(){

    }
    unshift(){

    }
    shift(){

    }
    sort(){

    }
    filter(){

    }
    slice(){
      
    }
  }
class ZikoUIOList extends ZikoUIList{
  constructor(...arr){
    super("ol","ol");
    this.append(...arr);
  }
  get isOl(){
    return true;
  }
  type(tp = 1) {
    this.element?.setAttribute("type", tp);
    return this;
  }
  start(st = 1) {
    this.element?.setAttribute("start", st);
    return this;
  }
}
class ZikoUIUList extends ZikoUIList{
  constructor(...arr){
    super("ul","ul");
    this.append(...arr);
  }
  get isUl(){
    return true;
  }
}
const li=UI=>new ZikoUILI(UI);
const ol = (...arr) => new ZikoUIOList(...arr);
const ul = (...arr) => new ZikoUIUList(...arr);

var List = /*#__PURE__*/Object.freeze({
  __proto__: null,
  li: li,
  ol: ol,
  ul: ul
});

class ZikoUIInput extends ZikoUIElement {
  constructor(type, name , value = "", datalist) {
    super("input", "input");
    Object.assign(this.events, { input: null });
    this.setValue(value);
    this.setAttr("type", type);
    this.setAttr("name", name);
    // this.setAttr("tab-index","0")
    if (datalist) this.linkDatalist(datalist);
  }
  get isInput() {
    return true;
  }
  setName(name){
    this.setAttr("name", name);
    return this;
  }
  onInput(...callbacks) {
    if (!this.events.input) this.events.input = useInputEvent(this);
    this.events.input.onInput(...callbacks);
    return this;
  }
  onChange(...callbacks) {
    if (!this.events.input) this.events.input = useInputEvent(this);
    this.events.input.onChange(...callbacks);
    return this;
  }
  linkDatalist(datalist) {
    let id;
    if (datalist instanceof ZikoUIInputDatalist) id = datalist.Id;
    else if (datalist instanceof Array) {
      const Datalist = new ZikoUIInputDatalist(...datalist);
      id = Datalist.Id;
      console.log(Datalist);
    } else id = datalist;
    this.element?.setAttribute("list", id);
    return this;
  }
  get value() {
    return this.element.value;
  }
  // _setType(type) {
  //   this.element.type = type;
  //   return this;
  // }
  setValue(value = "") {
    this.element.value = value;
    return this;
  }
  useState(state) {
    this.setValue(state);
    return [{ value: this.value }, (e) => this.setValue(e)];
  }
  setPlaceholder(value) {
    if (value) this.element.placeholder = value;
    return this;
  }
  get isValide() {
    return this.element.checkValidity();
  }
  setRequired(required = true) {
    this.element.required = required;
    return this;
  }
  select() {
    this.element.select();
    return this;
  }
  copy() {
    this.element.select();
    document.execCommand("copy");
    return this;
  }
  cut() {
    this.element.select();
    document.execCommand("cut");
    return this;
  }
  accept(value) {
    this.element.accept = value;
    return this;
  }
}

const input = (value, datalist) => {
  if (value instanceof Object) {
    const { datalist, placeholder } = value;
    value = value.value ?? "";
    return new ZikoUIInput("text", "input", value, datalist).setPlaceholder(placeholder);
  }
  return new ZikoUIInput("text", "input", value, datalist);
};

class ZikoUIInputNumber extends ZikoUIInput {
    constructor(min, max, step = 1) {
      super("number", "inpuNumber");
      this.setMin(min).setMax(max).setStep(step);
    }
    get isInputNumber() {
      return true;
    }
    get value() {
      return +this.element.value;
    }
    setMin(min) {
      this.element.min = min;
      return this;
    }
    setMax(max) {
      this.element.max = max;
      return this;
    }
    setStep(step) {
      this.element.step = step;
      return this;
    }
  }
  const inputNumber = (min, max, step) => {
    if (min instanceof Object) {
      const { value, max = 10, step = 1, placeholder = "" } = min;
      min = min?.min ?? 0;
      return new ZikoUIInputSlider(min, max, step)
        .setValue(value)
        .setPlaceholder(placeholder);
    }
    return new ZikoUIInputNumber(min, max, step);
  };

let ZikoUIInputSlider$1 = class ZikoUIInputSlider extends ZikoUIInput {
    constructor(val = 0, min = 0, max = 10, step = 1) {
      super("range", "inputSlider");
      this.setMin(min).setMax(max).setValue(val).setStep(step);
    }
    get isInputSlider(){
      return true;
    }
    setMin(min) {
      this.element.min = min;
      return this;
    }
    setMax(max) {
      this.element.max = max;
      return this;
    }
    setStep(step) {
      this.element.step = step;
      return this;
    }
};
const slider = (value, min, max, step) =>{
    if(value instanceof Object){
      const {min=0,max=10,step=1}=value;
      value=value?.value??5;
      return new ZikoUIInputSlider$1(value, min, max, step);
    }
    return new ZikoUIInputSlider$1(value, min, max, step);
};

class ZikoUIInputColor extends ZikoUIInput {
    constructor() {
      super("color", "inputColor");
      this.background(this.value);
      this.onInput(() => this.background(this.value));
    }
    get isInputColor(){
      return true;
    }
}
const inputColor = () => new ZikoUIInputColor();

class ZikoUIInputSearch extends ZikoUIInput {
  constructor() {
    super("search", "inputSearch");
    this.Length = 0;
  }
  get isInputSearch() {
    return true;
  }
  onsearch(callback) {
    this.element?.addEventListener("search", () => callback());
    return this;
  }
  connect(...UIElement) {
    /* 
      let memory = new Array(UIElement.length).fill([]);
      UIElement.map((n, i) => {
        //console.log(n)
        n.items.map((m, j) => {
          memory[i][j] = m.element.style.display;
        });
      });
      UIElement.map((n, i) =>
        this.onInput(() => {
          n.filterByTextContent(this.value, memory[i]);
          this.Length = n.children.filter(
            (n) => n.style.display != "none"
          ).length;
        })
      );
      */
    return this;
  }
  displayLength(UIElement) {
    this.element?.addEventListener("keyup", () =>
      UIElement.setValue(this.Length),
    );
    return this;
  }
}
const search = (...a) => new ZikoUIInputSearch().connect(...a);

class ZikoUIInputCheckbox extends ZikoUIInput {
    constructor() {
      super("checkbox", "inputCheckbox");
      this.cursor("pointer");
    }
    get isInputCheckbox(){
      return true;
    }
    get checked() {
      return this.element.checked;
    }
    check(checked = true) {
      this.element.checked = checked;
      return this;
    }
    color(color) {
      this.element.style.accentColor = color;
      return this;
    }
}
const checkbox = () => new ZikoUIInputCheckbox();

class ZikoUIInputRadio extends ZikoUIInput {
    constructor() {
      super("radio", "inputRadio");
      this.cursor("pointer");
    }
    get isInputRadio(){
      return true;
    }
    get checked() {
      return this.element.checked;
    }
    check(checked = true) {
      this.element.checked = checked;
      return this;
    }
    color(color) {
      this.element.style.accentColor = color;
      return this;
    }
}
const radio = () => new ZikoUIInputRadio();

class ZikoUIInputEmail extends ZikoUIInput {
    constructor() {
      super("email", "inputEmail");
    }
    get isInputEmail(){
      return true;
    }
  }
const inputEmail = () => new ZikoUIInputEmail();

class ZikoUIInputPassword extends ZikoUIInput {
    constructor() {
      super("password", "inputPassword");
    }
    get isInputPassword(){
      return true;
    }
  }
  const inputPassword = () => new ZikoUIInputPassword();

class ZikoUIInputDate extends ZikoUIInput {
    constructor() {
      super("date", "inputDate");
    }
    get isInputDate(){
      return true;
    }
}
const inputDate = () => new ZikoUIInputDate();

class ZikoUIInputTime extends ZikoUIInput {
    constructor() {
      super("time", "inputTime");
    }
    get isInputTime(){
      return true;
    }
}
const inputTime = () => new ZikoUIInputTime();

class ZikoUIInputDateTime extends ZikoUIInput {
    constructor() {
      super("datetime-local", "inputDateTime");
    }
    get isInputDateTime(){
      return true;
    }
}
const inputDateTime = () => new ZikoUIInputDateTime();

class ZikoUIXMLWrapper extends ZikoUIElement{
    constructor(XMLContent, type){
        super("div", "");
        this.element.append(type==="svg"?svg2dom(XMLContent):html2dom(XMLContent));
    }
}
function html2dom(htmlString) {
    if(globalThis?.DOMParser){
        const parser = new DOMParser();
        const doc = parser.parseFromString(`<div>${htmlString}</div>`, 'text/html');
        doc.body.firstChild.style.display = "contents";
        return doc.body.firstChild;
    }
  }
function svg2dom(svgString) {
    if(globalThis?.DOMParser){
        const parser = new DOMParser();
        const doc = parser.parseFromString(svgString.replace(/\s+/g, ' ').trim(), 'image/svg+xml');
        return doc.documentElement; // SVG elements are usually at the root
    }
}
class ZikoUIHTMLWrapper extends ZikoUIXMLWrapper{
    constructor(HTMLContent){
        super(HTMLContent, "html");
    }
}
class ZikoUISVGWrapper extends ZikoUIXMLWrapper{
    constructor(SVGContent){
        super(SVGContent, "svg");
    }
}
const HTMLWrapper = (HTMLContent) => new ZikoUIHTMLWrapper(HTMLContent);
const SVGWrapper = (SVGContent) => new ZikoUISVGWrapper(SVGContent);

// function loadComponent() {
//     return new Promise((resolve) => {
//       setTimeout(() => {
//         resolve(p(1000))
//       }, 500);
//     });
//   }

//   Suspense(p("Loading ..."),()=>fetch('https://jsonplaceholder.typicode.com/todos/1')
//   .then(response => response.json())
//   .then(json => h2(json.title)))

 

class ZikoUISuspense extends ZikoUIElement{
    constructor(fallback_ui, callback){
        super("div", "suspense");
        this.setAttr({
            dataTemp : "suspense"
        });
        this.fallback_ui = fallback_ui;
        this.append(fallback_ui);
        (async ()=>{
            try{
                const ui = await callback();
                fallback_ui.unrender();
                this.append(ui);
                // console.log(content)
            }
            catch(error){
                console.log({error});
            }
        })();
    }
}

const Suspense = (fallback_ui, callback) => new ZikoUISuspense(fallback_ui, callback);

const _h=(tag, type, attributes, ...children)=>{
    const { name, style, ...attrs } = attributes;
    let element = new ZikoUIElement(tag, name, type);
    style && element.style(style);
    attrs && element.setAttr(attrs);
    children && element.append(...children);
    return element; 
};
const h=(tag, attributes = {}, ...children)=> _h(tag, "html", attributes, ...children);
const s=(tag, attributes = {}, ...children)=> _h(tag, "svg", attributes, ...children);

const HTMLTags$1 = [
  'a',
  'abb',
  'address',
  'area',
  'article',
  'aside',
  'audio',
  'b',
  'base',
  'bdi',
  'bdo',
  'blockquote',
  'br',
  'button',
  'canvas',
  'caption',
  'cite',
  'code',
  'col',
  'colgroup',
  'data',
  'datalist',
  'dd',
  'del',
  'details',
  'dfn',
  'dialog',
  'div',
  'dl',
  'dt',
  'em',
  'embed',
  'fieldset',
  'figcaption',
  'figure',
  'footer',
  'form',
  'h1',
  'h2',
  'h3',
  'h4',
  'h5',
  'h6',
  'header',
  'hgroup',
  'hr',
  'i',
  'iframe',
  'img',
  'ipnut',
  'ins',
  'kbd',
  'label',
  'legend',
  'li',
  'main',
  'map',
  'mark',
  'menu',
  'meter',
  'nav',
  'object',
  'ol',
  'optgroup',
  'option',
  'output',
  'p',
  'param',
  'picture',
  'pre',
  'progress',
  'q',
  'rp',
  'rt',
  'ruby',
  's',
  'samp',
  'search',
  'section',
  'select',
  'small',
  'source',
  'span',
  'strong',
  'sub',
  'summary',
  'sup',
  'svg',
  'table',
  'tbody',
  'td',
  'template',
  'textarea',
  'tfoot',
  'th',
  'thead',
  'time',
  'title',
  'tr',
  'track',
  'u',
  'ul',
  'var',
  'video',
  'wbr'
];

const SVGTags$1 = [
    "svg", "g", "defs", "symbol", "use", "image", "switch",
    "rect", "circle", "ellipse", "line", "polyline", "polygon", "path",
    "text", "tspan", "textPath", "altGlyph", "altGlyphDef", "altGlyphItem", "glyph", "glyphRef",
    "linearGradient", "radialGradient", "pattern", "solidColor",
    "filter", "feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix",
    "feDiffuseLighting", "feDisplacementMap", "feDropShadow", "feFlood", "feFuncA", "feFuncR", "feFuncG", "feFuncB",
    "feGaussianBlur", "feImage", "feMerge", "feMergeNode", "feMorphology", "feOffset", "feSpecularLighting",
    "feTile", "feTurbulence",
    "animate", "animateMotion", "animateTransform", "set",
    "script",
    "desc", "title", "metadata", "foreignObject"
  ];
  
const hTags = HTMLTags$1.reduce((acc, key) => {
  acc[key] = (attr, ...children) => h(key, attr, ...children);
  return acc;
}, {});
const sTags = SVGTags$1.reduce((acc, key) => {
    acc[key] = (attr, ...children) => h(key, attr, ...children);
    return acc;
  }, {});

class ZikoUIHtmlTag extends ZikoUIElement {
  constructor(element) {
    super(element,"html");
  }
}
class ZikoUIBtn extends ZikoUIElement {
  constructor(value = "button") {
    super("button","btn");
    this.setValue(value);
    this.st.cursor("pointer");
    globalThis.__Ziko__.__Config__.default.render && this.render();
  }
  get isBtn(){
    return true
  }
  setValue(value) {
    if (value instanceof ZikoUIElement) value.setTarget(this.element);
    else {
      this.element?.appendChild(document.createTextNode(""));
      this.element.childNodes[0].data = value;
    }
    return this;
  }
  get value() {
    return this.element.innerText;
  }
  toggleValues(...values) {
    values = values.map((n) => "" + n);
    let index = values.indexOf("" + this.value);
    if (index != -1 && index != values.length - 1)
      this.setValue(values[index + 1]);
    else this.setValue(values[0]);
    return this;
  }
}
class ZikoUIBr extends ZikoUIElement {
    constructor() {
      super("br","br");
    }
    get isBr(){
      return true
    }
  }
  class ZikoUIHr extends ZikoUIElement {
    constructor() {
      super("hr","hr");
      this.setAttr("role", "none");
    }
    get isHr(){
      return true
    }
  }
  class ZikoUILink extends ZikoUIElement{
    constructor(href){
      super("a","link");
      Object.assign(this.cache,{
        defaultStyle:{
          color:"#0275d8",
          textDecoration: "none"
        },
        hoverStyle:{
          color:"#01447e",
          textDecoration: "underline"
        },
      });
      this.setHref(href);
      this.style(this.cache.defaultStyle);
      this.onPtrEnter(()=>this.style(this.cache.hoverStyle));
      this.onPtrLeave(()=>this.style(this.cache.defaultStyle));
    }
    setHref(href){
      this.element.href=href;
    }
    get isLink(){
      return true
    }
  }
  const br = () => new ZikoUIBr();
  const hr = () => new ZikoUIHr();
  const brs = (n=1)=> new Array(n).fill(new ZikoUIBr());
  const hrs = (n=1)=> new Array(n).fill(new ZikoUIHr());
  const link=(href,...UIElement)=>new ZikoUILink(href).append(...UIElement);
  const html=(tag,...UIElement)=>new ZikoUIHtmlTag(tag).append(...UIElement);
  const btn = (value) => new ZikoUIBtn(value);

var Misc = /*#__PURE__*/Object.freeze({
  __proto__: null,
  HTMLWrapper: HTMLWrapper,
  SVGWrapper: SVGWrapper,
  Suspense: Suspense,
  ZikoUIBr: ZikoUIBr,
  ZikoUIHTMLWrapper: ZikoUIHTMLWrapper,
  ZikoUIHr: ZikoUIHr,
  ZikoUIHtmlTag: ZikoUIHtmlTag,
  ZikoUILink: ZikoUILink,
  ZikoUISVGWrapper: ZikoUISVGWrapper,
  ZikoUISuspense: ZikoUISuspense,
  ZikoUIXMLWrapper: ZikoUIXMLWrapper,
  br: br,
  brs: brs,
  btn: btn,
  h: h,
  hTags: hTags,
  hr: hr,
  hrs: hrs,
  html: html,
  link: link,
  s: s,
  sTags: sTags
});

class ZikoUIInputImage extends ZikoUIElement {
    constructor(text = "File") {
      super("inputImage");
      this._aux_element = btn(text).setTarget(this.target);
      this.element = document?.createElement("input");
      this.element?.setAttribute("type", "file");
      this.element?.setAttribute("accept", "image");
      this._aux_element.onClick(() => this.element.click());
      this.element.onChange = this.handleImage.bind(this);
    }
    get isInputImage(){
      return true;
    }
    handleImage(e) {
      const reader = new FileReader();
      const img = new Image();
      reader.onload = function (event) {
        img.src = event.target.result;
        console.log(img.src);
      };
      reader.readAsDataURL(e.target.files[0]);
      this.img = img;
    }
    get value() {
      return this.img;
    }
    render(bool = true) {
      if (bool) this.target.appendChild(this._aux_element.element);
      else this.remove();
      return this;
    }
    remove() {
      if (this.target.children.length) this.target.removeChild(this._aux_element.element);
      return this;
    }
}
const inputImage = (text) => new ZikoUIInputImage(text);

class ZikoUIImage extends ZikoUIElement {
    constructor(src,alt, w, h) {
      super("img","image");
      this.value=src;
      if (src.nodeName === "IMG")this.element.setAttribute("src", src.src);
      else this.element?.setAttribute("src", src);
      if (typeof w == "number") w += "%";
      if (typeof h == "number") h += "%";
      this.setAttr("alt", alt);
      this.style({ border: "1px solid black", width: w, height: h });
    }
    get isImg(){
      return true;
    }
     updateSrc(url){
      this.value=url;
      this.element.src=url;
     return this;
    }
    toggleSrc(...values){
      values=values.map(n=>""+n);
      let index=values.indexOf(""+this.value);
      if(index!=-1&&index!=(values.length-1))this.updateSrc(values[index+1]);
      else this.updateSrc(values[0]);
      return this;
    }
    alt(alt){
      this.element.alt=alt;
      return this;
    }
  }
const image = (src,alt, width, height) => new ZikoUIImage(src,alt, width, height);

class ZikoUIFigure extends ZikoUIElement{
    constructor(src,caption){
      super("figure","figure");
      this.img=src.width("100%").element;
      this.caption=document?.createElement("figcaption");
      this.caption.append(caption.element);
      this.element?.append(this.img);
      this.element?.append(this.caption);
    }
    get isFigure(){
      return true;
    }
}
const figure =(image,caption) =>new ZikoUIFigure(image,caption);

class __ZikoUIDynamicMediaElement__ extends ZikoUIElement {
    constructor(element, name) {
      super(element, name);
      this.useControls();
    }
    get t(){
      return this.element.currentTime;  
    }
    useControls(enabled = true) {
      this.element.controls = enabled;
      return this;
    }
    enableControls(){
      this.element.controls = true;
      return this;
    }
    disableControls(){
      this.element.controls = true;
      return this;
    }
    toggleControls(){
      this.element.controls = !this.element.controls;
      return this;
    }
    play() {
      this.element.play();
      return this;
    }
    pause() {
      this.element.pause();
      return this;
    }
    seekTo(time) {
      this.element.currentTime = time;
      return this;
    }
    onPlay(){

    }
    onPause(){

    }
  }

class ZikoUIVideo extends __ZikoUIDynamicMediaElement__ {
    constructor(src="", w = "100%", h = "50vh") {
      super("video","video");
      if (src.nodeName === "VIDEO") this.element?.setAttribute("src", src.src);
      else this.element?.setAttribute("src", src);
      if (typeof w == "number") w += "%";
      if (typeof h == "number") h += "%";
      this.style({ width: w, height: h });
    }
    get isVideo(){
      return true;
    }
    usePoster(src=""){
      this.element.poster=src;
      return this;
    }
    usePIP(e){
      this.element.requestPictureInPicture(e);
      return this;
    }
  }
const video = (src, width, height) => new ZikoUIVideo(src, width, height);

class ZikoUIAudio extends __ZikoUIDynamicMediaElement__ {
    constructor(src) {
      super("audio","audio");
      this.element?.setAttribute("src", src);
      this.size("150px","30px");
      // this.useControls();
    }
    get isAudio(){
      return true;
    }
  }
const audio = (src) => new ZikoUIAudio(src);

var Media = /*#__PURE__*/Object.freeze({
  __proto__: null,
  ZikoUIAudio: ZikoUIAudio,
  ZikoUIFigure: ZikoUIFigure,
  ZikoUIImage: ZikoUIImage,
  ZikoUIVideo: ZikoUIVideo,
  audio: audio,
  figure: figure,
  image: image,
  video: video
});

class ZikoUIWebcame extends ZikoUIVideo{
    constructor(){
      super();
      this.element?.setAttribute("src", "");
      this.constraints = { audio: true, video: { width: 1280, height: 720 } };
      //this.video=this.element
    }
    get isInputCamera(){
      return true;
    }
    start(){
      navigator.mediaDevices.getUserMedia(this.constraints).then((mediaStream)=>{
        this.element.srcObject = mediaStream;
        this.element.onloadedmetadata = () =>{
          this.element.play();
        };
      })
      .catch(function(err) { console.log(err.name + ": " + err.message); });
      return this;
    }
  }
  const inputCamera=()=>new ZikoUIWebcame();

class ZikoUILabel extends ZikoUIElement{
    constructor(){
      super();
      this.element=document?.createElement("label");
    }
    get isLabel(){
      return true;
  }
  }
class ZikoUIInputOption extends ZikoUIElement {
    constructor(value = "") {
      super();
      this.element = document?.createElement("option");
      if(value instanceof Object&&"value" in value){
        this.setValue(value.value);
        this.setText(value?.text??value.value);
      }
      else this.setValue(value);
    }
    setValue(str = "") {
      this.element.value = str;
      return this;
    }
    setText(text=""){
      if(text)this.element.textContent=text;
      return this;
    }
}
let ZikoUIInputDatalist$1 = class ZikoUIInputDatalist extends ZikoUIElement {
  constructor(...options){
    super();
    this.element = document?.createElement("datalist");
    this.addOptions(...options).setId("ziko-datalist-id"+Random.string(10));
  }
  get isDatalist(){
    return true;
  }
  addOptions(...options) {
    options.map((n) => this.append(new ZikoUIInputOption(n)));
    return this;
  }
};

const datalist = (...options) => new ZikoUIInputDatalist$1(...options);

class ZikoUISelect extends ZikoUIElement {
    constructor(){
      super();
      this.element=document?.createElement("select");
    }
    addOptions(...options) {
      options.map(n => this.append(new ZikoUIInputOption(n)));
      return this;
    }
    get isSelect(){
      return true;
    }
  }
const select=()=>new ZikoUISelect();

class ZikoUITextArea extends ZikoUIElement {
    constructor() {
      super();
      this.element = document?.createElement("textarea");
    }
    get value(){
      return this.element.textContent;
    }
    get isTextArea(){
      return true;
    }
}
const textarea =()=> new ZikoUITextArea();

class ZikoUIFlex extends ZikoUIElement {
  constructor(tag = "div", w = "100%", h = "100%") {
    super(tag ,"Flex");
    this.direction = "cols";
    if (typeof w == "number") w += "%";
    if (typeof h == "number") h += "%";
    this.style({ width: w, height: h });
    this.style({ display: "flex" });
    // this.render();
  }
  get isFlex(){
    return true;
  }
  resp(px,wrap = true) {
    this.wrap(wrap);
    if (this.element.clientWidth < px) this.vertical();
    else this.horizontal();
    return this;
  }
  setSpaceAround() {
    this.style({ justifyContent: "space-around" });
    return this;
  }
  setSpaceBetween() {
    this.style({ justifyContent: "space-between" });
    return this;
  }
  setBaseline() {
    this.style({ alignItems: "baseline" });
    return this;
  }
  gap(g) {
    if (this.direction === "row") this.style({ columnGap: g });
    else if (this.direction === "column") this.style({ rowGap: g });
    return this;
  }
  wrap(value = "wrap") {
    const values = ["no-wrap", "wrap","wrap-reverse"];
    this.style({
      flexWrap: typeof value === "string" ? value : values[+value],
    });
    return this;
  }
  _justifyContent(align = "center") {
    this.style({ justifyContent: align });
    return this;
  }
  vertical(x, y, order=1) {
    set_vertical.call(this,order);
    this.style({
      alignItems: typeof(x)==="number"?map_pos_x.call(this,x):x,
      justifyContent: typeof(y)=="number"?map_pos_y.call(this,y):y
    });
    return this;
  }
  horizontal(x, y, order=1) {
    set_horizontal.call(this,order);
    this.style({
      alignItems: typeof(y)=="number"?map_pos_y.call(this,y):y,
      justifyContent: typeof(x)==="number"?map_pos_x.call(this,x):x
    });
    return this;
  }
  show() {
    this.isHidden = false;
    this.style({ display: "flex" });
    return this;
  }
}

const Flex = (...ZikoUIElement) =>{
  let tag="div";
  if(typeof ZikoUIElement[0]==="string"){
    tag=ZikoUIElement[0];
    ZikoUIElement.pop();
  }
  return new ZikoUIFlex(tag).append(...ZikoUIElement);
};
function set_vertical(direction){
  direction == 1
    ? this.style({ flexDirection: "column" })
    : direction == -1 && this.style({ flexDirection: "column-reverse" });
  return this;
}
function set_horizontal(direction){
direction == 1
    ? this.style({ flexDirection: "row" })
    : direction == -1 && this.style({ flexDirection: "row-reverse" });
  return this;
}
function map_pos_x(align){
let pos = ["flex-start", "center", "flex-end"];
if (typeof align === "number") align = pos[align + 1];
return align;
}
function map_pos_y(align){
return map_pos_x(-align);
}

var Flex$1 = /*#__PURE__*/Object.freeze({
  __proto__: null,
  Flex: Flex,
  ZikoUIFlex: ZikoUIFlex
});

class ZikoUIForm extends ZikoUIFlex{
    constructor(...items){
        super("form", "Form");
        this.append(...items);
        this.setMethod("POST");
        this.setAction("/");
    }
    setAction(action = "/"){
        this.setAttr("action", action);
        return this;
    }
    setMethod(method = "post"){
        this.setAttr("method", method);
        return this;
    }
    get data(){
        let formData = new FormData(this.element);
        this.items.forEach(n=>{
            if(n.isInput||n.isSelect||n.isTextarea)formData.append(n.element.name, n.value);
        });
        return formData;
    }
    sendFormData(){
        fetch(this.element.action, {
            method: this.element.method,
            body: this.data
          })
          .then(response => response.json())
          .then(data => console.log(data))
          .catch(error => console.error('Error:', error));
        return this;
    }
    getByName(name){
        return this.data.get(name);
    }
}
const Form = (...items) => new ZikoUIForm(...items);

var Io = /*#__PURE__*/Object.freeze({
  __proto__: null,
  Form: Form,
  ZikoUIForm: ZikoUIForm,
  ZikoUIInput: ZikoUIInput,
  ZikoUIInputCheckbox: ZikoUIInputCheckbox,
  ZikoUIInputColor: ZikoUIInputColor,
  ZikoUIInputDatalist: ZikoUIInputDatalist$1,
  ZikoUIInputDate: ZikoUIInputDate,
  ZikoUIInputDateTime: ZikoUIInputDateTime,
  ZikoUIInputEmail: ZikoUIInputEmail,
  ZikoUIInputImage: ZikoUIInputImage,
  ZikoUIInputNumber: ZikoUIInputNumber,
  ZikoUIInputOption: ZikoUIInputOption,
  ZikoUIInputPassword: ZikoUIInputPassword,
  ZikoUIInputRadio: ZikoUIInputRadio,
  ZikoUIInputSearch: ZikoUIInputSearch,
  ZikoUIInputSlider: ZikoUIInputSlider$1,
  ZikoUIInputTime: ZikoUIInputTime,
  ZikoUILabel: ZikoUILabel,
  ZikoUISelect: ZikoUISelect,
  ZikoUITextArea: ZikoUITextArea,
  checkbox: checkbox,
  datalist: datalist,
  input: input,
  inputCamera: inputCamera,
  inputColor: inputColor,
  inputDate: inputDate,
  inputDateTime: inputDateTime,
  inputEmail: inputEmail,
  inputImage: inputImage,
  inputNumber: inputNumber,
  inputPassword: inputPassword,
  inputTime: inputTime,
  radio: radio,
  search: search,
  select: select,
  slider: slider,
  textarea: textarea
});

class ZikoUITr extends ZikoUIElement{
    constructor(...ZikoUIElement){
        super();
        this.element=document?.createElement("Tr");
        this.append(...ZikoUIElement);
    }
}
class ZikoUITd extends ZikoUIElement{
    constructor(...ZikoUIElement){
        super();
        this.element=document?.createElement("Td");
        this.append(...ZikoUIElement);
    }
}
class ZikoUIThead extends ZikoUIElement{
    constructor(...ZikoUITr){
        super();
        this.element=document?.createElement("Thead");
        this.append(...ZikoUITr);
    }
}
class ZikoUITbody extends ZikoUIElement{
    constructor(...ZikoUITr){
        super();
        this.element=document?.createElement("Tbody");
        this.append(...ZikoUITr);
    }
}
class ZikoUICaption extends ZikoUIElement{
    constructor(ZikoUIElement){
        super();
        this.element=document?.createElement("Caption");
        this.append(ZikoUIElement);
    }
}

const tr=(...ZikoUIElement)=>new ZikoUITr(...ZikoUIElement);
const td=(...UI)=>{
    UI=UI.map(n=>{
        if(!(n instanceof ZikoUIElement))n=text(n);
        return n
    });
    return new ZikoUITd(...UI)
};
const thead=(...ZikoUITd)=>{
    ZikoUITd=ZikoUITd.map(n=>{
        if(!(n instanceof ZikoUIElement))n=td(n);
        return n
    });
    return new ZikoUIThead(...UI)
};
const tbody=(...ZikoUITr)=>new ZikoUITbody(...ZikoUITr);
const caption=(ZikoUITr)=>new ZikoUICaption(ZikoUITr);

const MatrixToTableUI=matrix=>{
    var Tr = new Array(matrix.rows).fill(null).map(() => tr());
    var Td = matrix.arr.map((n) => n.map(() => null));
    for (let i = 0; i < Td.length; i++) {
        for (let j = 0; j < Td[0].length; j++) {
            Td[i][j] = td(matrix.arr[i][j]);
            Tr[i].append(Td[i][j]);
        }
    }
    return Tr
};

class ZikoUITable extends ZikoUIElement {
    constructor(body,{caption=null,head=null,foot=null}={}){
        super("table","Table");
        this.structure={
            caption,
            head,
            body:null,
            foot
        };
        if(body)this.fromMatrix(body);
        if(caption)this.setCaption(caption);
    }
    get isTable(){
        return true;
      }
    get caption(){
        return this.structure.caption;
    }
    get header(){

    }
    get body(){

    }
    get footer(){

    }
    setCaption(c){
        this.removeCaption();
        this.structure.caption=caption(c);
        this.append(this.structure.caption);
        return this;
    }
    removeCaption(){
        if(this.structure.caption)this.removeItem(...this.items.filter(n=>n instanceof ZikoUICaption));
        this.structure.caption=null;
        return this;
    }
    setHeader(...c){
        this.tHead=thead(...c);
        this.append(this.tHead);
        return this;
    }
    removeHeader(){
        this.removeItem(...this.items.filter(n=>n instanceof ZikoUICaption));
        return this;
    }
    setFooter(c){
        this.structure.caption=caption(c);
        this.append(this.structure.caption);
        return this;
    }
    removeFooter(){
        this.removeItem(...this.items.filter(n=>n instanceof ZikoUICaption));
        return this;
    }
    fromMatrix(bodyMatrix) {
        (bodyMatrix instanceof Array)?this.bodyMatrix=matrix(bodyMatrix):this.bodyMatrix=bodyMatrix;
        if(this.structure.body)this.remove(this.structure.body);
        this.structure.body=tbody();
        this.append(this.structure.body);
        this.structure.body.append(...MatrixToTableUI(this.bodyMatrix));
        //this.structure.body.append(...MatrixToTableUI(matrix))
        //this.cellStyles({ padding: "0.2rem 0.4rem", textAlign: "center" });
        return this;
      }
    transpose() {
        this.fromMatrix(this.bodyMatrix.T);
        return this;
      }
    hstack(m) {
        if(m instanceof ZikoUITable)m=m.bodyMatrix;
        this.fromMatrix(this.bodyMatrix.clone.hstack(m));
        return this;
    }
    vstack(m) {
        if(m instanceof ZikoUITable)m=m.bodyMatrix;
        this.fromMatrix(this.bodyMatrix.clone.vstack(m));
        return this;
    }
    slice(r0=0,c0=0,r1=this.bodyMatrix.rows-1,c1=this.bodyMatrix.cols-1) {
        this.fromMatrix(this.bodyMatrix.slice(r0,c0,r1,c1));
        return this;
      }
    sortByCols(n, config = { type: "num", order: "asc" }) {
        this.fromMatrix(this.bodyMatrix.clone.sortTable(n, config));
        return this;
    }
    sortByRows(n, config = { type: "num", order: "asc" }) {
        this.fromMatrix(this.bodyMatrix.T.clone.sortTable(n, config).T);
        return this;
    }
    filterByRows(item) {
        this.fromMatrix(this.bodyMatrix.clone.filterByRows(item));
        return this;
    }
    filterByCols(item) {
        this.fromMatrix(this.bodyMatrix.clone.filterByCols(item));
        return this;
      }
    forEachRow(callback){
        this.structure.body.forEach(callback);
        return this;
    }
    forEachItem(callback){
        this.structure.body.forEach(n=>n.forEach(callback));
        return this;
    }
}
const Table$1=(matrix,config)=>new ZikoUITable(matrix,config);

var Table = /*#__PURE__*/Object.freeze({
  __proto__: null,
  Table: Table$1
});

const elements = ['Main', 'Header', 'Nav', 'Section', 'Article', 'Aside', 'Footer'];

// Storage for Classes and component functions
const Classes = {};
const Components = {};

// Auto-generate Classes and factory functions
for (let i=0; i<elements.length; i++) {
  Classes[`ZikoUI${elements[i]}`] = class extends ZikoUIElement {
    constructor() {
      super(elements[i].toLowerCase());
      this.style({ position: "relative" });
    }
    get [`is${elements[i]}`]() {
      return true;
    }
  };

  Components[elements[i]] = (...children) =>
    new Classes[`ZikoUI${elements[i]}`]().append(...children);
}

const {
  Main,
  Header,
  Nav,
  Section,
  Article,
  Aside,
  Footer
} = Components;

const {
  ZikoUIMain,
  ZikoUIHeader,
  ZikoUINav,
  ZikoUISection,
  ZikoUIArticle,
  ZikoUIAside,
  ZikoUIFooter
} = Classes;

var Semantic = /*#__PURE__*/Object.freeze({
  __proto__: null,
  Article: Article,
  Aside: Aside,
  Footer: Footer,
  Header: Header,
  Main: Main,
  Nav: Nav,
  Section: Section,
  ZikoUIArticle: ZikoUIArticle,
  ZikoUIAside: ZikoUIAside,
  ZikoUIFooter: ZikoUIFooter,
  ZikoUIHeader: ZikoUIHeader,
  ZikoUIMain: ZikoUIMain,
  ZikoUINav: ZikoUINav,
  ZikoUISection: ZikoUISection
});

class ZikoUIGrid extends ZikoUIElement {
    constructor(tag ="div", w = "50vw", h = "50vh") {
      super(tag,"Grid");
      this.direction = "cols";
      if (typeof w == "number") w += "%";
      if (typeof h == "number") h += "%";
      this.style({ border: "1px solid black", width: w, height: h });
      this.style({ display: "grid" });
    //   this.render();
    }
    get isGird(){
        return true;
      }
    columns(n) {
        let temp = "";
        for (let i = 0; i < n; i++) temp = temp.concat(" auto");
        this.#templateColumns(temp);
        return this;
    }
    #templateColumns(temp = "auto auto") {
        this.style({ gridTemplateColumns: temp });
        return this;
    }
    gap(w = 10, h = w) {
        if(typeof (w) === "number")w += "px";
        if(typeof (h) === "number")h += "px";
        this.style({gridColumnGap: w,gridRowGap: h});
        return this;
    }
}
const Grid$1 = (...ZikoUIElement) => new ZikoUIGrid("div").append(...ZikoUIElement);

var Grid$2 = /*#__PURE__*/Object.freeze({
  __proto__: null,
  Grid: Grid$1,
  ZikoUIGrid: ZikoUIGrid
});

const HTMLTags = [
  'a',
  'abb',
  'address',
  'area',
  'article',
  'aside',
  'audio',
  'b',
  'base',
  'bdi',
  'bdo',
  'blockquote',
  'br',
  'button',
  'canvas',
  'caption',
  'cite',
  'code',
  'col',
  'colgroup',
  'data',
  'datalist',
  'dd',
  'del',
  'details',
  'dfn',
  'dialog',
  'div',
  'dl',
  'dt',
  'em',
  'embed',
  'fieldset',
  'figcaption',
  'figure',
  'footer',
  'form',
  'h1',
  'h2',
  'h3',
  'h4',
  'h5',
  'h6',
  'header',
  'hgroup',
  'hr',
  'i',
  'iframe',
  'img',
  'ipnut',
  'ins',
  'kbd',
  'label',
  'legend',
  'li',
  'main',
  'map',
  'mark',
  'menu',
  'meter',
  'nav',
  'object',
  'ol',
  'optgroup',
  'option',
  'output',
  'p',
  'param',
  'picture',
  'pre',
  'progress',
  'q',
  'rp',
  'rt',
  'ruby',
  's',
  'samp',
  'search',
  'section',
  'select',
  'small',
  'source',
  'span',
  'strong',
  'sub',
  'summary',
  'sup',
  'svg',
  'table',
  'tbody',
  'td',
  'template',
  'textarea',
  'tfoot',
  'th',
  'thead',
  'time',
  'title',
  'tr',
  'track',
  'u',
  'ul',
  'var',
  'video',
  'wbr'
];

const SVGTags = [
    "svg", "g", "defs", "symbol", "use", "image", "switch",
    "rect", "circle", "ellipse", "line", "polyline", "polygon", "path",
    "text", "tspan", "textPath", "altGlyph", "altGlyphDef", "altGlyphItem", "glyph", "glyphRef",
    "linearGradient", "radialGradient", "pattern", "solidColor",
    "filter", "feBlend", "feColorMatrix", "feComponentTransfer", "feComposite", "feConvolveMatrix",
    "feDiffuseLighting", "feDisplacementMap", "feDropShadow", "feFlood", "feFuncA", "feFuncR", "feFuncG", "feFuncB",
    "feGaussianBlur", "feImage", "feMerge", "feMergeNode", "feMorphology", "feOffset", "feSpecularLighting",
    "feTile", "feTurbulence",
    "animate", "animateMotion", "animateTransform", "set",
    "script",
    "desc", "title", "metadata", "foreignObject"
  ];

const tags = new Proxy({}, {
  get(target, prop) {
    if (typeof prop !== 'string') return undefined;
    let tag = prop.replaceAll("_","-").toLowerCase();
    if(HTMLTags.includes(tag)) return (...args)=>{
      if(!(args[0] instanceof ZikoUIElement) && args[0] instanceof Object){
        let attributes = args.shift();
        console.log(args);
        return new ZikoUIElement(tag).setAttr(attributes).append(...args)
      }
      return new ZikoUIElement(tag).append(...args);
    }
    if(SVGTags.includes(tag)) return (...args)=>new ZikoUIElement(tag,"",{el_type : "svg"}).append(...args);
    return (...args)=>{
      if(!(args[0] instanceof ZikoUIElement) && args[0] instanceof Object){
        let attributes = args.shift();
        return new ZikoUIElement(tag).setAttr(attributes).append(...args)
      }
      return new ZikoUIElement(tag).append(...args);
    }
    // switch(tag){
    //   case "html"  : globalThis?.document?.createElement("html")
    //   case "head"  :
    //   case "style" :
    //   case "link"  :
    //   case "meta"  :
    //   case "srcipt":
    //   case "body"  : return null; break;
    //   default : return new ZikoUIElement(tag);
    // }
  }
});

const UI$1 = {
    ...Text$1,
    ...List,
    ...Io,
    ...Media,
    ...Table,
    ...Semantic,
    ...Misc,
    ...Flex$1,
    ...Grid$2,
    ZikoUIElement,
};

const svg2str=svg=>(new XMLSerializer()).serializeToString(svg);
const svg2ascii=svg=>btoa(svg2str(svg));
const svg2imgUrl=svg=>'data:image/svg+xml;base64,'+svg2ascii(svg);
const svg2img=(svg,render=true)=>image(svg2imgUrl(svg)).render(render);

// const obj2str=(object)=>{
//     const recursiveToString = (obj) => {
//       if (Array.isArray(obj)) return arr2str(obj);
//       if (typeof obj === 'object' && obj !== null) {
//         return `{ ${Object.entries(obj)
//           .map(([key, value]) => `${key}:${recursiveToString(value)}`)
//           .join(" , ")} }`;
//       }
//       return String(obj); 
//     };
//     return recursiveToString(object);
//   };
//   const obj2str = (object) => {
//     const recursiveToString = (obj, indentLevel = 0) => {
//       const indent = '  '.repeat(indentLevel);
//       const nextIndent = '  '.repeat(indentLevel + 1);
//       if(Array.isArray(obj)) return arr2str(obj, indentLevel);
//       if(obj instanceof Complex || obj instanceof Matrix) return obj.toString();
//       if (typeof obj === 'object' && obj !== null) {
//         const entries = Object.entries(obj)
//           .map(([key, value]) => `${nextIndent}${key}: ${recursiveToString(value, indentLevel + 1)}`)
//           .join(",\n");
  
//         return `{\n${entries}\n${indent}}`;
//       }
  
//       return String(obj);
//     };
  
//     return recursiveToString(object);
//   };
// const obj2str = (object, useIndentation = true, indentLevel = 0) => {
//     const recursiveToString = (obj, level = 0) => {
//       const indent = useIndentation ? '  '.repeat(level) : '';
//       const nextIndent = useIndentation ? '  '.repeat(level + 1) : '';
//     if (Array.isArray(obj)) return arr2str(obj, false, level);
//     if(obj instanceof Complex || obj instanceof Matrix) return obj.toString();
//     if (typeof obj === 'object' && obj !== null) {
//         const entries = Object.entries(obj)
//           .map(([key, value]) => useIndentation 
//             ? `${nextIndent}${key}: ${recursiveToString(value, level + 1)}` 
//             : `${key}: ${recursiveToString(value, level + 1)}`
//           ).join(useIndentation ? ",\n" : ", ");
  
//         return useIndentation 
//           ? `{\n${entries}\n${indent}}` 
//           : `{${entries}}`;
//       }
  
//       return String(obj);
//     };
  
//     return recursiveToString(object, indentLevel);
//   };

const obj2str=(obj)=>JSON.stringify(
  mapfun$1(n=>{
    if(["number","string","boolean","bigint"].includes(typeof n)) return String(n);
    if(n instanceof Complex || n instanceof Matrix) return n.toString();
    if(n instanceof Array) return arr2str(n)
  },
  obj), null, "  ")
  .replace(/"([^"]+)":/g, '$1:') // Remove Quotes from Keys 
  .replace(/: "([^"]+)"/g, ': $1'); // Remove Quotes from str values

const getMaxDepth = arr=> {
  if (!Array.isArray(arr)) return 0;
  let maxDepth = 1;
  for (const element of arr) {
    if (Array.isArray(element)) {
      const depth = getMaxDepth(element);
      if (depth + 1 > maxDepth) {
        maxDepth = depth + 1;
      }
    }
  }
  return maxDepth;
};
const arr2str = (arr) => {
  let level = 0;
  function arrStringify(arr) {
    let max = getMaxDepth(arr);
    let useIdentation = 0;
    if (arr.some((n) => Array.isArray(n))) {
      level++;
      useIdentation = 1;   
    }
    return (
      "[" +
      arr.map((n, i) => {
        if (["number", "string", "boolean", "bigint"].includes(typeof n))
          return String(n);
        if (n instanceof Complex) return n.toString();
        if (n instanceof Array) {
          return `\n${"  ".repeat(level)}${arrStringify(n)}${i === arr.length - 1 ? "\n" : ""}`;
        }
        if( n instanceof Object) return obj2str(n);
      }) 
      + `${"  ".repeat((max+level+1) * useIdentation)}]` 
    );
  }
  return arrStringify(arr);
};

const json2css=(json, indentLevel = 0)=>{
    json = trimKeys(json);
    let cssText = '';
    const indent = '  '.repeat(indentLevel); 

    for (let selector in json) {
        if (typeof json[selector] === 'object') {
            cssText += `${indent}${selector} {\n`;
            const properties = json[selector];
            for (let property in properties) {
                if (typeof properties[property] === 'object') {
                    cssText += json2css({ [property]: properties[property] }, indentLevel + 1);
                } else {
                    cssText += `${indent}  ${property.replace(/[A-Z]/g, match => '-' + match.toLowerCase())}: ${properties[property]};\n`;
                }
            }

            cssText += `${indent}}\n`; 
        }
    }

    return cssText;
};
function trimKeys(obj) {
    if (typeof obj !== 'object' || obj === null) {
        return obj; 
    }

    return Object.keys(obj).reduce((acc, key) => {
        const trimmedKey = key.trim();
        acc[trimmedKey] = trimKeys(obj[key]);
        return acc;
    }, Array.isArray(obj) ? [] : {});
}

// export { markdown2html } from "./markdown.js";
// export { adoc2html } from "./adoc.js";

var Converter = /*#__PURE__*/Object.freeze({
  __proto__: null,
  arr2str: arr2str,
  csv2arr: csv2arr,
  csv2json: csv2json,
  csv2matrix: csv2matrix,
  csv2object: csv2object,
  csv2sql: csv2sql,
  json2arr: json2arr,
  json2css: json2css,
  json2csv: json2csv,
  json2csvFile: json2csvFile,
  json2xml: json2xml,
  json2xmlFile: json2xmlFile,
  json2yml: json2yml,
  json2ymlFile: json2ymlFile,
  obj2str: obj2str,
  svg2ascii: svg2ascii,
  svg2img: svg2img,
  svg2imgUrl: svg2imgUrl,
  svg2str: svg2str
});

var Parser = /*#__PURE__*/Object.freeze({
  __proto__: null
});

const Patterns={
    isDigit: /^\d+$/,
    isURL: /^(https?:\/\/)?([\w\-]+\.)+[\w\-]+(\/[\w\-./?%&=]*)?$/,
    isHexColor: /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/,
    isIPv4: /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/,
    isMACAddress: /^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$/,
    isDate: /^\d{4}-\d{2}-\d{2}$/,
};

class Str{
    constructor(string){
        this.string=string;
    }
    isDigit() {
        return Patterns.isDigit.test(this.string);
    }
    static isDigit(string){
        return new Str(string).isDigit();
    }
    isNumber() {
        return !isNaN(this.string);
    }
    static isNumber(string){
        return new Str(string).isNumber();
    }
    isUrl(){
        return Patterns.isURL.test(this.string);
    }
    static isUrl(string){
        return new Str(string).isUrl();
    }
    isHexColor(){
        return Patterns.isHexColor.test(this.string);
    }
    static isHexColor(string){
        return new Str(string).isHexColor();
    }
    isIPv4(){
        return Patterns.isIPv4.test(this.string);
    }
    static isIPv4(string){
        return new Str(string).isIPv4();
    }
    isDate(){
        return Patterns.isDate.test(this.string);
    }
    static isDate(string){
        return new Str(string).isDate();
    }
    isMACAddress(){
        return Patterns.isMACAddress.test(this.string);
    }
    static isMACAddress(string){
        return new Str(string).isMACAddress();
    }
    isPascalCase(){
        if (this.string.length === 0) return false;
        const PascalCasePattern = /^[A-Z][a-zA-Z0-9]*$/;
        return PascalCasePattern.test(this.string);
    }
    static isPascalCase(string){
        return new Str(string).isPascalCase();
    }
    isCamelCase() {
        if (this.string.length === 0) return false;        
        const camelCasePattern = /^[a-z][a-zA-Z0-9]*$/;
        return camelCasePattern.test(this.string);
    }
    static isCamelCase(string){
        return new Str(string).isCamelCase();
    }
    isHyphenCase(){
        return this.string.split('-').length > 1;
    }
    static isHyphenCase(string){
        return new Str(string).isHyphenCase();
    }
    isSnakeCase(){
        return this.string.split('_').length > 1;
    }
    static isSnakeCase(string){
        return new Str(string).isSnakeCase();
    }
    isPalindrome(){
        const str=this.string.toLocaleLowerCase();
        let l=str.length,i;
        for(i=0;i<l/2;i++)if(str[i]!=str[l-i-1])return false;
        return true;
    }
    static isPalindrome(string){
        return new Str(string).isPalindrome();
    }
    static isAnagrams(word,words){
        word=word.split("").sort();
        words=words.split("").sort();
        return JSON.stringify(word)===JSON.stringify(words);
    }
    isIsogram(){
        return [...new Set(this.string.toLowerCase())].length===this.string.length; 
    }
    static isIsogram(string){
       return  new Str(string).isIsogram();
    }
    static camel2hyphencase(text) {
        return text.replace(/[A-Z]/g, match => '-' + match.toLowerCase());
    }
    static camel2snakecase(text) {
        return text.replace(/[A-Z]/g, match => '_' + match.toLowerCase());
    }
    static camel2pascalcase(text) {
        return text.charAt(0).toUpperCase() + text.slice(1);
    }
    static camel2constantcase(text) {
        return text.replace(/[A-Z]/g, match => '_' + match).toUpperCase();
    }
    static pascal2snakecase(text) {
        return text.replace(/([A-Z])/g, (match, offset) => offset ? '_' + match.toLowerCase() : match.toLowerCase());
    }
    static pascal2hyphencase(text) {
        return text.replace(/([A-Z])/g, (match, offset) => offset ? '-' + match.toLowerCase() : match.toLowerCase());
    }
    static pascal2camelcase(text) {
        return text.charAt(0).toLowerCase() + text.slice(1);
    }
    static pascal2constantcase(text) {
        return text.replace(/([A-Z])/g, (match, offset) => offset ? '_' + match : match).toUpperCase();
    }
    static snake2camelcase(text) {
        return text.replace(/(_\w)/g, match => match[1].toUpperCase());
    }
    static snake2hyphencase(text) {
        return text.replace(/_/g, "-");
    }
    static snake2pascalcase(text) {
        return text.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join('');
    }
    static snake2constantcase(text) {
        return text.toUpperCase();
    }
    static hyphen2camelcase(text) {
        return text.replace(/-([a-z])/g, match => match[1].toUpperCase());
    }
    static hyphen2snakecase(text) {
        return text.replace(/-/g, '_');
    }
    static hyphen2pascalcase(text) {
        return text.split('-').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join('');
    }
    static hyphen2constantcase(text) {
        return text.replace(/-/g, '_').toUpperCase();
    }
    static constant2camelcase(text) {
        return text.toLowerCase().replace(/_([a-z])/g, match => match[1].toUpperCase());
    }
    static constant2snakecase(text) {
        return text.toLowerCase();
    }
    static constant2pascalcase(text) {
        return text.toLowerCase().split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join('');
    }
    static constant2hyphencase(text) {
        return text.toLowerCase().replace(/_/g, '-');
    }
}
const removeExtraSpace=str=>str.replace(/\s+/g,' ');
const count=(str,value)=>str.split("").filter(x => x==value).length;
const countWords=(str,value)=>str.split(" ").filter(x => x==value).length;
const str=string=>new Str(string);

var String$1 = /*#__PURE__*/Object.freeze({
  __proto__: null,
  Str: Str,
  count: count,
  countWords: countWords,
  removeExtraSpace: removeExtraSpace,
  str: str
});

const Data = {
    ...Api,
    ...Converter,
    ...Parser,
    ...String$1
};

class Matrix extends ZikoMath{
    constructor(rows, cols, element = [] ) {
        super();
        if(rows instanceof Matrix){
            this.arr=rows.arr;
            this.rows=rows.rows;
            this.cols=rows.cols;
        }
        else {
        let arr = [],
            i,
            j;
        if (arguments[0] instanceof Array) {
            rows = arguments[0].length;
            cols = arguments[0][0].length;
            arr = arguments[0];
        } else {
            for (i = 0; i < rows; i++) {
                arr.push([]);
                arr[i].push(new Array(cols));
                for (j = 0; j < cols; j++) {
                    arr[i][j] = element[i * cols + j];
                    if (element[i * cols + j] == undefined) arr[i][j] = 0;
                }
            }
        }
        this.rows = rows;
        this.cols = cols;
        this.arr = arr;   
    }
    this.#maintain();
        //Object.seal(this);
    }
    toString(){
        return arr2str(this.arr);
    }
    at(i=0,j=undefined){
        if(i<0)i=this.rows+i;
        if(j==undefined) return this.arr[i];
        if(j<0)j=this.cols+j;
        return this.arr[i][j];
    }
    reshape(newRows, newCols) {
        let check = newRows * newCols === this.rows * this.cols;
        if (check) return new Matrix(newRows, newCols, this.arr.flat(1));
        else console.error("Err");
    }
    static eye(size) {
        let result = new Matrix(size, size);
        for (let i = 0; i < size; i++) for (let j = 0; j < size; j++) i === j ? (result.arr[i][j] = 1) : (result.arr[i][j] = 0);
        return result;
    }
    get clone() {
        return new Matrix(this.rows, this.cols, this.arr.flat(1));
    }
    get size() {
        return this.rows * this.cols;
    } 
    get shape() {
        return [this.rows, this.cols];
    }
    get reel() {
        return new Matrix(this.cols, this.rows, this.arr.flat(1).reel);
    }
    get imag() {
        return new Matrix(this.cols, this.rows, this.arr.flat(1).imag);
    }
    [Symbol.iterator]() {
      return this.arr[Symbol.iterator]();
    }
    #maintain() {
    for (let i = 0; i < this.arr.length; i++) {
        Object.defineProperty(this, i, {
        value: this.arr[i],
        writable: true,
        configurable: true,
        enumerable: false 
        });
        }
    }
    get(row = 0, col = 0) {
        if (col == -1) return this.arr[row];
        else if (row == -1) return this.arr.map((n) => n[col]);
        else return this.arr[row][col];
    }
    set(row = 0, col = 0, value) {
        if (col == -1) return (this.arr[row] = value);
        else if (row == -1) {
            for (let i = 0; i < this.cols; i++) {
                this.arr[i][col] = value[i] || 0;
            }
            return this.arr;
        }
        return (this.arr[row][col] = value);
    }
    get isSquare() {
        return this.rows / this.cols === 1;
    }
    get isSym() {
        if (!this.isSquare) return false;
        const T = this.T;
        const M = this.clone;
        return Matrix.sub(M, T).max == 0 && Matrix.sub(M, T).min == 0;
    }
    get isAntiSym() {
        if (!this.isSquare) return false;
        const T = this.T;
        const M = this.clone;
        return Matrix.add(M, T).max == 0 && Matrix.add(M, T).min == 0;
    }
    get isDiag() {
        if (!this.isSquare) return false;
        const T = this.T;
        const M = this.clone;
        const MT = Matrix.mul(M, T);
        const TM = Matrix.dot(T, M);
        return Matrix.sub(MT, TM).max == 0 && Matrix.sub(MT, TM).min == 0;
    }
    get isOrtho() {
        if (!this.isSquare) return false;
        return this.isDiag && (this.det == 1 || this.det == -1);
    }
    get isIdemp() {
        if (!this.isSquare) return false;
        const M = this.clone;
        const MM = Matrix.dot(M, M);
        return Matrix.sub(MM, M).max == 0 && Matrix.sub(MM, M).min == 0;
    }
    get T() {
        let transpose = [];
        for (let i = 0; i < this.arr[0].length; i++) {
            transpose[i] = [];
            for (let j = 0; j < this.arr.length; j++) {
                transpose[i][j] = this.arr[j][i];
            }
        }
        return new Matrix(this.cols, this.rows, transpose.flat(1));
    }
    get det() {
        if (!this.isSquare) return new Error("is not square matrix");
        if (this.rows == 1) return this.arr[0][0];
        function determinat(M) {
            if (M.length == 2) {
                if (M.flat(1).some((n) => n instanceof Matrix)) {
                    console.warn("Tensors are not completely supported yet ...");
                    return;
                }
                return Utils$1.sub(Utils$1.mul(M[0][0],M[1][1]),Utils$1.mul(M[0][1],M[1][0]))
            }
            var answer = 0;
            for (var i = 0; i < M.length; i++) {
                //console.log(M[0][i]);
                /*answer = answer.add(
                    pow(-1, i)
                        .mul(M[0][i])
                        .mul(determinat(deleteRowAndColumn(M, i)))
                );*/
                //const to_be_added=Utils.add(Utils.mul(pow(-1, i),Utils.mul(M[0][i],determinat(deleteRowAndColumn(M, i)))));
                const to_be_added=Utils$1.add(Utils$1.mul(pow(-1, i),Utils$1.mul(M[0][i],determinat(deleteRowAndColumn(M, i)))));
                answer=Utils$1.add(answer,to_be_added);
            }
            return answer;
        }
        function deleteRowAndColumn(M, index) {
            var temp = [];
            for (let i = 0; i < M.length; i++) temp.push(M[i].slice(0));
            temp.splice(0, 1);
            for (let i = 0; i < temp.length; i++) temp[i].splice(index, 1);
            return temp;
        }
        return determinat(this.arr);
    }
    get inv() {
        if (!this.isSquare) return new Error("is not square matrix");
        if (this.det === 0) return "determinat = 0 !!!";
        let A = InverseMatrixe(this.arr);
        return new Matrix(this.rows, this.cols, A.flat(1));
    }
    static zeros(rows, cols) {
        let result = new Matrix(rows, cols);
        for (let i = 0; i < rows; i++) for (var j = 0; j < cols; j++) result.arr[i][j] = 0;
        return result;
    }
    static ones(rows, cols) {
        let result = new Matrix(rows, cols);
        for (let i = 0; i < rows; i++) for (let j = 0; j < cols; j++) result.arr[i][j] = 1;
        return result;
    }
    static nums(rows, cols, number) {
        let result = new Matrix(rows, cols);
        for (let i = 0; i < rows; i++) for (let j = 0; j < cols; j++) result.arr[i][j] = number;
        return result;
    }
    static get rand(){
        return {
            int:(rows, cols, a, b)=>{
                let result = new Matrix(rows, cols);
                for (let i = 0; i < rows; i++) for (let j = 0; j < cols; j++) result.arr[i][j] = Random.randInt(a, b);
                return result;
            },
            bin:(rows,cols)=>{
                let result = new Matrix(rows, cols);
                for (let i = 0; i < rows; i++) {
                    for (let j = 0; j < cols; j++) result.arr[i][j] = Random.randBin;
                }
                return result;       
            },
            hex:(rows,cols)=>{
                let result = new Matrix(rows, cols);
                for (let i = 0; i < rows; i++) {
                    for (let j = 0; j < cols; j++) result.arr[i][j] = Random.randHex;
                }
                return result;       
            },
            choices:(rows, cols, choices, p)=>{
                let result = new Matrix(rows, cols);
                for (let i = 0; i < rows; i++) for (let j = 0; j < cols; j++) result.arr[i][j] = Random.choice(choices, p);
                return result
            },
            permutation:(rows,cols,arr)=>{
                //return new Matrix(rows, cols, Random.permutation(...arr))
            }
        }
    }
    static rands(rows, cols, a = 1, b) {
        let result = new Matrix(rows, cols);
        for (let i = 0; i < rows; i++) for (let j = 0; j < cols; j++) result.arr[i][j] = Random.rand(a, b);
        return result;
    }
    map(Imin, Imax, Fmin, Fmax) {
        return Utils$1.map(this, Imin, Imax, Fmin, Fmax);
    }
    lerp(min, max) {
        return Utils$1.lerp(this, min, max);
    }
    norm(min, max) {
        return Utils$1.norm(this, min, max);
    }
    clamp(min, max) {
        return Utils$1.clamp(this, min, max);
    }
    static map(matrix, Imin, Imax, Fmin, Fmax) {
        return Utils$1.map(matrix, Imin, Imax, Fmin, Fmax);
    }
    static lerp(matrix, min, max) {
        return Utils$1.lerp(matrix, min, max);
    }
    static norm(matrix, min, max) {
        return Utils$1.norm(matrix, min, max);
    }
    static clamp(m, min, max) {
        return Utils$1.clamp(matrix, min, max);
    }
    toPrecision(p) {
        for (let i = 0; i < this.cols; i++) for (let j = 0; j < this.rows; j++) this.arr[i][j] = +this.arr[i][j].toPrecision(p);
        return this;
    }
    get toBin() {
        let newArr = this.arr.flat(1).toBin;
        return new Matrix(this.rows, this.cols, newArr);
    }
    get toOct() {
        let newArr = this.arr.flat(1).toOct;
        return new Matrix(this.rows, this.cols, newArr);
    }
    get toHex() {
        let newArr = this.arr.flat(1).toHex;
        return new Matrix(this.rows, this.cols, newArr);
    }
    /*get isOdd() {
        let newArr = this.arr.flat(1).isOdd;
        return new Matrix(this.rows, this.cols, newArr);
    }*/
    max2min() {
        let newArr = this.arr.flat(1).max2min;
        return new Matrix(this.rows, this.cols, newArr);
    }
    min2max() {
        let newArr = this.arr.flat(1).min2max;
        return new Matrix(this.rows, this.cols, newArr);
    }
    sortRows(calback=undefined){
        let newArr=this.arr.map(n=>n.sort(calback)).flat(1);
        return new Matrix(this.rows, this.cols, newArr);           
    }
    sortCols(calback=undefined){
        let m=this.T;
        let newArr=m.arr.map(n=>n.sort(calback)).flat(1);
        return new Matrix(this.rows, this.cols, newArr).T;           
    }
    filterByRows(item){
        var truth=this.arr.map(n=>n.map(m=>+(""+m).includes(item)));
        var mask=truth.map(n=>!!Logic.or(...n));
        var filtredArray=this.arr.filter((n,i)=>mask[i]===true);
        if(filtredArray.length===0)filtredArray.push([]);
        console.log(filtredArray);
        return new Matrix(filtredArray)
    }
    filterByCols(item){
        return new Matrix(this.T.arr.filter(n=>n.includes(item)))
    }
    sortAll(calback=undefined){
        let newArr=this.arr.flat(1).sort(calback);
        return new Matrix(this.rows, this.cols, newArr);         
    }
    count(n) {
        return this.arr.flat(1).count(n);
    }
    toBase(n) {
        let newArr = this.arr.flat(1).toBase(n);
        return new Matrix(this.rows, this.cols, newArr);
    }
    #hstack(matrix){
        if (this.rows !== matrix.rows) return;
        let newArr = this.arr;
        for (let i = 0; i < this.rows; i++) for (let j = this.cols; j < this.cols + matrix.cols; j++) newArr[i][j] = matrix.arr[i][j - this.cols];
        this.cols += matrix.cols;
        return new Matrix(this.rows, this.cols, newArr.flat(1));
    }
    hstack(...matrices) {
        const M=[this,...matrices].reduce((a,b)=>a.#hstack(b));
        Object.assign(this,M);
        return this;
    }
    static hstack(matrix,...matrices) {
        return matrix.clone.hstack(...matrices);
    }
    #vstack(matrix) {
        if (this.cols !== matrix.cols) return;
        let newArr = this.arr;
        for (let i = this.rows; i < this.rows + matrix.rows; i++) {
            newArr[i] = [];
            for (let j = 0; j < this.cols; j++) newArr[i][j] = matrix.arr[i - this.rows][j];
        }
        this.rows += matrix.rows;
        return new Matrix(this.rows, this.cols, newArr.flat(1));
    }
    vstack(...matrices) {
        const M=[this,...matrices].reduce((a,b)=>a.#vstack(b));
        Object.assign(this,M);
        return this;
    }
    static vstack(matrix,...matrices) {
        return matrix.clone.vstack(...matrices);
    }
    hqueue(...matrices){
        const M=[this,...matrices].reverse().reduce((a,b)=>a.#hstack(b));
        Object.assign(this,M);
        return this;
    }
    vqueue(...matrices){
        const M=[this,...matrices].reverse().reduce((a,b)=>a.#vstack(b));
        Object.assign(this,M);
        return this;
    }
    static hqueue(matrix,...matrices) {
        return matrix.clone.hqueue(...matrices);
    }
    static vqueue(matrix,...matrices) {
        return matrix.clone.vqueue(...matrices);
    }
    slice(r0=0, c0=0, r1=this.rows-1, c1=this.cols-1) {
        let newRow = r1 - r0,
            newCol = c1 - c0;
        let newArr = new Array(newCol);
        for (let i = 0; i < newRow; i++) {
            newArr[i] = [];
            for (let j = 0; j < newCol; j++) newArr[i][j] = this.arr[i + r0][j + c0];
        }
        return new Matrix(newRow, newCol, newArr.flat(1));
    }
    static slice(m1,r0=0, c0=0, r1=this.rows-1, c1=this.cols-1) {
        return m1.slice(r0, c0, r1, c1);
    }
    splice(r0,c0,deleteCount,...items){
        
    }
    getRows(ri, rf = ri + 1) {
        return this.slice(ri, 0, rf, this.cols);
    }
    getCols(ci, cf = ci + 1) {
        return this.slice(0, ci, this.rows, cf);
    }
    static getRows(m, ri, rf = ri + 1) {
        return m.slice(ri, 0, rf, m.cols);
    }
    static getCols(m, ci, cf = ci + 1) {
        return m.slice(0, ci, m.rows, cf);
    }
    add(...matr) {
        for (let k = 0; k < matr.length; k++) {
            if (typeof matr[k] == "number"||matr[k] instanceof Complex) matr[k] = Matrix.nums(this.rows, this.cols, matr[k]);
            for (let i = 0; i < this.rows; i++) for (var j = 0; j < this.cols; j++) this.arr[i][j] = Utils$1.add(this.arr[i][j],matr[k].arr[i][j]);
        }
        return new Matrix(this.rows, this.cols, this.arr.flat(1));
    }
    sub(...matr) {
        for (let k = 0; k < matr.length; k++) {
            if (typeof matr[k] == "number") matr[k] = Matrix.nums(this.rows, this.cols, matr[k]);
            for (let i = 0; i < this.rows; i++) for (var j = 0; j < this.cols; j++) this.arr[i][j] = Utils$1.sub(this.arr[i][j],matr[k].arr[i][j]);
        }
        return new Matrix(this.rows, this.cols, this.arr.flat(1));
    }
    static add(m1, ...m2) {
        return m1.clone.add(...m2);
    }
    static sub(m1, ...m2) {
        return m1.clone.sub(...m2);
    }
    mul(...matr) {
        for (let k = 0; k < matr.length; k++) {
            if (typeof matr[k] == "number") matr[k] = Matrix.nums(this.rows, this.cols, matr[k]);
            for (var i = 0; i < this.rows; i++) for (var j = 0; j < this.cols; j++) this.arr[i][j] = Utils$1.mul(this.arr[i][j],matr[k].arr[i][j]);
        }
        return new Matrix(this.rows, this.cols, this.arr.flat(1));
    }
    div(...matr) {
        for (let k = 0; k < matr.length; k++) {
            if (typeof matr[k] == "number") matr[k] = Matrix.nums(this.rows, this.cols, matr[k]);
            for (let i = 0; i < this.rows; i++) for (var j = 0; j < this.cols; j++) this.arr[i][j] = Utils$1.div(this.arr[i][j],matr[k].arr[i][j]);
        }
        return new Matrix(this.rows, this.cols, this.arr.flat(1));
    }
    static div(m1, ...m2) {
        return m1.clone.div(...m2);
    }
    static mul(m1, ...m2) {
        return m1.clone.mul(...m2);
    }
    modulo(...matr) {
        for (let k = 0; k < matr.length; k++) {
            if (typeof matr[k] == "number") matr[k] = Matrix.nums(this.rows, this.cols, matr[k]);
            for (let i = 0; i < this.rows; i++) for (var j = 0; j < this.cols; j++)this.arr[i][j]=Utils$1.modulo(this.arr[i][j],matr[k].arr[i][j]);
        }
        return new Matrix(this.rows, this.cols, this.arr.flat(1));
    }
    static modulo(m1, ...m2) {
        return m1.clone.modulo(...m2);
    }
    dot(matrix) {
        var res = [];
        for (var i = 0; i < this.arr.length; i++) {
            res[i] = [];
            for (var j = 0; j < matrix.arr[0].length; j++) {
                res[i][j] = 0;
                for (var k = 0; k < this.arr[0].length; k++) {
                    res[i][j] = Utils$1.add(
                        res[i][j],
                        Utils$1.mul(this.arr[i][k],matrix.arr[k][j])
                        );
                }
            }
        }
        return new Matrix(this.arr.length, matrix.arr[0].length, res.flat(1));
    }
    static dot(matrix1, matrix2) {
        return matrix1.dot(matrix2);
    }
    pow(n) {
        let a = this.clone,
            p = this.clone;
        for (let i = 0; i < n - 1; i++) p = p.dot(a);
        return p;
    }
    static pow(m, n) {
        return m.clone.pow(n);
    }
    get somme() {
        let S = 0;
        for (let i = 0; i < this.rows; i++) for (let j = 0; j < this.cols; j++) S += this.arr[i][j];
        return S;
    }
    get DoesItContainComplexNumbers() {
        return this.arr.flat(Infinity).some((n) => n instanceof Complex);
    }
    get min() {
        if (this.DoesItContainComplexNumbers) console.error("Complex numbers are not comparable");
        let minRow = [];
        for (let i = 0; i < this.rows; i++) minRow.push(min(...this.arr[i]));
        return min(...minRow);
    }
    get max() {
        if (this.DoesItContainComplexNumbers) console.error("Complex numbers are not comparable");
        let maxRow = [];
        for (let i = 0; i < this.rows; i++) maxRow.push(max(...this.arr[i]));
        return max(...maxRow);
    }
    get minRows() {
        if (this.DoesItContainComplexNumbers) console.error("Complex numbers are not comparable");
        let minRow = [];
        for (let i = 0; i < this.rows; i++) minRow.push(min(...this.arr[i]));
        return minRow;
    }
    get maxRows() {
        if (this.DoesItContainComplexNumbers) console.error("Complex numbers are not comparable");
        let maxRow = [];
        for (let i = 0; i < this.rows; i++) maxRow.push(max(...this.arr[i]));
        return maxRow;
    }
    get minCols() {
        if (this.DoesItContainComplexNumbers) console.error("Complex numbers are not comparable");
        return this.T.minRows;
    }
    get maxCols() {
        if (this.DoesItContainComplexNumbers) console.error("Complex numbers are not comparable");
        return this.T.maxRows;
    }
    static fromVector(v) {
        return new Matrix(v.length, 1, v);
    }
    get toArray() {
        let arr = [];
        for (let i = 0; i < this.rows; i++) {
            for (let j = 0; j < this.cols; j++) {
                arr.push(this.arr[i][j]);
            }
        }
        return arr;
    }
    get print() {
        //"pretty print" the matrix
        let fstring = "[";
        for (let i = 0; i < this.arr.length; i++) {
            fstring += (i != 0 ? " " : "") + ` [${this.arr[i].map((n) => " " + n.toString() + " ")}],\n`;
        }
        console.log(fstring.substring(0, fstring.length - 2) + " ]");
        document.write(fstring.substring(0, fstring.length - 2) + " ]");
    }
    get table() {
        console.table(this.arr);
    }
    get serialize() {
        return JSON.stringify(this);
    }
    static deserialize(data) {
        if (typeof data == "string") {
            data = JSON.parse(data);
        }
        let matrix = new Matrix(data.rows, data.cols);
        matrix.arr = data.arr;
        return matrix;
    }

    toTable() {
        var table = new DocumentFragment();
        var Tr = new Array(this.rows).fill(null).map(() => document?.createElement("tr"));
        var Td = this.arr.map((n) => n.map(() => document?.createElement("td")));
        for (let i = 0; i < Td.length; i++) {
            for (let j = 0; j < Td[0].length; j++) {
                Td[i][j].innerHTML = this.arr[i][j];
                Tr[i].appendChild(Td[i][j]);
            }
        }
        Tr.map((n) => table.appendChild(n));
        return table;
    }
    toGrid(element, style = {}) {
        let a = Grid();
        a.append(
            ...this.map(element)
                .arr.flat(1)
                .map((n) => n.style(style))
        );
        a.Columns(this.cols);
        return a;
    }
    sortTable(n=0,{type="num",order="asc"}={}) {
        var obj=this.T.arr.map(n=>n.map((n,i)=>Object.assign({},{x:n,y:i})));
        var newObj=this.T.arr.map(n=>n.map((n,i)=>Object.assign({},{x:n,y:i})));
        if(type==="num"){
            if(order==="asc")obj[n].sort((a,b)=>a.x-b.x);
            else if(order==="desc")obj[n].sort((a,b)=>b.x-a.x);
            else if(order==="toggle"){
               // console.log(obj[n][0])
                //console.log(obj[n][1])
                if(obj[n][0].x>obj[n][1].x)obj[n].sort((a,b)=>b.x-a.x);
                else obj[n].sort((a,b)=>a.x-b.x);
            }
        }
        else if(type==="alpha"){
            if(order==="asc")obj[n].sort((a,b)=>(""+a.x).localeCompare(""+b.x));
            else if(order==="desc")obj[n].sort((a,b)=>(""+b.x).localeCompare(""+a.x));            
        }
        //var order=obj[n].map(n=>n.y);
        order=obj[n].map(n=>n.y);
        for(let i=0;i<obj.length;i++){
            if(i!==n)obj[i].map((n,j)=>n.y=order[j]);
        }
        for(let i=0;i<obj.length;i++){
            if(i!==n)newObj[i].map((n,j)=>n.x=obj[i][order[j]].x);
        }
        newObj[n]=obj[n];
        var newArr=newObj.map(n=>n.map(m=>m.x));
        return new Matrix(newArr).T;
    }
}

function InverseMatrixe(M) {
    if (M.length !== M[0].length) {
        return;
    }
    var i = 0,
        ii = 0,
        j = 0,
        dim = M.length,
        e = 0;
        //t = 0;
    var I = [],
        C = [];
    for (i = 0; i < dim; i += 1) {
        I[I.length] = [];
        C[C.length] = [];
        for (j = 0; j < dim; j += 1) {
            if (i == j) {
                I[i][j] = 1;
            } else {
                I[i][j] = 0;
            }
            C[i][j] = M[i][j];
        }
    }
    for (i = 0; i < dim; i += 1) {
        e = C[i][i];
        if (e == 0) {
            for (ii = i + 1; ii < dim; ii += 1) {
                if (C[ii][i] != 0) {
                    for (j = 0; j < dim; j++) {
                        e = C[i][j];
                        C[i][j] = C[ii][j];
                        C[ii][j] = e;
                        e = I[i][j];
                        I[i][j] = I[ii][j];
                        I[ii][j] = e;
                    }
                    break;
                }
            }
            e = C[i][i];
            if (e == 0) {
                return;
            }
        }
        for (j = 0; j < dim; j++) {
            C[i][j] = C[i][j] / e;
            I[i][j] = I[i][j] / e;
        }
        for (ii = 0; ii < dim; ii++) {
            if (ii == i) {
                continue;
            }
            e = C[ii][i];
            for (j = 0; j < dim; j++) {
                C[ii][j] -= e * C[i][j];
                I[ii][j] -= e * I[i][j];
            }
        }
    }
    return I;
}
/**
* @returns {Matrix}
*/
const matrix=(r, c, element)=>new Matrix(r, c, element);
const matrix2=(...element)=>new Matrix(2, 2, element);
const matrix3=(...element)=>new Matrix(3, 3, element);
const matrix4=(...element)=>new Matrix(4, 4, element);

var __Matrix__ = /*#__PURE__*/Object.freeze({
  __proto__: null,
  Matrix: Matrix,
  matrix: matrix,
  matrix2: matrix2,
  matrix3: matrix3,
  matrix4: matrix4
});

class Complex extends ZikoMath{
    constructor(a = 0, b = 0) {
        super();
        if(a instanceof Complex){
            this.a=a.a;
            this.b=a.b;
        }
        else if(typeof(a)==="object"){
            if(("a" in b && "b" in a)){
                this.a=a.a;
                this.b=a.b;
            }
            else if(("a" in b && "z" in a)){
                this.a=a.a;
                this.b=sqrt((a.z**2)-(a.a**2));
            }
            else if(("a" in b && "phi" in a)){
                this.a=a.a;
                this.b=a.a*tan(a.phi);
            }
            else if(("b" in b && "z" in a)){
                this.b=a.b;
                this.a=sqrt((a.z**2)-(a.b**2));
            }
            else if(("b" in b && "phi" in a)){
                this.b=b;
                this.a=a.b/tan(a.phi);
            }
            else if(("z" in b && "phi" in a)){
                this.a=a.z*cos(a.phi);
                this.a=a.z*sin(a.phi);
            }
        }
        else if(typeof(a)==="number"&&typeof(b)==="number"){
            this.a = +a.toFixed(32);
            this.b = +b.toFixed(32);
        }
    }
    toString(){
        let str = "";
        if (this.a !== 0)
          this.b >= 0
            ? (str = `${this.a}+${this.b}*i`)
            : (str = `${this.a}-${Math.abs(this.b)}*i`);
        else
          this.b >= 0
            ? (str = `${this.b}*i`)
            : (str = `-${Math.abs(this.b)}*i`);
        return str;
    }
      
    get clone() {
        return new Complex(this.a, this.b);
    }
    get z(){
        return hypot(this.a,this.b);    
    }
    get phi(){
        return atan2(this.b , this.a);        
    }
    static Zero() {
        return new Complex(0, 0);
    }
    get conj() {
        return new Complex(this.a, -this.b);
    }
    get inv() {
        return new Complex(this.a / (pow(this.a, 2) + pow(this.b, 2)), -this.b / (pow(this.a, 2) + pow(this.b, 2)));
    }
    add(...z) {
        for (let i = 0; i < z.length; i++) {
            if (typeof z[i] === "number") z[i] = new Complex(z[i], 0);
        }
        let re = z.map((n) => n.a);
        let im = z.map((n) => n.b);
        this.a+=+sum(...re).toFixed(15);
        this.b+=+sum(...im).toFixed(15);
        return this;
    }
    sub(...z) {
        for (let i = 0; i < z.length; i++) {
            if (typeof z[i] === "number") z[i] = new Complex(z[i], 0);
        }
        let re = z.map((n) => n.a);
        let im = z.map((n) => n.b);
        this.a-=+sum(...re).toFixed(15);
        this.b-=+sum(...im).toFixed(15);
        return this;
    }
    mul(...z){
        for (let i = 0; i < z.length; i++) {
            if (typeof z[i] === "number") z[i] = new Complex(z[i], 0);
        }
        let Z=+prod(this.z,...z.map(n=>n.z)).toFixed(15);
        let phi=+sum(this.phi,...z.map(n=>n.phi)).toFixed(15);
        this.a=+(Z*cos(phi).toFixed(15)).toFixed(14);
        this.b=+(Z*sin(phi).toFixed(15)).toFixed(14);    
        return this;
    }
    div(...z) {
        for (let i = 0; i < z.length; i++) {
            if (typeof z[i] === "number") z[i] = new Complex(z[i], 0);
        }
        let Z=+(this.z/prod(...z.map(n=>n.z))).toFixed(15);
        let phi=+(this.phi-sum(...z.map(n=>n.phi))).toFixed(15);
        this.a=+(Z*cos(phi).toFixed(15)).toFixed(15);
        this.b=+(Z*sin(phi).toFixed(15)).toFixed(15);
        return this;
    }
    pow(n) {
        if (floor(n) === n && n > 0) {
            let z=+(this.z**n).toFixed(15);
            let phi=+(this.phi*n).toFixed(15);
            this.a=+(z*cos(phi).toFixed(15)).toFixed(15);
            this.b=+(z*sin(phi).toFixed(15)).toFixed(15);
        }
        return this;
    }
    static fromExpo(z, phi) {
        return new Complex(
            +(z * cos(phi)).toFixed(13), 
            +(z * sin(phi)).toFixed(13)
            );
    }
    get expo() {
        return [this.z, this.phi];
    }
    static add(c,...z) {
        return c.clone.add(...z);
    }
    static sub(c,...z) {
        return c.clone.sub(...z);
    }
    static mul(c,...z) {
        return c.clone.mul(...z);
    }
    static div(c,...z) {
        return c.clone.div(...z);
    }
    static pow(z,n){
        return z.clone.pow(n);
    }
    static xpowZ(x){
        return complex((x**this.a)*cos(this.b*ln(x)),(x**this.a)*sin(this.b*ln(x)));
    }
    sqrtn(n=2){
        return complex(sqrtn(this.z,n)*cos(this.phi/n),sqrtn(this.z,n)*sin(this.phi/n));
    }
    get sqrt(){
        return this.sqrtn(2);
    }
    get log(){
        return complex(this.z,this.phi);
    }
    get cos(){
        return complex(cos(this.a)*cosh(this.b),sin(this.a)*sinh(this.b))
    }
    get sin(){
        return complex(sin(this.a)*cosh(this.b),cos(this.a)*sinh(this.b))
    }
    get tan(){
        const de=cos(this.a*2)+cosh(this.b*2);
        return complex(sin(2*this.a)/de,sinh(2*this.b)/de);
    }
    printInConsole() {
        let string = this.a + " + " + this.b + " * i";
        console.log(string);
        return string;
    }
    print() {
        //return text(this.a + " + i * " + this.b);
    }
    UI() {
        return "<span>" + this.a + " + i * " + this.b + "</span>";
    }
}
const complex=(a,b)=>{
    if((a instanceof Array||ArrayBuffer.isView(a)) && (b instanceof Array||ArrayBuffer.isView(a)))return a.map((n,i)=>complex(a[i],b[i]));
    if(a instanceof Matrix && b instanceof Matrix){
        if((a.shape[0]!==b.shape[0])||(a.shape[1]!==b.shape[1]))return Error(0)
        const arr=a.arr.map((n,i)=>complex(a.arr[i],b.arr[i]));
        return new Matrix(a.rows,a.cols,...arr)
    }
    return new Complex(a,b)
};

var __Complex__ = /*#__PURE__*/Object.freeze({
  __proto__: null,
  Complex: Complex,
  complex: complex
});

// import { 
//     gamma,
//     bessel,
//     beta 
// } from "../calculus/index.js";

const abs=(...x)=>mapfun$1(Math.abs,...x);
const sqrt=(...x)=>mapfun$1(Math.sqrt,...x);
const pow=(x,n)=>{
    if(typeof x === "number"){
        if(typeof n === "number")return Math.pow(x,n);
        else if(n instanceof Complex)return Complex.fromExpo(x**n.a,n.b*ln(x))
        else return mapfun$1(a=>pow(x,a),...n);
    }
    else if(x instanceof Complex){
        if(typeof n === "number")return Complex.fromExpo(x.z**n,x.phi*n);
        else if(n instanceof Complex)return Complex.fromExpo(
            x.z**n.a*e(-x.phi*n.b),
            ln(x.z)*n.b+n.a*x.phi
        )
        else return mapfun$1(a=>pow(x,a),...n);
    }
    else if(x instanceof Array){
        if(typeof n === "number") return mapfun$1(a=>pow(a,n),...x);
        else if(n instanceof Array){
            const Y=[];
            for(let i=0;i<x.length;i++){
                Y.push(mapfun$1(a=>pow(x[i],a),...n));
            }
            return Y;
        }
    }
};
const sqrtn=(x,n)=>{
    if(typeof x === "number"){
        if(typeof n === "number")return Math.pow(x,1/n);
        else return mapfun$1(a=>sqrtn(x,a),...n);
    }
    else if(x instanceof Complex){
        if(typeof n === "number")return Complex.fromExpo(sqrtn(x.z,n),x.phi/n);
        else return mapfun$1(a=>sqrtn(x,a),...n);
    }
    else if(x instanceof Array){
        if(typeof n === "number") return mapfun$1(a=>sqrtn(a,n),...x);
        else if(n instanceof Array){
            const Y=[];
            for(let i=0;i<x.length;i++){
                Y.push(mapfun$1(a=>sqrtn(x[i],a),...n));
            }
            return Y;
        }
    }
};
const e=(...x)=>mapfun$1(Math.exp,...x);
const ln=(...x)=>mapfun$1(Math.log,...x);
const cos=(...x)=>mapfun$1(Fixed.cos,...x);
const sin=(...x)=>mapfun$1(Fixed.sin,...x);
const tan=(...x)=>mapfun$1(Fixed.tan,...x);
const sec=(...x)=>mapfun$1(Fixed.sec,...x);
const sinc=(...x)=>mapfun$1(Fixed.sinc,...x);
const csc=(...x)=>mapfun$1(Fixed.csc,...x);
const cot=(...x)=>mapfun$1(Fixed.cot,...x);
const acos=(...x)=>mapfun$1(Fixed.acos,...x);
const asin=(...x)=>mapfun$1(Fixed.asin,...x);
const atan=(...x)=>mapfun$1(Fixed.atan,...x);
const acot=(...x)=>mapfun$1(Fixed.acot,...x);
const cosh=(...x)=>mapfun$1(Fixed.cosh,...x);
const sinh=(...x)=>mapfun$1(Fixed.sinh,...x);
const tanh=(...x)=>mapfun$1(Fixed.tanh,...x);
const coth=(...x)=>mapfun$1(Fixed.coth,...x);
const acosh=(...x)=>mapfun$1(Fixed.acosh,...x);
const asinh=(...x)=>mapfun$1(Fixed.asinh,...x);
const atanh=(...x)=>mapfun$1(Fixed.atanh,...x);
const ceil=(...x)=>mapfun$1(Math.ceil,...x);
const floor=(...x)=>mapfun$1(Math.floor,...x);
const round=(...x)=>mapfun$1(Math.round,...x);
const atan2=(x,y,rad=true)=>{
    if(typeof x === "number"){
        if(typeof y === "number")return rad?Math.atan2(x,y):Math.atan2(x,y)*180/Math.PI;
        else return mapfun$1(a=>atan2(x,a,rad),...y);
    }
    // else if(x instanceof Complex){
    //     if(typeof n === "number")return Complex.fromExpo(x.z**n,x.phi*n);
    //     else return mapfun(a=>pow(x,a),...n);
    // }
    else if(x instanceof Array){
        if(typeof y === "number") return mapfun$1(a=>atan2(a,y,rad),...x);
        else if(y instanceof Array){
            const Y=[];
            for(let i=0;i<x.length;i++){
                Y.push(mapfun$1(a=>pow(x[i],a),...y));
            }
            return Y;
        }
    }
};
const fact=(...x)=>mapfun$1(n=> {
        let i,
        y = 1;
        if (n == 0) y = 1;
        else if (n > 0) for (i = 1; i <= n; i++) y *= i;
        else y = NaN;
        return y;
    },...x);
const sign=(...x)=>mapfun$1(Math.sign,...x);

const sig=(...x)=>mapfun$1(n=>1/(1+e(-n)),...x);

const hypot=(...x)=>{
    if(x.every(n=>typeof n === "number"))return Math.hypot(...x);
    if(x.every(n=>n instanceof Array))return mapfun$1(
        Math.hypot,
        ...x
    )
};

var __Functions__ = /*#__PURE__*/Object.freeze({
  __proto__: null,
  abs: abs,
  acos: acos,
  acosh: acosh,
  acot: acot,
  asin: asin,
  asinh: asinh,
  atan: atan,
  atan2: atan2,
  atanh: atanh,
  ceil: ceil,
  cos: cos,
  cosh: cosh,
  cot: cot,
  coth: coth,
  csc: csc,
  e: e,
  fact: fact,
  floor: floor,
  hypot: hypot,
  ln: ln,
  max: max,
  min: min,
  pow: pow,
  round: round,
  sec: sec,
  sig: sig,
  sign: sign,
  sin: sin,
  sinc: sinc,
  sinh: sinh,
  sqrt: sqrt,
  sqrtn: sqrtn,
  tan: tan,
  tanh: tanh
});

const Math$1 = {
    ...__Const__,
    ...__Functions__,
    ...__Complex__,
    ...__Matrix__,
    ...__Random__,
    ...__Utils__,
    ...__Discrect__,
};

class ZikoTimeLoop {
  constructor(callback, step = 1000/30, startTime=0, endTime = Infinity, started = true) {
    this.callback = callback;
    this.cache = {
      isRunning: false,
      AnimationId : null,
      t0 : null,
      step,
      // fps,
      startTime,
      endTime,
      started
    };
    this.init();
    this.i=0;
  }
  init(){
    // if(this.cache.step && this.cache.fps){
    //   console.warn(`Fps will be adjusted from ${this.cache.fps} to ${1000/this.cache.step} to ensure a smoother animation`);
    //   this.cache.fps=1000/this.cache.step;
    // }
    if(this.cache.started){
      this.cache.startTime?this.startAfter(this.cache.startTime):this.start();
      if(this.cache.endTime&&this.cache.endTime!==Infinity)this.stopAfter(this.cache.endTime);
    }
    return this;
  }
  // get TIME_STEP() {
  //   // return this.cache.step?this.cache.step:1000 / this.cache.fps;
  //   return this.cache.step;
  // }
  start() {
    if (!this.cache.isRunning) {
      this.i=0;
      this.cache.isRunning = true;
      this.cache.t0 = Date.now();
      this.animate();
    }
    return this;
  }
  pause() {
    if (this.cache.isRunning) {
      clearTimeout(this.cache.AnimationId);
      this.cache.isRunning = false;
    }
    return this;
  }
  stop(){
    this.pause();
    this.i=0;
    return this;
  }
  resume(){
    this.cache.isRunning=true;
    this.animate();
    return this;
  }
  startAfter(t=1000){
    setTimeout(this.start.bind(this),t);
    return this;
  }
  stopAfter(t=1000){
    setTimeout(this.stop.bind(this),t);
    return this;   
  }
  animate = () => {
    if (this.cache.isRunning) {
      const now = Date.now();
      const delta = now - this.cache.t0;
      if (delta > this.cache.step) {
        this.callback(this);
        this.i++;
        this.cache.t0 = now - (delta % this.cache.step);
      }
      this.cache.AnimationId = setTimeout(this.animate, 0);
    }  }
}
const useFps = fps => 1000/fps;
const useTimeLoop = (callback, step, startTime, endTime, started) => new ZikoTimeLoop(callback, step, startTime, endTime, started);

var Animation = /*#__PURE__*/Object.freeze({
  __proto__: null,
  useFps: useFps,
  useTimeLoop: useTimeLoop
});

const Ease={
    Linear:function(t){
        return t;
    },
    InSin(t){
        return 1 - Math.cos((t * Math.PI) / 2);
    },
    OutSin(t){
        return Math.sin((t * Math.PI) / 2);
    },
    InOutSin(t){
        return  -(Math.cos(Math.PI * t) - 1) / 2;
    },
    InQuad(t){
        return t**2;
    },
    OutQuad(t){
        return 1 - Math.pow((1 - t),2)
    },
    InOutQuad(t){
        return t < 0.5 ? 2 * Math.pow(t,2) : 1 - Math.pow(-2 * t + 2, 2) / 2;
    },
    InCubic(t){
        return t**3;    
    },
    OutCubic(t){
        return 1 - Math.pow((1 - t),3)
    },
    InOutCubic(t){
        return t < 0.5 ? 4 * Math.pow(t,3) : 1 - Math.pow(-2 * t + 2, 3) / 2;
    },
    InQuart(t){
        return t**4;
    },
    OutQuart(t){
        return 1 - Math.pow((1 - t),4);
    },
    InOutQuart(t){
        return t < 0.5 ? 8 * Math.pow(t,4) : 1 - Math.pow(-2 * t + 2, 4) / 2;
    },
    InQuint(t){
        return t**5;
    },
    OutQuint(t){
        return 1 - Math.pow((1 - t),5);
    },
    InOutQuint(t){
        return t < 0.5 ? 16 * Math.pow(t,5) : 1 - Math.pow(-2 * t + 2, 5) / 2;
    },
    InExpo(t){
        return t === 0 ? 0 : Math.pow(2, 10 * t - 10);
    },
    OutExpo(t){
        return t === 1 ? 1 : 1 - Math.pow(2, -10 * t);
    },
    InOutExpo(t){
        return t === 0? 0: t === 1? 1: t < 0.5 ? Math.pow(2, 20 * t - 10) / 2: (2 - Math.pow(2, -20 * t + 10)) / 2;
    },
    InCirc(t){
        return 1 - Math.sqrt(1 - Math.pow(t, 2));
    },
    OutCirc(t){
        return Math.sqrt(1 - Math.pow(t - 1, 2));
    },
    InOutCic(t){
        return t < 0.5? (1 - Math.sqrt(1 - Math.pow(2 * t, 2))) / 2: (Math.sqrt(1 - Math.pow(-2 * t + 2, 2)) + 1) / 2;
    },
    Arc(t){
        return 1 - Math.sin(Math.acos(t));
    },
    Back(t){
        // To Be Changed
        let x=1;
        return Math.pow(t, 2) * ((x + 1) * t - x);  
    },
    Elastic(t){
        return -2*Math.pow(2, 10 * (t - 1)) * Math.cos(20 * Math.PI * t / 3 * t);
    },
    InBack(t){
        const c1 = 1.70158;
        const c3 = c1 + 1;
        return c3 *Math.pow(t,3)- c1 * (t**2);      
    },
    OutBack(t){
        const c1 = 1.70158;
        const c3 = c1 + 1;
        return 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2);     
    },
    InOutBack(t){
        const c1 = 1.70158;
        const c2 = c1 * 1.525;
        return t < 0.5
        ? (Math.pow(2 * t, 2) * ((c2 + 1) * 2 * t - c2)) / 2
        : (Math.pow(2 * t - 2, 2) * ((c2 + 1) * (t * 2 - 2) + c2) + 2) / 2;        
    },
    InElastic(t){
        const c4 = (2 * Math.PI) / 3;return t === 0
        ? 0
        : t === 1
        ? 1
        : -Math.pow(2, 10 * t - 10) * Math.sin((t * 10 - 10.75) * c4);
    },
    OutElastic(t){
        const c4 = (2 * Math.PI) / 3;
        return t === 0
        ? 0
        : t === 1
        ? 1
        : Math.pow(2, -10 * t) * Math.sin((t * 10 - 0.75) * c4) + 1;
    },
    InOutElastic(t){
        const c5 = (2 * Math.PI) / 4.5;
        return t === 0
        ? 0
        : t === 1
        ? 1
        : t < 0.5
        ? -(Math.pow(2, 20 * t - 10) * Math.sin((20 * t - 11.125) * c5)) / 2
        : (Math.pow(2, -20 * t + 10) * Math.sin((20 * t - 11.125) * c5)) / 2 + 1;
    },
    InBounce(t){
        return 1 - Ease.OutBounce(1-t);
    },
    OutBounce(t){
        const n1 = 7.5625;
        const d1 = 2.75;
        if (t < 1 / d1) {
            return n1 * t * t;
        } else if (t < 2 / d1) {
            return n1 * (t -= 1.5 / d1) * t + 0.75;
        } else if (t < 2.5 / d1) {
            return n1 * (t -= 2.25 / d1) * t + 0.9375;
        } else {
            return n1 * (t -= 2.625 / d1) * t + 0.984375;
        }

    },
    InOutBounce(t){
        return t < 0.5
        ? (1 - Ease.OutBounce(1 - 2 * t)) / 2
        : (1 + Ease.OutBounce(2 * t - 1)) / 2;
    }
};

const useDebounce=(fn,delay=1000)=>{
    let id;
    return (...args)=>id?clearTimeout(id):setTimeout(()=>fn(...args),delay)
};
const useThrottle=(fn,delay)=>{
    let lastTime=0;
    return (...args)=>{
        const now=new Date().getTime();
        if(now-lastTime<delay)return;
        lastTime=now;
        fn(...args); 
    }
};

const time_memory_Taken = (callback) => {
    const t0 = Date.now();
    const m0 = performance.memory.usedJSHeapSize;
    const result = callback();
    const t1 = Date.now();
    const m1 = performance.memory.usedJSHeapSize;
    const elapsedTime = t1 - t0;
    const usedMemory = m1 - m0;
    return { 
        elapsedTime,
        usedMemory, 
        result 
    };
  };

const waitForUIElm=(UIElement)=>{
    return new Promise(resolve => {
        if (UIElement.element) {
            return resolve(UIElement.element);
        }
  
        const observer = new MutationObserver(() => {
            if (UIElement.element) {
                resolve(UIElement.element);
                observer.disconnect();
            }
        });
  
        observer.observe(document?.body, {
            childList: true,
            subtree: true
        });
    });
  };
  const waitForUIElmSync=(UIElement,timeout=2000)=>{
    const t0=Date.now();
    while(Date.now()-t0<timeout){
      if(UIElement.element)return UIElement.element
    }
  };

const wait=(delayInMS)=>{
    return new Promise((resolve) => setTimeout(resolve, delayInMS));
};
const timeTaken = callback => {
    console.time('timeTaken');
    const r = callback();
    console.timeEnd('timeTaken');
    return r;
};

var Utils = /*#__PURE__*/Object.freeze({
  __proto__: null,
  Ease: Ease,
  timeTaken: timeTaken,
  time_memory_Taken: time_memory_Taken,
  useDebounce: useDebounce,
  useThrottle: useThrottle,
  wait: wait,
  waitForUIElm: waitForUIElm,
  waitForUIElmSync: waitForUIElmSync
});

class ZikoTimeAnimation{
    constructor(callback,ease=Ease.Linear,step=50,{t=[0,null],start=true,duration=3000}={}){
        this.cache={
            isRunning:false,
            AnimationId:null,
            startTime:null,
            ease,
            step,
            intervall:t,
            started:start,
            duration
        };
        this.t=0;
        this.tx=0;
        this.ty=0;
        this.i=0;
        this.callback=callback;
    }
    #animation_handler(){
            this.t+=this.cache.step;
            this.i++;
            this.tx=map(this.t,0,this.cache.duration,0,1);
            this.ty=this.cache.ease(this.tx);
            this.callback(this);
            if(this.t>=this.cache.duration){
                clearInterval(this.cache.AnimationId);
                this.cache.isRunning=false;
            }
    }
    reset(restart=true){
        this.t=0;
        this.tx=0;
        this.ty=0;
        this.i=0;
        if(restart)this.start();
        return this;
    }
    #animate(reset=true){
        if(!this.cache.isRunning){
            if(reset)this.reset(false);
            this.cache.isRunning=true;
            this.cache.startTime = Date.now();
            this.cache.AnimationId=setInterval(this.#animation_handler.bind(this),this.cache.step);
        }
        return this;
    }
    start(){
        this.#animate(true);
        return this;
    }
    pause(){
        if (this.cache.isRunning) {
            clearTimeout(this.cache.AnimationId);
            this.cache.isRunning = false;
          }
        return this;
    }
    resume(){
        this.#animate(false);
        return this;
    }
    stop(){
        this.pause();
        this.reset(false);
        return this;
    }
    // clear(){
    // }
    // stream(){
    // }
}

const useAnimation=(callback,ease=Ease.Linear,step=50,config)=>new ZikoTimeAnimation(callback,ease=Ease.Linear,step=50,config);

const Time = {
    ...Animation,
    ...Animation,
    ...Utils
};

class ZikoUISvg extends ZikoUIElement {
    constructor(w=360,h=300) {
      super("svg","svg");
      //this.cache={};
      // this.setAttr("width",w);
      // this.setAttr("height",h);
      // this.setAttr({
      //   width : w,
      //   height : h
      // })
      this.style({border:"1px black solid"});
      //this.view(-w/2,-h/2,w/2,h/2);
      this.size(w, h);
      this.view(-10,-10,10,10);
    }
    size(w, h){
      this.setAttr({
        width : w,
        height : h
      });
      return this
    }
    view(x1,y1,x2,y2){
      let width=Math.abs(x2-x1);
      let height=Math.abs(y2-y1);
      this.setAttr("viewBox",[x1,y1,width,height].join(" "));
      this.st.scaleY(-1);
      return this;
    }
    add(...svgElement){
      for(let i=0;i<svgElement.length;i++){
        this.element.append(svgElement[i].element);
        this.items.push(svgElement[i]);
      }
      this.maintain();
      return this;
    }
    remove(...svgElement){
      for(let i=0;i<svgElement.length;i++){
        this.element?.removeChild(svgElement[i].element);
        this.items=this.items.filter(n=>!svgElement);
      }
      this.maintain();
      return this;     
    }
    mask(){
  
    }
    toString(){
      return  (new XMLSerializer()).serializeToString(this.element);
    }
    btoa(){
      return btoa(this.toString())
    }
    toImg(){
      return 'data:image/svg+xml;base64,'+this.btoa()
    }
    toImg2(){
      return "data:image/svg+xml;charset=utf8,"+this.toString().replaceAll("<","%3C").replaceAll(">","%3E").replaceAll("#","%23").replaceAll('"',"'");
    }
    
  }

  const Svg =(w,h)=>new ZikoUISvg(w,h);

var SVG = /*#__PURE__*/Object.freeze({
  __proto__: null,
  Svg: Svg,
  ZikoUISvg: ZikoUISvg
});

// import { convolute } from "../../math/signal/conv.js";
class ZikoUICanvas extends ZikoUIElement{
    constructor(w,h){
        super("canvas","canvas");
        this.ctx = this.element?.getContext("2d");
        this.style({
            border:"1px red solid",
        });
        this.transformMatrix=new Matrix([
            [1,0,0],
            [0,1,0],
            [0,0,1]
        ]);
        this.axisMatrix=new Matrix([
            [-10,-10],
            [10,10]
        ]);
        // setTimeout(()=>this.resize(w,h),0);
        requestAnimationFrame(()=>this.resize(w,h),0);
        this.on("sizeupdated",()=>this.adjust());
    }
    get Xmin(){
        return this.axisMatrix[0][0];
    }
    get Ymin(){
        return this.axisMatrix[0][1];
    }
    get Xmax(){
        return this.axisMatrix[1][0];
    }
    get Ymax(){
        return this.axisMatrix[1][1];
    }
    get ImageData(){
        return this.ctx.getImageData(0,0,c.Width,c.Height);
    }
    draw(all=true){
        if(all){
            this.clear();  
            this.items.forEach(element => {
                element.parent=this;
                element.draw(this.ctx);
            });
        }
        else {
            this.items.at(-1).parent=this;
            this.items.at(-1).draw(this.ctx);
        }
        this.maintain();
        return this;
    }
    applyTransformMatrix(){
        this.ctx.setTransform(
            this.transformMatrix[0][0],
            this.transformMatrix[1][0],
            this.transformMatrix[0][1],
            this.transformMatrix[1][1],
            this.transformMatrix[0][2],
            this.transformMatrix[1][2],
        );
        return this;
    }
    resize(w,h){
        this.size(w,h);
        this.lineWidth();
        this.view(this.axisMatrix[0][0], this.axisMatrix[0][1], this.axisMatrix[1][0], this.axisMatrix[1][1]);
        this.emit("sizeupdated");
        return this;
    }
    adjust(){
        this.element.width =this.element?.getBoundingClientRect().width;
        this.element.height =this.element?.getBoundingClientRect().height;
        this.view(this.axisMatrix[0][0], this.axisMatrix[0][1], this.axisMatrix[1][0], this.axisMatrix[1][1]);
        return this;
    }
    view(xMin,yMin,xMax,yMax){
        this.transformMatrix[0][0]=this.width/(xMax-xMin); // scaleX
        this.transformMatrix[1][1]=-this.height/(yMax-yMin); // scaleY
        this.transformMatrix[0][2]=this.width/2;
        this.transformMatrix[1][2]=this.height/2;
        this.axisMatrix=new Matrix([
            [xMin,yMin],
            [xMax,yMax]
        ]);
        
        this.applyTransformMatrix(); 
        this.clear();
        this.lineWidth(1);
        this.draw();
        return this;
    }
    reset(){
        this.ctx.setTransform(1,0,0,0,0,0);
        return this;
    }
    append(element){
        this.items.push(element);
        this.draw(false);
        return this;
    }
    background(color){
        this.ctx.fillStyle = color;
        this.ctx.setTransform(1, 0, 0, 1, 0, 0);
        this.ctx.fillRect(0, 0, this.width, this.height);
        this.applyTransformMatrix();
        this.draw();
    }
    lineWidth(w){
        this.ctx.lineWidth=w/this.transformMatrix[0][0];
        return this
    }
    getImageData(x=0,y=0,w=this.width,h=this.height){
        return this.ctx.getImageData(x,y,w,h);
    }
    clear(){
        this.ctx.setTransform(1, 0, 0, 1, 0, 0);
        this.ctx.clearRect(0, 0, this.width, this.height);
        this.applyTransformMatrix(); 
        return this;
    }
    clone(){
        console.log(this.width);
        const canvas=new ZikoUICanvas();
        canvas.items=this.items;
        canvas.transformMatrix=this.transformMatrix;
        canvas.axisMatrix=this.axisMatrix;
        Object.assign(canvas.cache,{...this.cache});
        //waitForUIElm(this)
        //console.log(element)
        this.size(this.element.style.width,this.element.style.width);
        this.applyTransformMatrix();
        this.draw();
        this.adjust();
        return canvas;
    }
    toImage() {
        this.img = document?.createElement("img");
        this.img.src = this.element?.toDataURL("image/png");
        return this;
    }
    toBlob() {
        var canvas = this.element;
        canvas.toBlob(function (blob) {
            var newImg = document?.createElement("img"),
                url = URL.createObjectURL(blob);
            newImg.onload = function () {
                URL.revokeObjectURL(url);
            };
            newImg.src = url;
            console.log(newImg);
        });
    }
    zoomIn(){

    }
    zoomOut(){
        
    }
    undo(n){

    }
    redo(n){

    }
    stream(){

    }
}

const Canvas=(w,h)=>new ZikoUICanvas(w,h);

var CANVAS = /*#__PURE__*/Object.freeze({
  __proto__: null,
  Canvas: Canvas,
  ZikoUICanvas: ZikoUICanvas
});

const Graphics = {
    ...SVG,
    ...CANVAS
};

class ZikoUseFavIcon{
    constructor(FavIcon,useEventEmitter=true){
        this.#init();
        this.cache={
            Emitter:null
        };
        if(useEventEmitter)this.useEventEmitter();
        this.set(FavIcon);
    }
    #init(){     
        this.__FavIcon__ = document.querySelector("link[rel*='icon']") || document?.createElement('link');   
        this.__FavIcon__.type = 'image/x-icon';
        this.__FavIcon__.rel = 'shortcut icon';
        return this;
    }
    set(href){
        if(href!==this.__FavIcon__.href){
            this.__FavIcon__.href=href;
            if(this.cache.Emitter)this.cache.Emitter.emit("ziko:favicon-changed");
        }
        return this;
    }
    get current(){
        return document.__FavIcon__.href;
    }
    onChange(callback){
        if(this.cache.Emitter)this.cache.Emitter.on("ziko:favicon-changed",callback);
        return this;
    }
    useEventEmitter(){
        this.cache.Emitter=useEventEmitter();
        return this;
    }

}
const useFavIcon=(FavIcon,useEventEmitter)=>new ZikoUseFavIcon(FavIcon,useEventEmitter);

class ZikoMeta{
    constructor({viewport,charset,description,author,keywords}){
        this.document = globalThis?.document; 
        this.meta={};
        this.init({viewport,charset,description,author,keywords});
    }
    init({viewport,charset,description,author,keywords}){
        viewport && this.setViewport(viewport);
        charset && this.setCharset(charset);
        description && this.describe(description);
        author && this.setAuthor(author);
        keywords && this.setKeywords(keywords);
    }
    set(key,value){
        key = key.toLowerCase();
        const isCharset = (key === "charset");
        const meta = isCharset ? document.querySelector("meta[charset]"):document.querySelector(`meta[name=${key}]`);
        this.meta=meta?? document?.createElement("meta");
        if(isCharset) this.meta.setAttribute("charset",value);
        else {
            this.meta.setAttribute("name",key);
            this.meta.setAttribute("content",value);
        }
        if(!meta)this.document.head.append(this.meta);
        return this;     
    }
    setCharset(charset="utf-8"){
        this.set("charset",charset);
        return this;
    }
    describe(description){
        this.set("description",description);
        return this;    
    }
    setViewport(viewport="width=device-width, initial-scale=1.0"){
        this.set("viewport",viewport);
        return this;    
    }
    setKeywords(...keywords){
        // keywords.push("zikojs");
        keywords=[...new Set(keywords)].join(", ");
        this.set("keywords",keywords);
        return this;
    }
    setAuthor(author){
        this.set("author",author);
        return this;
    }
}
const useMeta=({viewport,charset,description,author,keywords})=>new ZikoMeta({viewport,charset,description,author,keywords});

class ZikoUseTitle{
    constructor(title=document.title,useEventEmitter=true){
        this.cache={
            Emitter:null
        };
        if(useEventEmitter)this.useEventEmitter();
        this.set(title);
    }
    useEventEmitter(){
        this.cache.Emitter=useEventEmitter();
        return this;
    }
    set(title){
        if(title!==document.title){
            document.title=title;
            if(this.cache.Emitter)this.cache.Emitter.emit("ziko:title-changed");
        }
        return this;
    }
    get current(){
        return document.title;
    }
    onChange(callback){
        if(this.cache.Emitter)this.cache.Emitter.on("ziko:title-changed",callback);
        return this;
    }
}
const useTitle=(title, useEventEmitter)=>new ZikoUseTitle(title, useEventEmitter);

// import {useLink} from "./";
class ZikoHead{
    constructor({title,lang,icon,meta,noscript}){
        this.html = globalThis?.document?.documentElement;
        this.head = globalThis?.document?.head;

        title && useTitle(title);
        lang && this.setLang(lang);
        icon && useFavIcon(icon);
        meta && useMeta(meta);
        noscript && this.setNoScript();
    }
    setLang(lang){
        this.html.setAttribute("lang",lang);
    }
    setNoScript(content){

    }
}

const useHead=({ title, lang, icon, meta, noscript })=>new ZikoHead({ title, lang, icon, meta, noscript });

class ZikoApp {
    constructor({head = null, wrapper = null, target = null}){
        this.head = head;
        this.wrapper = wrapper;
        this.target = target;
        this.init();        
    }
    get isZikoApp(){
        return true;
    }
    init(){
        this.head && this.setHead(this.head);
        this.wrapper && this.setWrapper(this.wrapper);
        this.target && this.setTarget(this.target);
        if(this.wrapper && this.target)this.wrapper.render(this.target);
    }
    setTarget(target){
        if(target instanceof HTMLElement) this.target = target;
        else if (typeof target === "string") this.target = globalThis?.document?.querySelector(target);
        return this;
    }
    setWrapper(wrapper){
        if(wrapper?.isZikoUIElement) this.wrapper = wrapper;
        else if(typeof wrapper === "function") this.wrapper = wrapper();
        return this;
    }
    setHead(head){
        if(head instanceof ZikoHead) this.head = head;
        else this.head = useHead(head);
        return this;  
    }
    
}
const App$1 = ({head, wrapper, target}) => new ZikoApp({head, wrapper, target});

var __App__ = /*#__PURE__*/Object.freeze({
  __proto__: null,
  App: App$1,
  ZikoApp: ZikoApp
});

function routesMatcher(mask, route) {
    const maskSegments = mask.split('/');
    const routeSegments = route.split('/');
    if (maskSegments.length !== routeSegments.length) {
        return false;
    }
    for (let i = 0; i < maskSegments.length; i++) {
        const maskSegment = maskSegments[i];
        const routeSegment = routeSegments[i];
        if (maskSegment.startsWith(':')) {
            continue;
        } else if (maskSegment !== routeSegment) {
            return false;
        }
    }    
    return true;
}
function dynamicRoutesParser(mask, route) {
    const maskSegments = mask.split('/');
    const routeSegments = route.split('/');
    const params = {};
    if (maskSegments.length !== routeSegments.length) {
        return params; 
    }
    for (let i = 0; i < maskSegments.length; i++) {
        const maskSegment = maskSegments[i];
        const routeSegment = routeSegments[i];
        if (maskSegment.startsWith(':')) {
            const paramName = maskSegment.slice(1); 
            params[paramName] = routeSegment;
        } else if (maskSegment !== routeSegment) {
            return {};
        }
    }
    return params;
}

function isDynamic(path) {
    const DynamicPattern = /:\w+/;    
    return DynamicPattern.test(path);
  }

// // Example usage:
// const mask = "app/lang/:lang/id/:id";
// const route = "app/lang/en/id/7";
// console.log(dynamicRoutesParser(mask, route)); // Should return { lang: "en", id: "7" }

class ZikoSPA extends ZikoApp{
    constructor({head, wrapper, target, routes}){
        super({head, wrapper, target});
        this.routes=new Map([
            ["404",text("Error 404")],
            ...Object.entries(routes)
        ]);
        this.clear();
        globalThis.onpopstate = this.render(location.pathname);
    }
    clear(){
        [...this.routes].forEach(n=>{
            !isDynamic(n[0]) && n[1]?.isZikoUIElement && n[1].unrender();
        });   
        // this.wrapper.clear();
        return this;
    }
    render(path){
        const [mask, callback] = [...this.routes].find(route=>routesMatcher(route[0],path));
        let element ;
        if(isDynamic(mask)){
            const params = dynamicRoutesParser(mask, path);
            element = callback.call(this,params);
        }
        else {
            callback?.isZikoUIElement && callback.render(this.wrapper); 
            if(typeof callback === "function") element = callback();  
        }
        if(element?.isZikoUIElement) element.render(this.wrapper);
        // if(element?.isZikoApp) element.render(this.wrapper);
        if(element instanceof Promise){
            element.then(e=>e.render(this.wrapper));
        }
        globalThis.history.pushState({}, "", path);
        return this;
    }
}
const SPA=({head, wrapper, target, routes})=>new ZikoSPA({head, wrapper, target, routes});


/*
 // Static 
  S.get("/url",wrapper)
// Dynamique 
 s.get("/url/name/:name/id/:id",(path,name,id)=>handler())
// regEx
*/

var Spa = /*#__PURE__*/Object.freeze({
  __proto__: null,
  SPA: SPA,
  ZikoSPA: ZikoSPA
});

function parseQueryParams(queryString) {
    const params = {};
    queryString.replace(/[A-Z0-9]+?=([\w|:|\/\.]*)/gi, (match) => {
        const [key, value] = match.split('=');
        params[key] = value;
    });
    return params;
}

function defineParamsGetter(target ){
    Object.defineProperties(target, {
        'QueryParams': {
            get: function() {
                return parseQueryParams(globalThis.location.search.substring(1));
            },
            configurable: false,
            enumerable: true 
        },
        'HashParams': {
            get: function() {
                const hash = globalThis.location.hash.substring(1);
                return hash.split("#");
            },
            configurable: false,
            enumerable: true 
        }
    });
}

const __UI__={
    __all__(){
        return Object.values(this)
          .filter(Array.isArray)
          .flat();
    },
    querySelectorAll(){
        return this.__all__().filter(n=>n)
    },
    getElementByIndex(index){
        return this.__all__().find(n=>n.ui_index===index);
    },
    getElementById(id){
        return null;
    },
    getElementsByClass(){

    },
    getElementsByTagName(){
        
    }
};
const __HYDRATION__ = {
    map : new Map(),
    index : 0,
    increment : function(){
        return this.index ++
    }
};
const __HYDRATION_MAP__ = new Map();
const __Config__={
    default:{
        target:null,
        render:true,
        math:{
            mode:"deg"
        }
    },
    setDefault:function(pairs){
        const keys=Object.keys(pairs);
        const values=Object.values(pairs);
        for(let i=0; i<keys.length; i++) this.default[keys[i]]=values[i];
    },
    init:()=>{
        // document.documentElement.setAttribute("data-engine","zikojs")
    },
    renderingMode :"spa",
    isSSC : false,
};
const __CACHE__ = {
    ui_index : 0,
    get_ui_index:function(){
        return this.ui_index ++
    }
};

var Global = /*#__PURE__*/Object.freeze({
  __proto__: null,
  __CACHE__: __CACHE__,
  __Config__: __Config__,
  __HYDRATION_MAP__: __HYDRATION_MAP__,
  __HYDRATION__: __HYDRATION__,
  __UI__: __UI__
});

// import.meta.glob('./src/pages/**/*.js')
async function FileBasedRouting(pages /* use import.meta.glob */){
   const routes = Object.keys(pages);
   const root = findCommonPath(routes);
   const pairs = {};
   for(let i=0; i<routes.length; i++){
      const module = await pages[routes[i]]();
      const component = await module.default;
      Object.assign(pairs,{[customPath(routes[i], root)]:component});
   }
   return SPA({
      target : document.body,
      routes : {
         "/" : ()=>{},
         ...pairs
      },
      wrapper : Section()
   })   
}
function customPath(inputPath, root = './src/pages', extensions = ['js', 'ts']) {
   if(root.at(-1)==="/") root = root.slice(0, -1);
   const normalizedPath = inputPath.replace(/\\/g, '/').replace(/\[(\w+)\]/g, '$1/:$1');
   const parts = normalizedPath.split('/');
   const rootParts = root.split('/');
   const rootIndex = parts.indexOf(rootParts[rootParts.length - 1]);
   if (rootIndex !== -1) {
       const subsequentParts = parts.slice(rootIndex + 1);
       const lastPart = subsequentParts[subsequentParts.length - 1];
       const isIndexFile = lastPart === 'index.js' || lastPart === 'index.ts';
       const hasValidExtension = extensions.some(ext => lastPart === `.${ext}` || lastPart.endsWith(`.${ext}`));
       if (isIndexFile) {
           return '/' + (subsequentParts.length > 1 ? subsequentParts.slice(0, -1).join('/') : '');
       }
       if (hasValidExtension) {
           return '/' + subsequentParts.join('/').replace(/\.(js|ts)$/, '');
       }
   }
   return '';
}
function findCommonPath(paths) {
   if (paths.length === 0) return '';
   const splitPaths = paths.map(path => path.split('/'));
   const minLength = Math.min(...splitPaths.map(parts => parts.length));
   let commonParts = [];
   for (let i = 0; i < minLength; i++) {
       const part = splitPaths[0][i]; 
       if (splitPaths.every(parts => parts[i] === part || parts[i].startsWith('['))) {
           commonParts.push(part);
       } else {
           break; 
       }
   }
   const commonPath = commonParts.join('/') + (commonParts.length ? '/' : '');
   return commonPath;
}

// import * as Params from "./params"

const App={
    ...__App__,
    ...Spa,
    ...Global,
    // ...Params
};

class ZikoUseChannel{
    constructor(name = ""){
        this.channel = new BroadcastChannel(name);
        this.EVENTS_DATAS_PAIRS = new Map();
        this.EVENTS_HANDLERS_PAIRS = new Map();
        this.LAST_RECEIVED_EVENT = "";
        this.UUID="ziko-channel"+Random.string(10);
        this.SUBSCRIBERS = new Set([this.UUID]);
    }
    get broadcast(){
        // update receiver
        return this;
    }
    emit(event, data){
        this.EVENTS_DATAS_PAIRS.set(event,data);
        this.#maintainEmit(event);
        return this;
    }
    on(event,handler=console.log){
        this.EVENTS_HANDLERS_PAIRS.set(event,handler);
        this.#maintainOn();
        return this;
    }
    #maintainOn(){
        this.channel.onmessage = (e) => {
            this.LAST_RECEIVED_EVENT=e.data.last_sended_event;
            const USER_ID=e.data.userId;
            this.SUBSCRIBERS.add(USER_ID);
            const Data=e.data.EVENTS_DATAS_PAIRS.get(this.LAST_RECEIVED_EVENT);
            const Handler=this.EVENTS_HANDLERS_PAIRS.get(this.LAST_RECEIVED_EVENT);
            if(Data && Handler)Handler(Data);
          };
          return this;
    }
    #maintainEmit(event){
        this.channel.postMessage({
            EVENTS_DATAS_PAIRS:this.EVENTS_DATAS_PAIRS,
            last_sended_event:event,
            userId:this.UUID
        });
        return this;
    }
    close(){
        this.channel.close();
        return this;
    }
}
const useChannel = name => new ZikoUseChannel(name);

// To do : remove old items
class ZikoUseStorage{
    constructor(storage, globalKey, initialValue){
        this.cache={
            storage,
            globalKey,
            channel:useChannel(`Ziko:useStorage-${globalKey}`),
            oldItemKeys:new Set()
        };
        this.#init(initialValue);
        this.#maintain();
    }
    get items(){
        return JSON.parse(this.cache.storage[this.cache.globalKey]??null);
    }
    #maintain() {
        for(let i in this.items)Object.assign(this, { [[i]]: this.items[i] });
    }
    #init(initialValue){
        this.cache.channel=useChannel(`Ziko:useStorage-${this.cache.globalKey}`);
        this.cache.channel.on("Ziko-Storage-Updated",()=>this.#maintain());
        if(!initialValue)return;
        if(this.cache.storage[this.cache.globalKey]){
            Object.keys(this.items).forEach(key=>this.cache.oldItemKeys.add(key));
            console.group("Ziko:useStorage");
            console.warn(`Storage key '${this.cache.globalKey}' already exists. we will not overwrite it.`);
            console.info(`%cWe'll keep the existing data.`,"background-color:#2222dd; color:gold;");
            console.group("");
        }
        else this.set(initialValue);
    }
    set(data){
        this.cache.storage.setItem(this.cache.globalKey,JSON.stringify(data));
        this.cache.channel.emit("Ziko-Storage-Updated",{});
        Object.keys(data).forEach(key=>this.cache.oldItemKeys.add(key));
        this.#maintain();
        return this
    }
    add(data){
        const db={
            ...this.items,
            ...data
        };
        this.cache.storage.setItem(this.cache.globalKey,JSON.stringify(db));
        this.#maintain();
        return this;
    }
    remove(...keys){
        const db={...this.items};
        for(let i=0;i<keys.length;i++){
            delete db[keys[i]];
            delete this[keys[i]];
        }
        this.set(db);
        return this;
    }
    get(key){
        return this.items[key];
    }
    clear(){
        this.cache.storage.removeItem(this.cache.globalKey);
        this.#maintain();
        return this;
    }

}
const useLocaleStorage=(key,initialValue)=>new ZikoUseStorage(localStorage,key,initialValue);
const useSessionStorage=(key,initialValue)=>new ZikoUseStorage(sessionStorage,key,initialValue);

class ZikoUseThreed {
    #workerContent;
    constructor() {
        this.#workerContent = (
            function (msg) {
                try {
                    const func = new Function("return " + msg.data.fun)();
                    let result = func();
                    postMessage({ result });
                } catch (error) {
                    postMessage({ error: error.message });
                } finally {
                    if (msg.data.close) self.close();
                }
            }
        ).toString();
        this.blob = new Blob(["this.onmessage = " + this.#workerContent], { type: "text/javascript" });
        this.worker = new Worker(window.URL.createObjectURL(this.blob));
    }
    call(func, callback, close = true) {
        this.worker.postMessage({
            fun: func.toString(),
            close
        });
        this.worker.onmessage = function (e) {
            if (e.data.error) {
                console.error(e.data.error);
            } else {
                callback(e.data.result);
            }
        };
        return this;
    }
}

const useThread = (func, callback , close) => {
    const T = new ZikoUseThreed();
    if (func) {
        T.call(func, callback , close);
    }
    return T;
};

[
    App,
    Math$1,
    UI$1,
    Time,
    Data,
    Reactivity,
    Graphics,
].forEach(n=>Object.assign(n,{
    ExtractAll:()=>__ExtractAll__(n),
    RemoveAll:()=>__RemoveAll__(n)
}));

const Ziko={
    App,
    Math: Math$1,
    UI: UI$1,
    Time,
    Data,
    Reactivity,
    Graphics
};

if ( globalThis.__Ziko__ ) {
    console.warn( 'WARNING: Multiple instances of Ziko.js being imported.' );
	} else {
		globalThis.__Ziko__={
            ...Ziko,
            __UI__,
            __HYDRATION__,
            __HYDRATION_MAP__,
            __Config__,
            __CACHE__,
            ExtractAll,
            RemoveAll
        };
        defineParamsGetter(__Ziko__);
	}
// globalThis.__Ziko__={
//     ...Ziko,
//     __UI__,
//     __Config__,
//     ExtractAll,
//     RemoveAll
// };
if(globalThis?.document){
    document?.addEventListener("DOMContentLoaded", __Ziko__.__Config__.init());
}
function ExtractAll(){
    UI$1.ExtractAll();
    Math$1.ExtractAll();
    Time.ExtractAll();
    Reactivity.ExtractAll();
    Graphics.ExtractAll();
    Data.ExtractAll();
    return this;
}
function RemoveAll(){
    UI$1.RemoveAll();
    Math$1.RemoveAll();
    Time.RemoveAll();
    Reactivity.RemoveAll();
    Graphics.RemoveAll();
    Data.RemoveAll();
}

exports.App = App$1;
exports.Article = Article;
exports.Aside = Aside;
exports.Base = Base;
exports.Canvas = Canvas;
exports.Combinaison = Combinaison;
exports.Complex = Complex;
exports.E = E;
exports.EPSILON = EPSILON;
exports.Ease = Ease;
exports.FileBasedRouting = FileBasedRouting;
exports.Flex = Flex;
exports.Footer = Footer;
exports.Form = Form;
exports.Grid = Grid$1;
exports.HTMLWrapper = HTMLWrapper;
exports.Header = Header;
exports.Logic = Logic$1;
exports.Main = Main;
exports.Matrix = Matrix;
exports.Nav = Nav;
exports.PI = PI$1;
exports.Permutation = Permutation;
exports.Random = Random;
exports.SPA = SPA;
exports.SVGWrapper = SVGWrapper;
exports.Section = Section;
exports.Str = Str;
exports.Suspense = Suspense;
exports.Svg = Svg;
exports.Table = Table$1;
exports.Utils = Utils$1;
exports.ZikoApp = ZikoApp;
exports.ZikoCustomEvent = ZikoCustomEvent;
exports.ZikoEventClick = ZikoEventClick;
exports.ZikoEventClipboard = ZikoEventClipboard;
exports.ZikoEventCustom = ZikoEventCustom;
exports.ZikoEventDrag = ZikoEventDrag;
exports.ZikoEventFocus = ZikoEventFocus;
exports.ZikoEventInput = ZikoEventInput;
exports.ZikoEventKey = ZikoEventKey;
exports.ZikoEventMouse = ZikoEventMouse;
exports.ZikoEventPointer = ZikoEventPointer;
exports.ZikoEventSwipe = ZikoEventSwipe;
exports.ZikoEventTouch = ZikoEventTouch;
exports.ZikoEventWheel = ZikoEventWheel;
exports.ZikoHead = ZikoHead$1;
exports.ZikoMutationObserver = ZikoMutationObserver;
exports.ZikoSPA = ZikoSPA;
exports.ZikoUIAbbrText = ZikoUIAbbrText;
exports.ZikoUIArticle = ZikoUIArticle;
exports.ZikoUIAside = ZikoUIAside;
exports.ZikoUIAudio = ZikoUIAudio;
exports.ZikoUIBlockQuote = ZikoUIBlockQuote;
exports.ZikoUIBr = ZikoUIBr;
exports.ZikoUICanvas = ZikoUICanvas;
exports.ZikoUICodeText = ZikoUICodeText;
exports.ZikoUIDefintion = ZikoUIDefintion;
exports.ZikoUIElement = ZikoUIElement;
exports.ZikoUIFigure = ZikoUIFigure;
exports.ZikoUIFlex = ZikoUIFlex;
exports.ZikoUIFooter = ZikoUIFooter;
exports.ZikoUIForm = ZikoUIForm;
exports.ZikoUIGrid = ZikoUIGrid;
exports.ZikoUIHTMLWrapper = ZikoUIHTMLWrapper;
exports.ZikoUIHeader = ZikoUIHeader;
exports.ZikoUIHeading = ZikoUIHeading;
exports.ZikoUIHr = ZikoUIHr;
exports.ZikoUIHtmlTag = ZikoUIHtmlTag;
exports.ZikoUIImage = ZikoUIImage;
exports.ZikoUIInput = ZikoUIInput;
exports.ZikoUIInputCheckbox = ZikoUIInputCheckbox;
exports.ZikoUIInputColor = ZikoUIInputColor;
exports.ZikoUIInputDatalist = ZikoUIInputDatalist$1;
exports.ZikoUIInputDate = ZikoUIInputDate;
exports.ZikoUIInputDateTime = ZikoUIInputDateTime;
exports.ZikoUIInputEmail = ZikoUIInputEmail;
exports.ZikoUIInputImage = ZikoUIInputImage;
exports.ZikoUIInputNumber = ZikoUIInputNumber;
exports.ZikoUIInputOption = ZikoUIInputOption;
exports.ZikoUIInputPassword = ZikoUIInputPassword;
exports.ZikoUIInputRadio = ZikoUIInputRadio;
exports.ZikoUIInputSearch = ZikoUIInputSearch;
exports.ZikoUIInputSlider = ZikoUIInputSlider$1;
exports.ZikoUIInputTime = ZikoUIInputTime;
exports.ZikoUILabel = ZikoUILabel;
exports.ZikoUILink = ZikoUILink;
exports.ZikoUIMain = ZikoUIMain;
exports.ZikoUINav = ZikoUINav;
exports.ZikoUIParagraphe = ZikoUIParagraphe;
exports.ZikoUIQuote = ZikoUIQuote;
exports.ZikoUISVGWrapper = ZikoUISVGWrapper;
exports.ZikoUISection = ZikoUISection;
exports.ZikoUISelect = ZikoUISelect;
exports.ZikoUISubText = ZikoUISubText;
exports.ZikoUISupText = ZikoUISupText;
exports.ZikoUISuspense = ZikoUISuspense;
exports.ZikoUISvg = ZikoUISvg;
exports.ZikoUIText = ZikoUIText;
exports.ZikoUITextArea = ZikoUITextArea;
exports.ZikoUIVideo = ZikoUIVideo;
exports.ZikoUIXMLWrapper = ZikoUIXMLWrapper;
exports.ZikoUseRoot = ZikoUseRoot;
exports.ZikoUseStyle = ZikoUseStyle;
exports.__CACHE__ = __CACHE__;
exports.__Config__ = __Config__;
exports.__HYDRATION_MAP__ = __HYDRATION_MAP__;
exports.__HYDRATION__ = __HYDRATION__;
exports.__UI__ = __UI__;
exports.__ZikoEvent__ = __ZikoEvent__;
exports.abbrText = abbrText;
exports.abs = abs;
exports.accum = accum;
exports.acos = acos;
exports.acosh = acosh;
exports.acot = acot;
exports.add = add;
exports.arange = arange;
exports.arr2str = arr2str;
exports.asin = asin;
exports.asinh = asinh;
exports.atan = atan;
exports.atan2 = atan2;
exports.atanh = atanh;
exports.audio = audio;
exports.bindClickEvent = bindClickEvent;
exports.bindClipboardEvent = bindClipboardEvent;
exports.bindCustomEvent = bindCustomEvent;
exports.bindDragEvent = bindDragEvent;
exports.bindFocusEvent = bindFocusEvent;
exports.bindHashEvent = bindHashEvent;
exports.bindKeyEvent = bindKeyEvent;
exports.bindMouseEvent = bindMouseEvent;
exports.bindPointerEvent = bindPointerEvent;
exports.bindTouchEvent = bindTouchEvent;
exports.bindWheelEvent = bindWheelEvent;
exports.blockQuote = blockQuote;
exports.br = br;
exports.brs = brs;
exports.btn = btn;
exports.cartesianProduct = cartesianProduct;
exports.ceil = ceil;
exports.checkbox = checkbox;
exports.clamp = clamp;
exports.codeText = codeText;
exports.combinaison = combinaison;
exports.complex = complex;
exports.cos = cos;
exports.cosh = cosh;
exports.cot = cot;
exports.coth = coth;
exports.count = count;
exports.countWords = countWords;
exports.csc = csc;
exports.csv2arr = csv2arr;
exports.csv2json = csv2json;
exports.csv2matrix = csv2matrix;
exports.csv2object = csv2object;
exports.csv2sql = csv2sql;
exports.datalist = datalist;
exports.default = Ziko;
exports.defineParamsGetter = defineParamsGetter;
exports.deg2rad = deg2rad;
exports.dfnText = dfnText;
exports.div = div;
exports.e = e;
exports.fact = fact;
exports.figure = figure;
exports.floor = floor;
exports.geomspace = geomspace;
exports.getEvent = getEvent;
exports.h = h;
exports.h1 = h1;
exports.h2 = h2;
exports.h3 = h3;
exports.h4 = h4;
exports.h5 = h5;
exports.h6 = h6;
exports.hTags = hTags;
exports.hr = hr;
exports.hrs = hrs;
exports.html = html;
exports.hypot = hypot;
exports.image = image;
exports.inRange = inRange;
exports.input = input;
exports.inputCamera = inputCamera;
exports.inputColor = inputColor;
exports.inputDate = inputDate;
exports.inputDateTime = inputDateTime;
exports.inputEmail = inputEmail;
exports.inputImage = inputImage;
exports.inputNumber = inputNumber;
exports.inputPassword = inputPassword;
exports.inputTime = inputTime;
exports.isApproximatlyEqual = isApproximatlyEqual;
exports.json2arr = json2arr;
exports.json2css = json2css;
exports.json2csv = json2csv;
exports.json2csvFile = json2csvFile;
exports.json2xml = json2xml;
exports.json2xmlFile = json2xmlFile;
exports.json2yml = json2yml;
exports.json2ymlFile = json2ymlFile;
exports.lerp = lerp;
exports.li = li;
exports.link = link;
exports.linspace = linspace;
exports.ln = ln;
exports.logspace = logspace;
exports.map = map;
exports.mapfun = mapfun$1;
exports.matrix = matrix;
exports.matrix2 = matrix2;
exports.matrix3 = matrix3;
exports.matrix4 = matrix4;
exports.max = max;
exports.min = min;
exports.modulo = modulo;
exports.mul = mul;
exports.norm = norm;
exports.nums = nums;
exports.obj2str = obj2str;
exports.ol = ol;
exports.ones = ones;
exports.p = p;
exports.pgcd = pgcd;
exports.pow = pow;
exports.powerSet = powerSet;
exports.ppcm = ppcm;
exports.preload = preload;
exports.prod = prod;
exports.quote = quote;
exports.rad2deg = rad2deg;
exports.radio = radio;
exports.removeExtraSpace = removeExtraSpace;
exports.round = round;
exports.s = s;
exports.sTags = sTags;
exports.search = search;
exports.sec = sec;
exports.select = select;
exports.sig = sig;
exports.sign = sign;
exports.sin = sin;
exports.sinc = sinc;
exports.sinh = sinh;
exports.slider = slider;
exports.sqrt = sqrt;
exports.sqrtn = sqrtn;
exports.str = str;
exports.sub = sub;
exports.subSet = subSet;
exports.subText = subText;
exports.sum = sum;
exports.supText = supText;
exports.svg2ascii = svg2ascii;
exports.svg2img = svg2img;
exports.svg2imgUrl = svg2imgUrl;
exports.svg2str = svg2str;
exports.tags = tags;
exports.tan = tan;
exports.tanh = tanh;
exports.text = text;
exports.textarea = textarea;
exports.timeTaken = timeTaken;
exports.time_memory_Taken = time_memory_Taken;
exports.ul = ul;
exports.useAnimation = useAnimation;
exports.useChannel = useChannel;
exports.useCustomEvent = useCustomEvent;
exports.useEventEmitter = useEventEmitter;
exports.useFavIcon = useFavIcon$1;
exports.useFps = useFps;
exports.useHashEvent = useHashEvent;
exports.useHead = useHead$1;
exports.useInputEvent = useInputEvent;
exports.useLocaleStorage = useLocaleStorage;
exports.useMediaQuery = useMediaQuery;
exports.useMeta = useMeta$1;
exports.useRoot = useRoot;
exports.useRootValue = useRootValue;
exports.useSessionStorage = useSessionStorage;
exports.useStyle = useStyle;
exports.useSuccesifKeys = useSuccesifKeys;
exports.useSwipeEvent = useSwipeEvent;
exports.useThread = useThread;
exports.useTimeLoop = useTimeLoop;
exports.useTitle = useTitle$1;
exports.video = video;
exports.wait = wait;
exports.waitForUIElm = waitForUIElm;
exports.waitForUIElmSync = waitForUIElmSync;
exports.watch = watch;
exports.watchAttr = watchAttr;
exports.watchChildren = watchChildren;
exports.watchIntersection = watchIntersection;
exports.watchScreen = watchScreen;
exports.watchSize = watchSize;
exports.zeros = zeros;