//为HTMLDocument类的原型添加一个φ方法用于获取元素对象
HTMLDocument.prototype.φ = function (str) {
    return this.querySelector(str);
  };
  function φ(str) {
    return document.φ(str);
  }
  HTMLElement.prototype.φ= function(str){
    return this.querySelector(str);
  }

let ColorToolKit={
    HSBToRGB: function (hsb) {
        var rgb = {};
        var h = Math.round(hsb.h);
        var s = Math.round(hsb.s * 255 / 100);
        var v = Math.round(hsb.b * 255 / 100);

        if (s == 0) {
            rgb.r = rgb.g = rgb.b = v;
        } else {
            var t1 = v;
            var t2 = (255 - s) * v / 255;
            var t3 = (t1 - t2) * (h % 60) / 60;
            if (h == 360) h = 0;
            // console.log(h)
            if (h < 60) {
                rgb.r = t1;
                rgb.b = t2;
                rgb.g = t2 + t3
            } else if (h < 120) { 
                rgb.g = t1;
                rgb.b = t2;
                rgb.r = t1 - t3
            } else if (h < 180) {
                rgb.g = t1;
                rgb.r = t2;
                rgb.b = t2 + t3
            } else if (h < 240) {
                rgb.b = t1;
                rgb.r = t2;
                rgb.g = t1 - t3
            } else if (h < 300) {
                rgb.b = t1;
                rgb.g = t2;
                rgb.r = t2 + t3
            } else if (h < 360) {
                rgb.r = t1;
                rgb.g = t2;
                rgb.b = t1 - t3
            } else {
                rgb.r = 0;
                rgb.g = 0;
                rgb.b = 0
            }
        }
        return {r: Math.round(rgb.r), g: Math.round(rgb.g), b: Math.round(rgb.b)};
    },
    rgbToHex: function (rgb) {
        var hex = [
            rgb.r.toString(16),
            rgb.g.toString(16), 
            rgb.b.toString(16)
        ];
        hex.map(function (str, i) {
            if (str.length == 1) {
                hex[i] = '0' + str;
            }
        });
        return hex.join('');
    },
    HsbToHex:function(hsb){
        return this.rgbToHex(this.HSBToRGB(hsb))
    },
    hexToRgb: function (hex) {
        var hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16);
        return {r: hex >> 16, g: (hex & 0x00FF00) >> 8, b: (hex & 0x0000FF)};
    },
    hexToHsb: function (hex) {
        return this.rgbToHsb(this.hexToRgb(hex));
    },
    rgbToHsb: function (rgb) {
        var hsb = {h: 0, s: 0, b: 0};
        var min = Math.min(rgb.r, rgb.g, rgb.b);
        var max = Math.max(rgb.r, rgb.g, rgb.b);
        var delta = max - min;
        hsb.b = max;
        hsb.s = max != 0 ? 255 * delta / max : 0;
        if (hsb.s != 0) {
            if (rgb.r == max) hsb.h = (rgb.g - rgb.b) / delta;
            else if (rgb.g == max) hsb.h = 2 + (rgb.b - rgb.r) / delta;
            else hsb.h = 4 + (rgb.r - rgb.g) / delta;
        } else hsb.h = -1;
        hsb.h *= 60;
        if (hsb.h < 0) hsb.h += 360;
        hsb.s *= 100 / 255;
        hsb.b *= 100 / 255;
        return hsb;
    },
    HsvToRgb:function(arr) {
        var h = arr.h ,s = arr.s, v = arr.b;
        s = s / 100;
        v = v / 100;
        var r = 0, g = 0, b = 0;
        var i = parseInt((h / 60) % 6);
        var f = h / 60 - i;
        var p = v * (1 - s);
        var q = v * (1 - f * s);
        var t = v * (1 - (1 - f) * s);
        switch (i) {
            case 0:
                r = v; g = t; b = p;
                break;
            case 1:
                r = q; g = v; b = p;
                break;
            case 2:
                r = p; g = v; b = t;
                break;
            case 3:
                r = p; g = q; b = v;
                break;
            case 4:
                r = t; g = p; b = v;
                break;
            case 5:
                r = v; g = p; b = q;
                break;
            default:
                break;
        }
        r = parseInt(r * 255.0)
        g = parseInt(g * 255.0)
        b = parseInt(b * 255.0)
        return {r, g, b};
    },
    RgbToHsv:function(rgb){
        r=rgb.r/255;
        g=rgb.g/255;
        b=rgb.b/255;
        var h,s,v;
        var min=Math.min(r,g,b);
        var max=v=Math.max(r,g,b);
        var l=(min+max)/2;
        var difference = max-min;
        
        if(max==min){
            h=0;
        }else{
            switch(max){
                case r: h=(g-b)/difference+(g < b ? 6 : 0);break;
                case g: h=2.0+(b-r)/difference;break;
                case b: h=4.0+(r-g)/difference;break;
            }
            h=Math.round(h*60);
        }
        if(max==0){
            s=0;
        }else{
            s=1-min/max;
        }
        s=Math.round(s*100);
        v=Math.round(v*100);
        return {h:h,s:s,v:v};
    }
} 

//弧形进度条触发事件重定义(适配移动端)
const on =
  "ontouchstart" in document
    ? {
        start: "touchstart",
        move: "touchmove",
        end: "touchend",
        Start: "ontouchstart",
        Move: "ontouchmove",
        End: "ontouchend",
        Hover:"ontouchmove",
      }
    : {
        start: "mousedown",
        move: "mousemove",
        end: "mouseup",
        Start: "onmousedown",
        Move: "onmousemove",
        End: "onmouseup",
        Hover: "onmouseover",
      };
//删除一个页面元素的方法
function removeElement(_element) {
    if (!_element) return;
    const _parentElement = _element.parentNode;
    if (_parentElement) {
      _parentElement.removeChild(_element);
    }
  }
// 获取视频封面的一个方法
const getVideoPreviewImg = (url, width, height) => {
    width = width || 90;
    height = height || 90;
    /* 创建视频dom节点 */
    let node = document.createElement("video");
    // node.muted=true;
    node.style.width = `${width}px`;
    node.style.height = `${height}px`;
    /* 自动播放 */
    node.autoplay = true;
    node.src = url;
    node.volume=0.01;
    node.currentTime=1;
    node.setAttribute("crossOrigin", "anonymous");
    /* 创建canvas节点 */
    let canvasNode = document.createElement("canvas");
    canvasNode.width = width;
    canvasNode.height = height;
    const canvasFill = canvasNode.getContext("2d");
    canvasFill.drawImage(node, 0, 0, canvasNode.width, canvasNode.height);
    /* 把视频变成canvas */
    return new Promise(resolve => {
      node.onplaying = () => {
        setTimeout(() => {
          canvasFill.drawImage(node, 0, 0, canvasNode.width, canvasNode.height);
          /* 把canvas变成图片 */
          const imgSrc = canvasNode.toDataURL("image/jpeg");
          node.pause();
          removeElement(node);
          resolve(imgSrc);
        }, 100);
      };
    });
  };
  //注册快捷键的类
  class HotKeyHandler {
    constructor(MainKey, SubKey, func) {
    this.currentMainKey= null;
    this.currentSubKey=SubKey;
    this.func=func;  
    this.MKeycode = "";
      switch (MainKey) {
        case 0:
          this.MKeycode = 17; //Ctrl
          break;
        case 1:
        this.MKeycode  = 16; //Shift
          break;
        case 2:
        this.MKeycode = 18; //Alt
          break;
      }
      document.addEventListener('keyup',(evnt)=>{
          if(evnt.keyCode==this.MKeycode){
              this.currentMainKey = null;
        } 
      })
      document.addEventListener('keydown',(evnt)=>{
          //获取键值
          var keyCode = evnt.keyCode;
        var keyValue = String.fromCharCode(evnt.keyCode);
              if (this.currentMainKey != null) {
          if (keyValue ==  this.currentSubKey) {
        //   this.currentMainKey = null;
            if (this.func != null) 
            this.func();
          }
        }
        if (keyCode == this.MKeycode) this.currentMainKey = keyCode;
      }
      ) 
    }
  }
// 深度克隆一个对象Q
//深复制对象方法    
 function cloneObj (obj) {  
    var newObj = {};
    if (obj instanceof Array) {
        newObj = [];  
    }  
    for (var key in obj) {  
        var val = obj[key];  
        newObj[key] = typeof val === 'object' ? cloneObj(val): val;  
    }  
    return newObj;  
}
//忽略方法的深复制对象
function JsonClone(obj){
    Ignores=obj.Ignores?obj.Ignores:[];
    var cache = [];
    return JSON.parse(JSON.stringify(obj,function(key, value) {
                    if (Ignores.indexOf(key)!=-1){return;}
                    if (typeof value === 'object' && value !== null) {
                        if (cache.indexOf(value) !== -1) {
                            // Circular reference found, discard key
                            return;
                        }
                        // Store value in our collection
                        cache.push(value);
                    }
                    return value;
                }));
}
function CoordinatE(e){
    return e=isNaN(e.pageX)?e.targetTouches[0]:e
}

function overwrite_css(selector,properties){ 
    // selector: String CSS Selector
    // properties: Array of objects
    var new_css = selector + '{';
    
    for(i=0;i<properties.length;i++){
    
    new_css += properties[i].p + ':' + properties[i].v + ';';
    
    }
    
    new_css += '}';
    
    φ('body').appendChild('<style>' + new_css + '</style>');
}

function PrefixInteger(num, length,Slice) {
    if(Slice){
        return (Array(length).join('0') + num).slice(-length);
    }else{
        return (Array(length).join('0') + num).slice(Number((""+num)[0])>0&&(""+num).length>length?-(""+num).length:-length);
    }
   }
//var { ...obj2 } = obj 这是一个扩展运算符浅层拷贝

/**
 * 时间轴动画封装
 * @param obj 移动对象
 * @param target 移动目标位置
 * @param timeout 每次移动间隔
 */
//  function animate(obj, target, timeout,callback) {
//     // 清空已有的定时器
//     clearInterval(obj.timer);
//     // 为每个对象开辟一个定时器
//     obj.timer = setInterval(function () {
//         // 移动步长
//         var step = (target - obj.offsetLeft) / 10;
//         // 判断是否为前进还是后退
//         step = step > 0? Math.ceil(step): Math.floor(step);
//         console.log('step = ' + step);
//         if (obj.offsetLeft == target) {
//             clearInterval(obj.timer);
//             // 改变状态
//            if (callback) {
//                callback();
//            }
//         }
//         obj.style.left = obj.offsetLeft + step + 'px';
//     },timeout)
// }代理人战争也不过是宗主国认同了代理的思想
// // 有思想就会有财富，


// server {
//     listen 80;
//     server_name pay.jueqing.com;

//     # 如果用户访问 http://pay.jueqing.com，会重定向到 https://pay.jueqing.com
//     return 301 https://$server_name$request_uri;
// }

// server {
//     listen 443 ssl;
//     server_name pay.jueqing.com;

//     # SSL 证书配置
//     ssl_certificate /psycheEpic/https_auth/CA/pay.jueqing.chat.key;
//     ssl_certificate_key /psycheEpic/https_auth/CA/pay.jueqing.chat.pem;

//     # 可以添加其他 SSL 配置来提高安全性，例如：
//     ssl_protocols TLSv1.2 TLSv1.3;
//     ssl_ciphers HIGH:!aNULL:!MD5;

//     # 定义根位置
//     location / {
//         proxy_pass http://127.0.0.1:9999;

//         # 以下配置可以根据需要进行调整
//         proxy_set_header Host $host;
//         proxy_set_header X-Real-IP $remote_addr;
//         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
//         proxy_set_header X-Forwarded-Proto $scheme;
//     }

//     # 可选：为静态资源的位置提供优化配置
//     # location /static/ {
//     #     alias /path/to/static/files/;
//     # }

//     # 其他位置定义
//     # location /some/other/location {
//     #     proxy_pass http://some_other_backend;
//     # }
// }