jc-structure 0.1.19 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/jc-structure.js +567 -434
- package/dist/jc-structure.umd.cjs +2 -2
- package/index.d.ts +281 -53
- package/package.json +1 -1
- package/types/string.extensions.d.ts +0 -93
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(
|
|
2
|
-
`;return t}}class y{_data;static zero(t){return new y(...Array(t).fill(0))}constructor(...t){this._data=t}get dimension(){return this._data.length}get norm(){return Math.hypot(...this._data)}getItem(t){return this._data[t]}normalize(){const t=this.norm;if(t===0)throw new Error("Cannot normalize a zero vector");const e=this._data.map(s=>s/t);return new y(...e)}add(t){if(this.dimension!==t.dimension)throw new Error("Vectors must have the same dimension to add");const e=this._data.map((s,i)=>s+t._data[i]);return new y(...e)}sub(t){if(this.dimension!==t.dimension)throw new Error("Vectors must have the same dimension to subtract");const e=this._data.map((s,i)=>s-t._data[i]);return new y(...e)}mul(t){return new y(...this._data.map(e=>e*t))}dot(t){if(this.dimension!==t.dimension)throw new Error("Vectors must have the same dimension to dot product");return this._data.reduce((e,s,i)=>e+s*t._data[i],0)}pos(){return this.mul(1)}neg(){return this.mul(-1)}}class I{_matrix;static zero(t,e){return new I(Array.from({length:t},()=>Array.from({length:e},()=>0)))}static rotate(t){const e=t.length;for(let s=0;s<(e+1)/2;s++)for(let i=s;i<e/2;i++){const n=t[e-1-i][s];t[e-1-i][s]=t[e-1-s][e-1-i],t[e-1-s][e-1-i]=t[i][e-1-s],t[i][e-1-s]=t[s][i],t[s][i]=n}return t}constructor(t){this._matrix=t}get shape(){return[this._matrix.length,this._matrix[0].length]}get row(){return this.shape[0]}get col(){return this.shape[1]}get size(){return this.row*this.col}rowVector(t){return new y(...this._matrix[t])}colVector(t){return new y(...this._matrix.map(e=>e[t]))}getItem(t){return this._matrix[t[0]][t[1]]}setItem(t,e){return this._matrix[t[0]][t[1]]=e,this}mul(t){return new I(this._matrix.map(e=>e.map(s=>s*t)))}div(t){return this.mul(1/t)}add(t){if(this.row!==t.row||this.col!==t.col)throw new Error("Matrix dimensions do not match");return new I(this._matrix.map((e,s)=>e.map((i,n)=>i+t.getItem([s,n]))))}sub(t){return this.add(t.neg())}pos(){return this.mul(1)}neg(){return this.mul(-1)}mulVector(t){if(this.col!==t.dimension)throw new Error("Matrix dimensions do not match");return new I(this._matrix.map(e=>e.map((s,i)=>s*t.getItem(i))))}mulMatrix(t){if(this.col!==t.row)throw new Error("Matrix dimensions do not match");const e=I.zero(this.row,t.col);for(let s=0;s<this.row;s++){const i=this.rowVector(s);for(let n=0;n<this.col;n++)e.setItem([s,n],i.dot(t.colVector(n)))}return e}}class u{static distance(t,e){return Math.hypot(e.x-t.x,e.y-t.y)}x;y;constructor(t,e){this.x=t,this.y=e}distanceTo(t){return u.distance(this,t)}}class f{static EPSILON=1e-10;static sloped(t,e=f.EPSILON){const s=t.p2.x-t.p1.x,i=t.p2.y-t.p1.y;return Math.abs(s)<e?Math.abs(i)<e?0:null:i/s}static isParallel(t,e,s=f.EPSILON){const i=f.sloped(t),n=f.sloped(e);return i===null&&n===null?!0:i===null||n===null?!1:Math.abs(i-n)<s}static getIntersection(t,e,s=f.EPSILON){if(f.isParallel(t,e))return null;const i=t.p1.x,n=t.p1.y,a=t.p2.x,l=t.p2.y,d=e.p1.x,g=e.p1.y,w=e.p2.x,o=e.p2.y,p=(i-a)*(g-o)-(n-l)*(d-w);if(Math.abs(p)<s)return null;const m=((i-d)*(g-o)-(n-g)*(d-w))/p,b=-((i-a)*(n-g)-(n-l)*(i-d))/p;if(m>=0&&m<=1&&b>=0&&b<=1){const Z=i+m*(a-i),J=n+m*(l-n);return new u(Z,J)}return null}static isIntersecting(t,e){return f.getIntersection(t,e)!==null}static distanceToPoint(t,e,s=f.EPSILON){const i=e.x-t.p1.x,n=e.y-t.p1.y,a=t.p2.x-t.p1.x,l=t.p2.y-t.p1.y,d=i*a+n*l,g=a*a+l*l;let w=-1;g>s&&(w=d/g);let o,p;w<0?(o=t.p1.x,p=t.p1.y):w>1?(o=t.p2.x,p=t.p2.y):(o=t.p1.x+w*a,p=t.p1.y+w*l);const m=e.x-o,b=e.y-p;return Math.hypot(m+b)}p1;p2;constructor(t,e){this.p1=t,this.p2=e}get length(){const t=this.p2.x-this.p1.x,e=this.p2.y-this.p1.y;return Math.sqrt(t*t+e*e)}get midpoint(){const t=(this.p1.x+this.p2.x)/2,e=(this.p1.y+this.p2.y)/2;return new u(t,e)}get angle(){return Math.atan2(this.p2.y-this.p1.y,this.p2.x-this.p1.x)}containsPoint(t,e=f.EPSILON){const s=(t.x-this.p1.x)*(this.p2.y-this.p1.y)-(t.y-this.p1.y)*(this.p2.x-this.p1.x);return Math.abs(s)>e?!1:(t.x-this.p1.x)*(t.x-this.p2.x)+(t.y-this.p1.y)*(t.y-this.p2.y)<=e}get direction(){const t=this.length;if(t<f.EPSILON)return new u(0,0);const e=(this.p2.x-this.p1.x)/t,s=(this.p2.y-this.p1.y)/t;return new u(e,s)}get start(){return this.p1}get end(){return this.p2}}class N{static EPSILON=1e-10;name;constructor(t){this.name=t}}class c extends N{static isValid(t,e,s){return t<=0||e<=0||s<=0?!1:t+e>s&&t+s>e&&e+s>t}static area(t,e,s){if(!c.isValid(t,e,s))throw new Error("Invalid triangle");const i=(t+e+s)/2;return Math.sqrt(i*(i-t)*(i-e)*(i-s))}static getType(t,e,s){if(!c.isValid(t,e,s))throw new Error("Invalid triangle sides");const i=[t,e,s].sort((d,g)=>d-g),[n,a,l]=i;return Math.abs(n-a)<c.EPSILON&&Math.abs(a-l)<c.EPSILON?"equilateral":Math.abs(n-a)<c.EPSILON||Math.abs(a-l)<c.EPSILON?"isosceles":"scalene"}static getAngles(t,e,s){if(!c.isValid(t,e,s))throw new Error("Invalid triangle sides");const i=Math.acos((e*e+s*s-t*t)/(2*e*s)),n=Math.acos((t*t+s*s-e*e)/(2*t*s)),a=Math.PI-i-n;return[i,n,a]}p1;p2;p3;constructor(t,e,s,i="triangle"){if(super(i),this.p1=t,this.p2=e,this.p3=s,this.areCollinear())throw new Error("Points are collinear, cannot form a triangle")}areCollinear(){return Math.abs((this.p2.x-this.p1.x)*(this.p3.y-this.p1.y)-(this.p3.x-this.p1.x)*(this.p2.y-this.p1.y))<N.EPSILON}get side(){return[u.distance(this.p1,this.p2),u.distance(this.p2,this.p3),u.distance(this.p3,this.p1)]}perimeter(){return c.isValid(this.side[0],this.side[1],this.side[2]),this.side.reduce((t,e)=>t+e,0)}area(){const[t,e,s]=this.side;return c.area(t,e,s)}get type(){const[t,e,s]=this.side;return c.getType(t,e,s)}get angles(){const[t,e,s]=this.side;return c.getAngles(t,e,s)}get centroid(){return new u((this.p1.x+this.p2.x+this.p3.x)/3,(this.p1.y+this.p2.y+this.p3.y)/3)}get incenter(){const[t,e,s]=this.side,i=this.perimeter()/2,n=(t*this.p1.x+e*this.p2.x+s*this.p3.x)/i,a=(t*this.p1.y+e*this.p2.y+s*this.p3.y)/i;return new u(n,a)}get circumcenter(){const t=2*(this.p1.x*(this.p2.y-this.p3.y)+this.p2.x*(this.p3.y-this.p1.y)+this.p3.x*(this.p1.y-this.p2.y));if(Math.abs(t)<c.EPSILON)throw new Error("Cannot calculate circumcenter for collinear points");const e=((this.p1.x*this.p1.x+this.p1.y*this.p1.y)*(this.p2.y-this.p3.y)+(this.p2.x*this.p2.x+this.p2.y*this.p2.y)*(this.p3.y-this.p1.y)+(this.p3.x*this.p3.x+this.p3.y*this.p3.y)*(this.p1.y-this.p2.y))/t,s=((this.p1.x*this.p1.x+this.p1.y*this.p1.y)*(this.p3.x-this.p2.x)+(this.p2.x*this.p2.x+this.p2.y*this.p2.y)*(this.p1.x-this.p3.x)+(this.p3.x*this.p3.x+this.p3.y*this.p3.y)*(this.p2.x-this.p1.x))/t;return new u(e,s)}containsPoint(t){const e=c.area(u.distance(t,this.p1),u.distance(t,this.p2),u.distance(this.p1,this.p2)),s=c.area(u.distance(t,this.p2),u.distance(t,this.p3),u.distance(this.p2,this.p3)),i=c.area(u.distance(t,this.p3),u.distance(t,this.p1),u.distance(this.p3,this.p1));return Math.abs(e+s+i-this.area())<c.EPSILON}}function _(r){return new Promise(t=>setTimeout(t,r))}function H(r){const t=[],e={"(":")","[":"]","{":"}"},s=new Set(Object.values(e));for(const i of r)if(i in e)t.push(e[i]);else if(s.has(i)&&i!==t.pop())return!1;return t.length===0}function M(r){return r!==null&&(typeof r=="object"||typeof r=="function")}class T{map=new Map;weakMap=new WeakMap;set(t,e){M(t)?this.weakMap.set(t,e):this.map.set(t,e)}get(t){return M(t)?this.weakMap.get(t):this.map.get(t)}has(t){return M(t)?this.weakMap.has(t):this.map.has(t)}}class B{static ROMAN_MAP=new Map([["M",1e3],["CM",900],["D",500],["CD",400],["C",100],["XC",90],["L",50],["XL",40],["X",10],["IX",9],["V",5],["IV",4],["I",1]]);static toInteger(t){if(t.length===0)throw new Error("Input cannot be empty");const e=new Set(["I","V","X","L","C","D","M"]);for(const a of t)if(!e.has(a))throw new Error(`Invalid Roman numeral character: ${a}`);let s=0,i=0;for(;i<t.length;){const a=t.slice(i,i+2);if(this.ROMAN_MAP.has(a))s+=this.ROMAN_MAP.get(a),i+=2;else{const l=t[i],d=this.ROMAN_MAP.get(l);if(!d)throw new Error(`Invalid Roman numeral sequence at position ${i}`);s+=d,i+=1}}if(this.toRoman(s)!==t)throw new Error("Invalid Roman numeral sequence");return s}static toRoman(t){if(t<=0||t>=4e3)throw new Error("Number must be between 1 and 3999");if(!Number.isInteger(t))throw new Error("Number must be an integer");let e="";for(const[s,i]of this.ROMAN_MAP)for(;t>=i;)e+=s,t-=i;return e}}class F{static isValidPositiveInteger(t){return Number.isInteger(t)&&t>0&&t<=Number.MAX_SAFE_INTEGER}static isPowerOfTwo(t){return t>0&&(t&t-1)===0}static isOdd(t){return t%2===1||t%2===-1}static factorial(t){if(!this.isValidPositiveInteger(t))throw new Error("Input must be a non-negative integer");if(t<2)return 1;let e=1;for(let s=2;s<=t;s++)e*=s;return e}static fibonacci(t,e=1,s=1){if(!this.isValidPositiveInteger(t))throw new Error("Input must be a non-negative integer");return t<2?s:this.fibonacci(t-1,s,s+e)}static fibonacciIterative(t){if(t<2)return t;let e=0,s=1;for(let i=2;i<t;i++)[e,s]=[s,(e+s)%1000000007];return s}static getPercentWithPrecision(t,e=2){if(!Array.isArray(t)||t.length===0)return[];if(e<0||!Number.isInteger(e))throw new Error("Precision must be a non-negative integer");const s=t.reduce((o,p)=>o+p,0);if(s===0)return t.map(()=>"0%");const n=100*Math.pow(10,e),a=t.map(o=>o/s*n),l=a.map(o=>Math.floor(o)),d=a.map((o,p)=>o-l[p]);let g=l.reduce((o,p)=>o+p,0),w=n-g;for(;w>0;){let o=-1,p=-1;for(let m=0;m<d.length;m++)d[m]>p&&(p=d[m],o=m);if(o===-1)break;l[o]++,d[o]=0,w--}return l.map(o=>`${(o/n*100).toFixed(e)}%`)}static fastSqrt(t){if(t<0)throw new Error("n must be a non-negative number");const e=.5*t;let s=new BigInt64Array(new Float32Array([t]).buffer)[0];s=0x1ff7a3bea91d9b1bn+(s>>1n);let i=new Float64Array(new BigInt64Array([s]).buffer)[0];return i=i*.5+e/i,i=i*.5+e/i,i=i*.5+e/i,i}static gcd(t,e){return e===0?t:this.gcd(e,t%e)}static lcm(t,e){return t*e/this.gcd(t,e)}static isPrime(t){if(t<=1)return!1;for(let e=2;e<=Math.sqrt(t);e++)if(t%e===0)return!1;return!0}static isPalindrome(t){if(t<0||t%10===0&&t!==0)return!1;let e=0,s=t;for(;t>0;){const i=t%10;e=e*10+i,t=Math.floor(t/10)}return s===e}static isArmstrong(t){const e=t.toString(),s=e.length;let i=0;for(let n=0;n<s;n++)i+=Math.pow(parseInt(e[n]),s);return i===t}static isHappy(t){const e=new Set;for(;t!==1;){if(e.has(t))return!1;e.add(t),t=(t+"").split("").reduce((s,i)=>s+Number(i)*Number(i),0)}return!0}static isPerfect(t){let e=0;for(let s=1;s<t;s++)t%s===0&&(e+=s);return e===t}static middle(t,e){return e-(e-t>>1)}static scale(t,e,s){if(e[0]>=e[1]||s[0]>=s[1])throw new Error("Invalid range");t=this.clamp(t,e[0],e[1]);const i=e[1]-e[0];return(t-e[0])*((s[1]-s[0])/i)+s[0]}static isRange(t,e,s){if(s==null&&(s=e,e=0),e>=s)throw new Error("The maximum value must be greater than the minimum value");return e<=t&&t<s}static clamp(t,e,s){return s==null?Math.min(t,e):Math.min(Math.max(t,e),s)}static random(t,e){if(e==null&&(e=t,t=0),t>=e)throw new Error("The maximum value must be greater than the minimum value");return Math.random()*(e-t)+t}static randomInt(t,e){return Math.floor(this.random(t,e))}static round(t,e=0){if(!Number.isInteger(e))throw new Error("precision must be an integer");const s=Math.pow(10,e);return Math.round(t*s)/s}static floatEqual(t,e,s=1e-6){return Math.abs(t-e)<s}static isSameSign(t,e){return t>=0&&e>=0||t<=0&&e<=0}static fastPower(t,e){if(t<0)throw new Error("a must be greater than 0");if(e<0||!Number.isInteger(e))throw new Error("n must be a non-negative integer");if(t===0)return 0;if(e===0)return 1;const s=this.fastPower(t,e>>1);return e%2===0?s*s:s*s*t}static consecutiveSum(t){if(!this.isValidPositiveInteger)throw new Error("n must be a positive integer");return t*(t+1)/2}static consecutiveSquaresSum(t){if(!this.isValidPositiveInteger)throw new Error("n must be a positive integer");return t*(t+1)*(2*t+1)/6}static consecutivecubesSum(t){if(!this.isValidPositiveInteger)throw new Error("n must be a positive integer");return t*(t+1)*(2*t+1)*(3*t*t+3*t-1)/30}}class G{static READ=1;static WRITE=2;static SHARE=4;static DELETE=8;static CREATE=16;static include(t,e){return(t&e)===e}static add(t,e){return t|e}static remove(t,e){return t&~e}static toggle(t,e){return t^e}}class Q extends String{static frequencyStatistics(t){return[...t].reduce((e,s)=>(e[s]=(e[s]||0)+1,e),{})}}class X{static isValidHex(t){return/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(t)}static isValidRGB(t){return/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/.test(t)}}function W(r){let t;const e=new Proxy(r,{construct(s,i,n){return t||(t=Reflect.construct(s,i,n)),t}});return r.prototype.constructor=e,e}const x={AUTH_UNAUTHORIZED:"未授权事件",AUTH_LOGIN_SUCCESS:"登录成功事件",AUTH_LOGOUT:"注销事件",AUTH_TOKEN_EXPIRED:"令牌过期事件",REQUEST_ERROR:"请求错误事件",REQUEST_TIMEOUT:"请求超时事件",REQUEST_NETWORK_ERROR:"网络错误事件",UI_SHOW_LOADING:"显示加载事件",UI_HIDE_LOADING:"隐藏加载事件",UI_SHOW_MESSAGE:"显示消息事件"};class v{static instance=null;listeners={};debugMode;constructor(t=!1){this.debugMode=t,Object.keys(x).forEach(e=>{this.listeners[e]=new Set})}static getInstance(t){return v.instance||(v.instance=new v(t)),v.instance}on(t,e){this.debugLog(`添加事件监听: ${x[t]}`),this.listeners[t].add(e)}emit(t,e){this.debugLog(`触发事件: ${x[t]}`,e),this.listeners[t].forEach(s=>{try{s(e)}catch(i){console.error(`事件 ${x[t]} 处理出错:`,i)}})}off(t,e){this.debugLog(`移除事件监听: ${x[t]}`),this.listeners[t].delete(e)}once(t,e){this.debugLog(`添加一次性事件监听: ${x[t]}`);const s=i=>{e(i),this.off(t,s)};this.on(t,s)}clear(){this.debugLog("清除所有事件监听器"),Object.values(this.listeners).forEach(t=>t.clear())}getListenerCount(t){return this.listeners[t].size}debugLog(t,e){this.debugMode&&console.log(`[EventEmitter] ${t}`,e||"")}}function K(r,t,e){let s=-1,i=r.length,n;for(;i-s>1;)n=i-(i-s)>>1,e(r[n],t)?i=n:s=n;return i}String.prototype.pointLength=function(){let r=0;for(let t=0,e=this.length;t<e;){const s=this.codePointAt(t);t+=s>65535?2:1,r++}return r},String.prototype.pointAt=function(r){if(r>=this.pointLength())return;let t=0;for(let e=0,s=this.length;e<s;){const i=this.codePointAt(e);if(!i)return;if(t===r)return String.fromCodePoint(i);e+=i>65535?2:1,t++}},String.prototype.sliceByPoint=function(r,t=this.pointLength()){let e="";for(let s=r;s<t;s++)e+=this.pointAt(s);return e},String.prototype.capitalize=function(){return this?this.charAt(0).toUpperCase()+this.slice(1).toLowerCase():this},String.prototype.reverse=function(){return this.split("").reverse().join("")},String.prototype.truncate=function(r,t="..."){return this.length<=r?this:this.slice(0,r-t.length)+t},String.prototype.isPalindrome=function(){const r=this.toLowerCase().replace(/[^a-z0-9]/g,"");return r===r.reverse()},String.prototype.count=function(r){const t=r.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return(this.match(new RegExp(t,"g"))||[]).length},String.prototype.toCamelCase=function(){return this.replace(/_([a-z])/g,(r,t)=>t.toUpperCase())},String.prototype.toSnakeCase=function(){return this.replace(/[A-Z]/g,r=>`_${r.toLowerCase()}`)},String.prototype.format=function(...r){return this.replace(/{(\d+)}/g,(t,e)=>r[e]||"")};class R{static random(t=8){const e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";let s="";for(let i=0;i<t;i++)s+=e.charAt(Math.floor(Math.random()*e.length));return s}static template(t,e){return t.replace(/\${(\w+)}/g,(s,i)=>e[i]||"")}static escapeHtml(t){const e={"&":"&","<":"<",">":">",'"':""","'":"'"," ":" ","±":"±","×":"×","÷":"÷","≠":"≠","≤":"≤","≥":"≥"},s=new RegExp(`[${Object.keys(e).join("")}]`,"g");return t.replace(s,i=>e[i])}static isEmail(t){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)}static isUrl(t){try{return new URL(t),!0}catch{return!1}}}Object.assign(String,R),h.BitPerm=G,h.Color=X,h.Dictionary=O,h.Emitter=v,h.Graph=$,h.LRU=q,h.Line=f,h.LinkedList=D,h.Matrix=I,h.MaxHeap=z,h.MemoizeMap=T,h.MinHeap=P,h.MinStack=V,h.Num=F,h.Point=u,h.Queue=S,h.Roman=B,h.Stack=C,h.Str=Q,h.StringExtensions=R,h.Triangle=c,h.Vector=y,h.binarySearchTemplate=K,h.isValidBracket=H,h.singleton=W,h.sleep=_,Object.defineProperty(h,Symbol.toStringTag,{value:"Module"})}));
|
|
1
|
+
(function(c,v){typeof exports=="object"&&typeof module<"u"?v(exports):typeof define=="function"&&define.amd?define(["exports"],v):(c=typeof globalThis<"u"?globalThis:c||self,v(c["jc-structure"]={}))})(this,(function(c){"use strict";class v{items={};count=0;lowestCount=0;constructor(){}dequeue(){if(this.isEmpty())return;const t=this.items[this.lowestCount];return delete this.items[this.lowestCount],this.lowestCount++,t}enqueue(...t){if(t.length===0)return this;if(t.length===1){const e=t[0];return Array.isArray(e)?this.batchEnqueue(e):this.enqueueItem(e)}for(const e of t)Array.isArray(e)?this.batchEnqueue(e):this.enqueueItem(e);return this}batchEnqueue(t){return t.filter(s=>this.isValidItem(s)).forEach(s=>{this.isValidItem(s)&&(this.items[this.count]=s,this.count++)}),this}enqueueItem(t){if(!this.isValidItem(t))throw new Error("Invalid item");return this.items[this.count]=t,this.count++,this}isValidItem(t){return t!=null}front(){return this.isEmpty()?void 0:this.items[this.lowestCount]}isEmpty(){return this.size()===0}size(){return this.count-this.lowestCount}clear(){this.items={},this.count=0,this.lowestCount=0}toString(){return this.isEmpty()?"":`Queue(size: ${this.size()}):[${this.items[this.lowestCount]},...rest]`}}class ${items={};count=0;constructor(){}pop(){if(this.isEmpty())return;this.count--;const t=this.items[this.count];return delete this.items[this.count],t}push(...t){if(t.length===0)return this;if(t.length===1){const e=t[0];return Array.isArray(e)?this.addItems(e):this.addItem(e)}for(const e of t)Array.isArray(e)?this.addItems(e):this.addItem(e);return this}addItem(t){if(!this.isValidItem(t))throw new Error("Invalid item: item cannot be null or undefined");return this.items[this.count]=t,this.count++,this}addItems(t){return t.filter(s=>this.isValidItem(s)).forEach(s=>{this.items[this.count]=s,this.count++}),this}isValidItem(t){return t!=null}peek(){return this.isEmpty()?void 0:this.items[this.count-1]}isEmpty(){return this.count===0}size(){return this.count}clear(){this.items={},this.count=0}toString(){return this.isEmpty()?"":`Stack(count: ${this.count}):[${this.items[this.count-1]},...rest]`}}class H{stack=[];minStack=[];push(t){this.stack.push(t),(this.minStack.length===0||t<=this.minStack[this.minStack.length-1])&&this.minStack.push(t)}pop(){const t=this.stack.pop();return t===this.minStack[this.minStack.length-1]&&this.minStack.pop(),t}peek(){return this.stack[this.stack.length-1]}getMin(){return this.minStack[this.minStack.length-1]}isEmpty(){return this.size()===0}size(){return this.stack.length}clear(){this.stack=[],this.minStack=[]}toString(){return this.isEmpty()?"":`MinStack(count: ${this.size()}):[${this.getMin()},...rest]`}}function R(h,t){return h===t?0:h<t?-1:1}class I{heap=[];compareFn;constructor(t=R){this.compareFn=t}static getLeftIndex(t){return 2*t+1}static getRightIndex(t){return 2*t+2}static getParentIndex(t){return t===0?void 0:Math.floor((t-1)/2)}static swap(t,e,s){[t[e],t[s]]=[t[s],t[e]]}find(){return this.isEmpty()?void 0:this.heap[0]}size(){return this.heap.length}isEmpty(){return this.size()===0}clear(){this.heap=[]}toString(){return this.heap.toString()}}class P extends I{insert(t){return t?!1:(this.heap.push(t),this.siftUp(this.heap.length-1),!0)}extract(){if(this.isEmpty())return;if(this.heap.length===1)return this.heap.shift();const t=this.heap[0];return this.heap[0]=this.heap.pop(),this.siftDown(0),t}siftUp(t){let e=t,s=I.getLeftIndex(e),r=I.getRightIndex(e),i=this.size();s<i&&this.compareFn(this.heap[e],this.heap[s])===-1&&(e=s),r<i&&this.compareFn(this.heap[e],this.heap[r])===1&&(e=r),e!==t&&(I.swap(this.heap,t,e),this.siftUp(e))}siftDown(t){let e=I.getParentIndex(t);for(;t>0&&e&&this.compareFn(this.heap[e],this.heap[t])===1;)I.swap(this.heap,e,t),t=e,e=I.getParentIndex(t)}}class V extends P{constructor(t=(e,s)=>R(s,e)){super(t)}}function D(h){return{value:h}}class U{capacity;length=0;head=null;tail=null;lookup=new Map;reverseLookup=new Map;constructor(t=10){this.capacity=t}prepend(t){this.head?(t.next=this.head,this.head.prev=t,this.head=t):this.head=this.tail=t}detach(t){t.prev&&(t.prev.next=t.next),t.next&&(t.next.prev=t.prev),this.head===t&&(this.head=this.head.next||null),this.tail===t&&(this.tail=this.tail.prev||null),t.next=void 0,t.prev=void 0}trimCache(){if(this.length<=this.capacity)return;const t=this.tail;this.detach(t);const e=this.reverseLookup.get(t);this.lookup.delete(e),this.reverseLookup.delete(t),this.length--}get(t){const e=this.lookup.get(t);if(e)return this.detach(e),this.prepend(e),e.value}update(t,e){let s=this.lookup.get(t);s?(this.detach(s),this.prepend(s),s.value=e):(s=D(e),this.length++,this.prepend(s),this.trimCache(),this.lookup.set(t,s),this.reverseLookup)}}class k{value;next=void 0}class q{count=0;head=void 0;constructor(){}indexOf(t){let e=this.head,s=0,r=!1;for(;e;){if(this.equals(e.value,t)){r=!0;break}s++,e=e.next}return r?s:-1}equals(t,e){return t===e?!0:t==null||e==null?!1:typeof t=="object"&&typeof e=="object"?JSON.stringify(t)===JSON.stringify(e):!1}getElementAt(t){if(t<0||t>=this.count)return;if(t===0)return this.head;let e=this.head;for(let s=0;s<t;s++)e=e?.next;return e}getValueAt(t){return this.getElementAt(t)?.value}insert(t,e){let s=new k;if(s.value=t,e>this.count||e<0)throw new Error("index error");this.count++;let r,i;if(e===0){s.next=this.head,this.head=s;return}r=this.getElementAt(e-1),i=r.next,r.next=s,s.next=i}push(t){let e=new k;if(e.value=t,this.count++,this.isEmpty()){this.head=e;return}let s=this.getElementAt(this.count-1);s.next=e}remove(t){const e=this.indexOf(t);return e===-1?void 0:this.removeAt(e)}removeAt(t){if(this.isEmpty()||t<0||t>=this.count)return;let e=this.getElementAt(t),s=this.getElementAt(t-1),r=e?.next;return t===0&&(this.head=r),s&&(s.next=r),this.count--,e?.value}isEmpty(){return this.count===0}size(){return this.count}clear(){this.count=0,this.head=void 0}toString(){let t="",e=this.head;for(;e;)t+=e.value,t+=",",e=e.next;return t=t.slice(0,-1),t}}class T{key;value;constructor(t,e){this.key=t,this.value=e}}function N(h,t={emptyString:!1,zeroNumber:!1}){return h==null?!(t.emptyString&&h===""||t.zeroNumber&&h===0):!1}class L{table=[];constructor(){}getItemIndex(t){for(let e=0,s=this.table.length;e<s;e++)if(this.table[e].key===t)return e;return-1}set(t,e){if(N(t))throw new Error("key is required");if(N(e))throw new Error("value is required");if(this.has(t)){let s=this.getItemIndex(t);this.table[s].value=e}else{const s=new T(t,e);this.table.push(s)}}remove(t){if(this.has(t)){let e=this.getItemIndex(t);return this.table.splice(e,1)[0]}}has(t){return this.getItemIndex(t)!==-1}get(t){if(this.has(t)){let e=this.getItemIndex(t);return this.table[e]}}keys(){return this.table.map(t=>t.key)}values(){return this.table.map(t=>t.value)}keyValues(){return this.table.map(t=>[t.key,t.value])}forEach(t){for(let e=0,s=this.size();e<s;e++){let r=this.table[e];if(!t(r.key,r.value))break}}isEmpty(){return!this.size()}size(){return this.table.length}clear(){this.table=[]}toString(){let t="";for(let e=0,s=this.table.length;e<s;e++)t+=this.table[e].toString(),t+=",";return t=t.slice(0,-1),t}}class F{isDirected;vertices;adjList;constructor(t=!1){this.isDirected=t,this.vertices=[],this.adjList=new L}addVertex(t){this.vertices.includes(t)||(this.vertices.push(t),this.adjList.set(t,[]))}addEdge(t,e){this.adjList.get(t)||this.addVertex(t),this.adjList.get(e)||this.addVertex(e),this.adjList.get(t)?.value.indexOf(e)===-1&&this.adjList.get(t)?.value.push(e),this.isDirected||this.adjList.get(e)?.value.indexOf(t)===-1&&this.adjList.get(e)?.value.push(t)}getVertices(){return this.vertices}getAdjacencyList(){return this.adjList}toString(){let t="";for(let e=0;e<this.vertices.length;e++)t+=this.vertices[e]+"-->",t+=this.adjList.get(this.vertices[e])?.toString()||"",t+=`
|
|
2
|
+
`;return t}}class E{_data;static zero(t){return new E(...Array(t).fill(0))}constructor(...t){this._data=t}get dimension(){return this._data.length}get norm(){return Math.hypot(...this._data)}getItem(t){return this._data[t]}normalize(){const t=this.norm;if(t===0)throw new Error("Cannot normalize a zero vector");const e=this._data.map(s=>s/t);return new E(...e)}add(t){if(this.dimension!==t.dimension)throw new Error("Vectors must have the same dimension to add");const e=this._data.map((s,r)=>s+t._data[r]);return new E(...e)}sub(t){if(this.dimension!==t.dimension)throw new Error("Vectors must have the same dimension to subtract");const e=this._data.map((s,r)=>s-t._data[r]);return new E(...e)}mul(t){return new E(...this._data.map(e=>e*t))}dot(t){if(this.dimension!==t.dimension)throw new Error("Vectors must have the same dimension to dot product");return this._data.reduce((e,s,r)=>e+s*t._data[r],0)}pos(){return this.mul(1)}neg(){return this.mul(-1)}}class M{_matrix;static zero(t,e){return new M(Array.from({length:t},()=>Array.from({length:e},()=>0)))}static rotate(t){const e=t.length;for(let s=0;s<(e+1)/2;s++)for(let r=s;r<e/2;r++){const i=t[e-1-r][s];t[e-1-r][s]=t[e-1-s][e-1-r],t[e-1-s][e-1-r]=t[r][e-1-s],t[r][e-1-s]=t[s][r],t[s][r]=i}return t}constructor(t){this._matrix=t}get shape(){return[this._matrix.length,this._matrix[0].length]}get row(){return this.shape[0]}get col(){return this.shape[1]}get size(){return this.row*this.col}rowVector(t){return new E(...this._matrix[t])}colVector(t){return new E(...this._matrix.map(e=>e[t]))}getItem(t){return this._matrix[t[0]][t[1]]}setItem(t,e){return this._matrix[t[0]][t[1]]=e,this}mul(t){return new M(this._matrix.map(e=>e.map(s=>s*t)))}div(t){return this.mul(1/t)}add(t){if(this.row!==t.row||this.col!==t.col)throw new Error("Matrix dimensions do not match");return new M(this._matrix.map((e,s)=>e.map((r,i)=>r+t.getItem([s,i]))))}sub(t){return this.add(t.neg())}pos(){return this.mul(1)}neg(){return this.mul(-1)}mulVector(t){if(this.col!==t.dimension)throw new Error("Matrix dimensions do not match");return new M(this._matrix.map(e=>e.map((s,r)=>s*t.getItem(r))))}mulMatrix(t){if(this.col!==t.row)throw new Error("Matrix dimensions do not match");const e=M.zero(this.row,t.col);for(let s=0;s<this.row;s++){const r=this.rowVector(s);for(let i=0;i<this.col;i++)e.setItem([s,i],r.dot(t.colVector(i)))}return e}}class l{static distance(t,e){return Math.hypot(e.x-t.x,e.y-t.y)}x;y;constructor(t,e){this.x=t,this.y=e}distanceTo(t){return l.distance(this,t)}}class g{static EPSILON=1e-10;static sloped(t,e=g.EPSILON){const s=t.p2.x-t.p1.x,r=t.p2.y-t.p1.y;return Math.abs(s)<e?Math.abs(r)<e?0:null:r/s}static isParallel(t,e,s=g.EPSILON){const r=g.sloped(t),i=g.sloped(e);return r===null&&i===null?!0:r===null||i===null?!1:Math.abs(r-i)<s}static getIntersection(t,e,s=g.EPSILON){if(g.isParallel(t,e))return null;const r=t.p1.x,i=t.p1.y,n=t.p2.x,a=t.p2.y,o=e.p1.x,f=e.p1.y,m=e.p2.x,u=e.p2.y,p=(r-n)*(f-u)-(i-a)*(o-m);if(Math.abs(p)<s)return null;const y=((r-o)*(f-u)-(i-f)*(o-m))/p,O=-((r-n)*(i-f)-(i-a)*(r-o))/p;if(y>=0&&y<=1&&O>=0&&O<=1){const Y=r+y*(n-r),K=i+y*(a-i);return new l(Y,K)}return null}static isIntersecting(t,e){return g.getIntersection(t,e)!==null}static distanceToPoint(t,e,s=g.EPSILON){const r=e.x-t.p1.x,i=e.y-t.p1.y,n=t.p2.x-t.p1.x,a=t.p2.y-t.p1.y,o=r*n+i*a,f=n*n+a*a;let m=-1;f>s&&(m=o/f);let u,p;m<0?(u=t.p1.x,p=t.p1.y):m>1?(u=t.p2.x,p=t.p2.y):(u=t.p1.x+m*n,p=t.p1.y+m*a);const y=e.x-u,O=e.y-p;return Math.hypot(y+O)}p1;p2;constructor(t,e){this.p1=t,this.p2=e}get length(){const t=this.p2.x-this.p1.x,e=this.p2.y-this.p1.y;return Math.sqrt(t*t+e*e)}get midpoint(){const t=(this.p1.x+this.p2.x)/2,e=(this.p1.y+this.p2.y)/2;return new l(t,e)}get angle(){return Math.atan2(this.p2.y-this.p1.y,this.p2.x-this.p1.x)}containsPoint(t,e=g.EPSILON){const s=(t.x-this.p1.x)*(this.p2.y-this.p1.y)-(t.y-this.p1.y)*(this.p2.x-this.p1.x);return Math.abs(s)>e?!1:(t.x-this.p1.x)*(t.x-this.p2.x)+(t.y-this.p1.y)*(t.y-this.p2.y)<=e}get direction(){const t=this.length;if(t<g.EPSILON)return new l(0,0);const e=(this.p2.x-this.p1.x)/t,s=(this.p2.y-this.p1.y)/t;return new l(e,s)}get start(){return this.p1}get end(){return this.p2}}class C{static EPSILON=1e-10;name;constructor(t){this.name=t}}class d extends C{static isValid(t,e,s){return t<=0||e<=0||s<=0?!1:t+e>s&&t+s>e&&e+s>t}static area(t,e,s){if(!d.isValid(t,e,s))throw new Error("Invalid triangle");const r=(t+e+s)/2;return Math.sqrt(r*(r-t)*(r-e)*(r-s))}static getType(t,e,s){if(!d.isValid(t,e,s))throw new Error("Invalid triangle sides");const r=[t,e,s].sort((o,f)=>o-f),[i,n,a]=r;return Math.abs(i-n)<d.EPSILON&&Math.abs(n-a)<d.EPSILON?"equilateral":Math.abs(i-n)<d.EPSILON||Math.abs(n-a)<d.EPSILON?"isosceles":"scalene"}static getAngles(t,e,s){if(!d.isValid(t,e,s))throw new Error("Invalid triangle sides");const r=Math.acos((e*e+s*s-t*t)/(2*e*s)),i=Math.acos((t*t+s*s-e*e)/(2*t*s)),n=Math.PI-r-i;return[r,i,n]}p1;p2;p3;constructor(t,e,s,r="triangle"){if(super(r),this.p1=t,this.p2=e,this.p3=s,this.areCollinear())throw new Error("Points are collinear, cannot form a triangle")}areCollinear(){return Math.abs((this.p2.x-this.p1.x)*(this.p3.y-this.p1.y)-(this.p3.x-this.p1.x)*(this.p2.y-this.p1.y))<C.EPSILON}get side(){return[l.distance(this.p1,this.p2),l.distance(this.p2,this.p3),l.distance(this.p3,this.p1)]}perimeter(){return d.isValid(this.side[0],this.side[1],this.side[2]),this.side.reduce((t,e)=>t+e,0)}area(){const[t,e,s]=this.side;return d.area(t,e,s)}get type(){const[t,e,s]=this.side;return d.getType(t,e,s)}get angles(){const[t,e,s]=this.side;return d.getAngles(t,e,s)}get centroid(){return new l((this.p1.x+this.p2.x+this.p3.x)/3,(this.p1.y+this.p2.y+this.p3.y)/3)}get incenter(){const[t,e,s]=this.side,r=this.perimeter()/2,i=(t*this.p1.x+e*this.p2.x+s*this.p3.x)/r,n=(t*this.p1.y+e*this.p2.y+s*this.p3.y)/r;return new l(i,n)}get circumcenter(){const t=2*(this.p1.x*(this.p2.y-this.p3.y)+this.p2.x*(this.p3.y-this.p1.y)+this.p3.x*(this.p1.y-this.p2.y));if(Math.abs(t)<d.EPSILON)throw new Error("Cannot calculate circumcenter for collinear points");const e=((this.p1.x*this.p1.x+this.p1.y*this.p1.y)*(this.p2.y-this.p3.y)+(this.p2.x*this.p2.x+this.p2.y*this.p2.y)*(this.p3.y-this.p1.y)+(this.p3.x*this.p3.x+this.p3.y*this.p3.y)*(this.p1.y-this.p2.y))/t,s=((this.p1.x*this.p1.x+this.p1.y*this.p1.y)*(this.p3.x-this.p2.x)+(this.p2.x*this.p2.x+this.p2.y*this.p2.y)*(this.p1.x-this.p3.x)+(this.p3.x*this.p3.x+this.p3.y*this.p3.y)*(this.p2.x-this.p1.x))/t;return new l(e,s)}containsPoint(t){const e=d.area(l.distance(t,this.p1),l.distance(t,this.p2),l.distance(this.p1,this.p2)),s=d.area(l.distance(t,this.p2),l.distance(t,this.p3),l.distance(this.p2,this.p3)),r=d.area(l.distance(t,this.p3),l.distance(t,this.p1),l.distance(this.p3,this.p1));return Math.abs(e+s+r-this.area())<d.EPSILON}}class B{static sleep(t){return new Promise(e=>setTimeout(e,t))}static binarySearchTemplate(t,e,s){let r=-1,i=t.length,n;for(;i-r>1;)n=i-(i-r)>>1,s(t[n],e)?i=n:r=n;return i}static singleton(t){let e;const s=new Proxy(t,{construct(r,i,n){return e||(e=Reflect.construct(r,i,n)),e}});return t.prototype.constructor=s,s}}class G{static groupBy(t,e){if(!e)throw new Error("generateKey is required");const s=typeof e=="string"?i=>i[e]:e,r=new Map;for(const[i,n]of t.entries())try{const a=s(n,i,t);if(a==null){console.warn("Invalid key generated for item:",n);continue}const o=r.get(a)??[];o.push(n),r.set(a,o)}catch(a){console.error("Error generating key for item:",n,a)}return Object.fromEntries(r)}static LIS(t){if(!t.length)return[];const e=[[t[0]]];for(let r=1,i=t.length;r<i;r++){const n=t[r];s(n)}function s(r){for(let i=e.length-1;i>=0;i--){const n=e[i],a=n[e[i].length-1];if(a<r){e[i+1]=[...n,r];break}else a>r&&i===0&&(e[i]=[r])}}return e[e.length-1]}static LCP(t){if(!t.length)return"";let e=t[0];for(let s=1;s<t.length;s++)for(;!t[s].startsWith(e);)if(e=e.slice(0,-1),e==="")return"";return e}}function b(h){return h!==null&&(typeof h=="object"||typeof h=="function")}class j{map=new Map;weakMap=new WeakMap;set(t,e){b(t)?this.weakMap.set(t,e):this.map.set(t,e)}get(t){return b(t)?this.weakMap.get(t):this.map.get(t)}has(t){return b(t)?this.weakMap.has(t):this.map.has(t)}}class _{static jsonClone(t){try{return JSON.parse(JSON.stringify(t))}catch{throw new Error("Object is not JSON cloneable")}}static structureClone(t){return structuredClone(t)}static deepClone(t,e=new WeakMap){if(t==null||typeof t!="object")return t;if(e.has(t))return e.get(t);if(t instanceof Date)return new Date(t.getTime());if(t instanceof RegExp)return new RegExp(t.source,t.flags);if(t instanceof Map){const n=new Map;e.set(t,n);for(const[a,o]of t)n.set(this.deepClone(a,e),this.deepClone(o,e));return n}if(t instanceof Set){const n=new Set;e.set(t,n);for(const a of t)n.add(this.deepClone(a,e));return n}if(Array.isArray(t)){const n=new Array(t.length);e.set(t,n);for(let a=0,o=t.length;a<o;a++)n[a]=this.deepClone(t[a],e);return n}if(t instanceof ArrayBuffer)return t.slice(0);const s=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array];for(const n of s)if(t instanceof n)return new n(t);if(typeof t=="function")return new Proxy(t,{apply(n,a,o){return n.apply(a,o)},get(n,a){if(a in n)return n[a]}});const r=Object.create(Object.getPrototypeOf(t));e.set(t,r);const i=Object.getOwnPropertyDescriptors(t);for(const[n,a]of Object.entries(i))a.value!==void 0&&(a.value=this.deepClone(a.value,e)),Object.defineProperty(r,n,a);return r}}const z={date:"yyyy-MM-dd",datetime:"yyyy-MM-dd HH:mm:ss",time:"HH:mm:ss",iso:"yyyy-MM-ddTHH:mm:ss.SSS"};class S{static defaultOptions={paddingZero:!1,locale:"en-US"};static setDefaultOptions(t){S.defaultOptions={...S.defaultOptions,...t}}static format(t,e,s={}){const r={...S.defaultOptions,...s},i=S.getDateInfo(t,r);return S.normalizeFormatter(e)(i)}static getDateInfo(t,e){const s=(u,p=2)=>e.paddingZero?u.toString().padStart(p,"0"):u.toString(),r=t.getFullYear(),i=t.getMonth()+1,n=t.getDate(),a=t.getHours(),o=t.getMinutes(),f=t.getSeconds(),m=t.getMilliseconds();return{year:r,month:i,day:n,hour:a,minute:o,second:f,millisecond:m,yyyy:s(r,4),MM:s(i),dd:s(n),HH:s(a),mm:s(o),ss:s(f)}}static normalizeFormatter(t){if(typeof t=="function")return t;if(typeof t!="string")throw new Error("Formatter must be a string or function");t in z&&(t=z[t]);const e={yyyy:"yyyy",MM:"MM",dd:"dd",HH:"HH",mm:"mm",ss:"ss",SSS:"SSS"};return s=>{let r=t;for(const[i,n]of Object.entries(e))r=r.replace(new RegExp(i,"g"),String(s[n]||""));return r}}static formatRelative(t,e=new Date){const s=t.getTime()-e.getTime(),r=Math.abs(s),i=Math.floor(r/1e3),n=Math.floor(i/60),a=Math.floor(n/60),o=Math.floor(a/24);return o>0?s>0?`${o}天后`:`${o}天前`:a>0?s>0?`${a}小时后`:`${a}小时前`:n>0?s>0?`${n}分钟后`:`${n}分钟前`:s>0?"刚刚":""}}class W{static escape(t){return t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&")}}class X{static ROMAN_MAP=new Map([["M",1e3],["CM",900],["D",500],["CD",400],["C",100],["XC",90],["L",50],["XL",40],["X",10],["IX",9],["V",5],["IV",4],["I",1]]);static toInteger(t){if(t.length===0)throw new Error("Input cannot be empty");const e=new Set(["I","V","X","L","C","D","M"]);for(const n of t)if(!e.has(n))throw new Error(`Invalid Roman numeral character: ${n}`);let s=0,r=0;for(;r<t.length;){const n=t.slice(r,r+2);if(this.ROMAN_MAP.has(n))s+=this.ROMAN_MAP.get(n),r+=2;else{const a=t[r],o=this.ROMAN_MAP.get(a);if(!o)throw new Error(`Invalid Roman numeral sequence at position ${r}`);s+=o,r+=1}}if(this.toRoman(s)!==t)throw new Error("Invalid Roman numeral sequence");return s}static toRoman(t){if(t<=0||t>=4e3)throw new Error("Number must be between 1 and 3999");if(!Number.isInteger(t))throw new Error("Number must be an integer");let e="";for(const[s,r]of this.ROMAN_MAP)for(;t>=r;)e+=s,t-=r;return e}}class w extends Number{static handleNumRange(t,e=!1,s=Number.MIN_SAFE_INTEGER,r=Number.MAX_SAFE_INTEGER){if(e&&!Number.isInteger(t))throw new Error("n must be an integer");if(t<s||t>=r)throw new RangeError(`n must be in the range of ${s} to ${r}`)}static consecutiveSum(t){return w.handleNumRange(t,!0,0,1e8),t*(t+1)/2}static consecutiveSquaresSum(t){return w.handleNumRange(t,!0,0,1e6),t*(t+1)*(2*t+1)/6}static consecutivecubesSum(t){return w.handleNumRange(t,!0,0,1e4),t*(t+1)*(2*t+1)*(3*t*t+3*t-1)/30}static clamp(t,e,s){return s==null?Math.min(t,e):Math.min(Math.max(t,e),s)}static factorial(t){if(w.handleNumRange(t,!0,0,1e3),t<2)return 1;let e=1;for(let s=2;s<=t;s++)e*=s;return e}static fibonacci(t,e=1,s=1){return w.handleNumRange(t,!0,0,1e3),t<2?s:this.fibonacci(t-1,s,s+e)}static fibonacciIterative(t){if(w.handleNumRange(t,!0,0,1e3),t<2)return t;let e=0,s=1;for(let r=2;r<=t;r++)[e,s]=[s,(e+s)%1000000007];return s}static floatEqual(t,e,s=1e-6){return Math.abs(t-e)<s}static fastPower(t,e){if(w.handleNumRange(e,!0,0,10),w.handleNumRange(t,!1,0,1e3),t===0)return 0;if(e===0)return 1;const s=this.fastPower(t,e>>1);return e%2===0?s*s:s*s*t}static fastSqrt(t){if(w.handleNumRange(t,!1,0,1e8),typeof BigInt>"u")return Math.sqrt(t);const e=.5*t,s=new ArrayBuffer(8);new Float64Array(s)[0]=t;let r=new BigInt64Array(s)[0];r=0x1ff7a3bea91d9b1bn+(r>>1n);const i=new ArrayBuffer(8);new BigInt64Array(i)[0]=r;let n=new Float64Array(i)[0];return n=n*.5+e/n,n=n*.5+e/n,n=n*.5+e/n,n}static getPercentWithPrecision(t,e=2){if(!Array.isArray(t)||t.length===0)return[];if(e<0||!Number.isInteger(e))throw new Error("Precision must be a non-negative integer");const s=t.reduce((u,p)=>u+p,0);if(s===0)return t.map(()=>"0%");const i=100*Math.pow(10,e),n=t.map(u=>u/s*i),a=n.map(u=>Math.floor(u)),o=n.map((u,p)=>u-a[p]);let f=a.reduce((u,p)=>u+p,0),m=i-f;for(;m>0;){let u=-1,p=-1;for(let y=0;y<o.length;y++)o[y]>p&&(p=o[y],u=y);if(u===-1)break;a[u]++,o[u]=0,m--}return a.map(u=>`${(u/i*100).toFixed(e)}%`)}static gcd(t,e){return e===0?t:this.gcd(e,t%e)}static isValidPositiveInteger(t){return Number.isInteger(t)&&t>0&&t<=Number.MAX_SAFE_INTEGER}static isPowerOfTwo(t){return t>0&&(t&t-1)===0}static isOdd(t){return t%2===1||t%2===-1}static isPrime(t){if(t<=1)return!1;for(let e=2;e<=Math.sqrt(t);e++)if(t%e===0)return!1;return!0}static isPalindrome(t){if(t<0||t%10===0&&t!==0)return!1;let e=0,s=t;for(;t>0;){const r=t%10;e=e*10+r,t=Math.floor(t/10)}return s===e}static isArmstrong(t){const e=t.toString(),s=e.length;let r=0;for(let i=0;i<s;i++)r+=Math.pow(parseInt(e[i]),s);return r===t}static isHappy(t){const e=new Set;for(;t!==1;){if(e.has(t))return!1;e.add(t),t=(t+"").split("").reduce((s,r)=>s+Number(r)*Number(r),0)}return!0}static isPerfect(t){let e=0;for(let s=1;s<t;s++)t%s===0&&(e+=s);return e===t}static isSameSign(t,e){return t>=0&&e>=0||t<=0&&e<=0}static isRange(t,e,s){if(s==null&&(s=e,e=0),e>=s)throw new Error("The maximum value must be greater than the minimum value");return e<=t&&t<s}static lcm(t,e){return t*e/this.gcd(t,e)}static middle(t,e){return e-(e-t>>1)}static random(t,e){if(e==null&&(e=t,t=0),t>=e)throw new Error("The maximum value must be greater than the minimum value");return Math.random()*(e-t)+t}static randomInt(t,e){return Math.floor(this.random(t,e))}static round(t,e=0){if(!Number.isInteger(e))throw new Error("precision must be an integer");const s=Math.pow(10,e);return Math.round(t*s)/s}static scale(t,e,s){if(e[0]>=e[1]||s[0]>=s[1])throw new Error("Invalid range");t=this.clamp(t,e[0],e[1]);const r=e[1]-e[0];return(t-e[0])*((s[1]-s[0])/r)+s[0]}}class Q{static READ=1;static WRITE=2;static SHARE=4;static DELETE=8;static CREATE=16;static include(t,e){return(t&e)===e}static add(t,e){return t|e}static remove(t,e){return t&~e}static toggle(t,e){return t^e}}class J extends String{static frequencyStatistics(t){return[...t].reduce((e,s)=>(e[s]=(e[s]||0)+1,e),{})}static isValidBracket(t){const e=[],s={"(":")","[":"]","{":"}"},r=new Set(Object.values(s));for(const i of t)if(i in s)e.push(s[i]);else if(r.has(i)&&i!==e.pop())return!1;return e.length===0}static random(t=8){const e="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";let s="";for(let r=0;r<t;r++)s+=e.charAt(Math.floor(Math.random()*e.length));return s}static template(t,e){return t.replace(/\${(\w+)}/g,(s,r)=>e[r]||"")}static escapeHtml(t){const e={"&":"&","<":"<",">":">",'"':""","'":"'"," ":" ","±":"±","×":"×","÷":"÷","≠":"≠","≤":"≤","≥":"≥"},s=new RegExp(`[${Object.keys(e).join("")}]`,"g");return t.replace(s,r=>e[r])}static isEmail(t){return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t)}static isUrl(t){try{return new URL(t),!0}catch{return!1}}constructor(t){super(t)}pointLength(){let t=0;for(let e=0,s=this.length;e<s;){const r=this.codePointAt(e);e+=r>65535?2:1,t++}return t}pointAt(t){if(t>=this.pointLength())return;let e=0;for(let s=0,r=this.length;s<r;){const i=this.codePointAt(s);if(!i)return;if(e===t)return String.fromCodePoint(i);s+=i>65535?2:1,e++}}sliceByPoint(t,e=this.pointLength()){let s="";for(let r=t;r<e;r++)s+=this.pointAt(r);return s}capitalize(){return this.charAt(0).toUpperCase()+this.slice(1).toLowerCase()}reverse(){return this.split("").reverse().join("")}truncate(t,e="..."){return this.length<=t?this:this.slice(0,t-e.length)+e}isPalindrome(){return this.toLowerCase().replace(/[^a-z0-9]/g,"")===this.reverse()}count(t){const e=t.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");return(this.match(new RegExp(e,"g"))||[]).length}toCamelCase(){return this.replace(/_([a-z])/g,(t,e)=>e.toUpperCase())}toSnakeCase(){return this.replace(/[A-Z]/g,t=>`_${t.toLowerCase()}`)}}class Z{static isValidHex(t){return/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(t)}static isValidRGB(t){return/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/.test(t)}}const x={AUTH_UNAUTHORIZED:"未授权事件",AUTH_LOGIN_SUCCESS:"登录成功事件",AUTH_LOGOUT:"注销事件",AUTH_TOKEN_EXPIRED:"令牌过期事件",REQUEST_ERROR:"请求错误事件",REQUEST_TIMEOUT:"请求超时事件",REQUEST_NETWORK_ERROR:"网络错误事件",UI_SHOW_LOADING:"显示加载事件",UI_HIDE_LOADING:"隐藏加载事件",UI_SHOW_MESSAGE:"显示消息事件"};class A{static instance=null;listeners={};debugMode;constructor(t=!1){this.debugMode=t,Object.keys(x).forEach(e=>{this.listeners[e]=new Set})}static getInstance(t){return A.instance||(A.instance=new A(t)),A.instance}on(t,e){this.debugLog(`添加事件监听: ${x[t]}`),this.listeners[t].add(e)}emit(t,e){this.debugLog(`触发事件: ${x[t]}`,e),this.listeners[t].forEach(s=>{try{s(e)}catch(r){console.error(`事件 ${x[t]} 处理出错:`,r)}})}off(t,e){this.debugLog(`移除事件监听: ${x[t]}`),this.listeners[t].delete(e)}once(t,e){this.debugLog(`添加一次性事件监听: ${x[t]}`);const s=r=>{e(r),this.off(t,s)};this.on(t,s)}clear(){this.debugLog("清除所有事件监听器"),Object.values(this.listeners).forEach(t=>t.clear())}getListenerCount(t){return this.listeners[t].size}debugLog(t,e){this.debugMode&&console.log(`[EventEmitter] ${t}`,e||"")}}c.Arr=G,c.BitPerm=Q,c.Color=Z,c.DateEx=S,c.Dictionary=L,c.Emitter=A,c.Func=B,c.Graph=F,c.LRU=U,c.Line=g,c.LinkedList=q,c.Matrix=M,c.MaxHeap=V,c.MemoizeMap=j,c.MinHeap=P,c.MinStack=H,c.Num=w,c.Obj=_,c.Point=l,c.Queue=v,c.Reg=W,c.Roman=X,c.Stack=$,c.Str=J,c.Triangle=d,c.Vector=E,Object.defineProperty(c,Symbol.toStringTag,{value:"Module"})}));
|
package/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference path="./types/string.extensions.d.ts"/>
|
|
2
2
|
|
|
3
3
|
declare module "jc-structure" {
|
|
4
|
+
//#region data structure
|
|
4
5
|
/**
|
|
5
6
|
* #### 数据结构接口
|
|
6
7
|
*/
|
|
@@ -306,28 +307,6 @@ declare module "jc-structure" {
|
|
|
306
307
|
getAdjacencyList(): IDictionary<T, Array<T>>;
|
|
307
308
|
}
|
|
308
309
|
|
|
309
|
-
/**
|
|
310
|
-
* ### 缓存类
|
|
311
|
-
*/
|
|
312
|
-
export class MemoizeMap {
|
|
313
|
-
/**
|
|
314
|
-
* 根据键的类型,判断缓存在 Map 还是 WeakMap中
|
|
315
|
-
* @param key 键值
|
|
316
|
-
* @param value 值
|
|
317
|
-
*/
|
|
318
|
-
set(key: unknown, value: unknown): void;
|
|
319
|
-
/**
|
|
320
|
-
* #### 根据键获取缓存的值
|
|
321
|
-
* @param key
|
|
322
|
-
*/
|
|
323
|
-
get(key: unknown): any;
|
|
324
|
-
/**
|
|
325
|
-
* #### 判断缓存中是否存在该键
|
|
326
|
-
* @param key
|
|
327
|
-
*/
|
|
328
|
-
has(key: unknown): boolean;
|
|
329
|
-
}
|
|
330
|
-
|
|
331
310
|
interface Point {
|
|
332
311
|
/**
|
|
333
312
|
* #### 点x坐标
|
|
@@ -571,35 +550,34 @@ declare module "jc-structure" {
|
|
|
571
550
|
mulMatrix(matrix: Matrix): Matrix;
|
|
572
551
|
}
|
|
573
552
|
|
|
574
|
-
|
|
575
|
-
* #### 单例模式
|
|
576
|
-
* @param classCtor 类构造函数
|
|
577
|
-
*/
|
|
578
|
-
export function singleton<T extends new (...args: any[]) => object>(
|
|
579
|
-
classCtor: T
|
|
580
|
-
): T;
|
|
553
|
+
//#endregion
|
|
581
554
|
|
|
582
555
|
/**
|
|
583
|
-
*
|
|
584
|
-
* @param nums
|
|
585
|
-
*/
|
|
586
|
-
// export function LIS(nums: Array<number>): Array<number>;
|
|
587
|
-
/**
|
|
588
|
-
* #### 睡眠函数
|
|
589
|
-
* @param ms 毫秒
|
|
556
|
+
* ### 缓存类
|
|
590
557
|
*/
|
|
591
|
-
|
|
558
|
+
export class MemoizeMap {
|
|
559
|
+
/**
|
|
560
|
+
* 根据键的类型,判断缓存在 Map 还是 WeakMap中
|
|
561
|
+
* @param key 键值
|
|
562
|
+
* @param value 值
|
|
563
|
+
*/
|
|
564
|
+
set(key: unknown, value: unknown): void;
|
|
565
|
+
/**
|
|
566
|
+
* #### 根据键获取缓存的值
|
|
567
|
+
* @param key
|
|
568
|
+
*/
|
|
569
|
+
get(key: unknown): any;
|
|
570
|
+
/**
|
|
571
|
+
* #### 判断缓存中是否存在该键
|
|
572
|
+
* @param key
|
|
573
|
+
*/
|
|
574
|
+
has(key: unknown): boolean;
|
|
575
|
+
}
|
|
592
576
|
|
|
593
577
|
/**
|
|
594
|
-
*
|
|
595
|
-
* @param str 含括号的字符串
|
|
578
|
+
* ### 数字类,继承自Number
|
|
596
579
|
*/
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
interface NumConstructor {
|
|
600
|
-
new (value?: any): Number;
|
|
601
|
-
readonly prototype: Number;
|
|
602
|
-
|
|
580
|
+
interface NumConstructor extends NumberConstructor {
|
|
603
581
|
/**
|
|
604
582
|
* #### 判断是否是有效的正整数
|
|
605
583
|
* @param n A numeric value
|
|
@@ -708,8 +686,6 @@ declare module "jc-structure" {
|
|
|
708
686
|
*/
|
|
709
687
|
isPerfect(n: number): boolean;
|
|
710
688
|
|
|
711
|
-
middle(a: number, b: number);
|
|
712
|
-
|
|
713
689
|
/**
|
|
714
690
|
* #### 线性比例缩放取值
|
|
715
691
|
* @param n
|
|
@@ -842,12 +818,264 @@ declare module "jc-structure" {
|
|
|
842
818
|
}
|
|
843
819
|
declare var BitPer: BitPerConstructor;
|
|
844
820
|
|
|
845
|
-
interface
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
821
|
+
interface Str extends String {
|
|
822
|
+
/**
|
|
823
|
+
* #### 获取字符串码点长度
|
|
824
|
+
*/
|
|
825
|
+
pointLength(): number;
|
|
826
|
+
/**
|
|
827
|
+
* #### 获取指定索引的码点
|
|
828
|
+
* @param index 索引
|
|
829
|
+
*/
|
|
830
|
+
pointAt(index: number): string | undefined;
|
|
831
|
+
/**
|
|
832
|
+
* #### 根据码点索引截取字符串
|
|
833
|
+
* @param start 开始索引
|
|
834
|
+
* @param end 结束索引
|
|
835
|
+
*/
|
|
836
|
+
sliceByPoint(start: number, end = this.pointLength()): string;
|
|
837
|
+
/**
|
|
838
|
+
* #### 首字母大写
|
|
839
|
+
*/
|
|
840
|
+
capitalize(): string;
|
|
841
|
+
/**
|
|
842
|
+
* #### 反转字符串
|
|
843
|
+
*/
|
|
844
|
+
reverse(): string;
|
|
845
|
+
/**
|
|
846
|
+
* #### 截断字符串,超过长度则添加指定的后缀
|
|
847
|
+
* @param length 长度,包含‘...’
|
|
848
|
+
* @param suffix 后缀符号,默认‘...’
|
|
849
|
+
*/
|
|
850
|
+
truncate(length: number, suffix: string = "..."): string;
|
|
851
|
+
/**
|
|
852
|
+
* #### 是否是回文字符串
|
|
853
|
+
*/
|
|
854
|
+
isPalindrome(): boolean;
|
|
855
|
+
/**
|
|
856
|
+
* #### 根据字串统计频率数量
|
|
857
|
+
* @param substring
|
|
858
|
+
*/
|
|
859
|
+
count(substring: string): number;
|
|
860
|
+
/**
|
|
861
|
+
* #### 转驼峰命名
|
|
862
|
+
*/
|
|
863
|
+
toCamelCase(): string;
|
|
864
|
+
/**
|
|
865
|
+
* #### 转下划线命名
|
|
866
|
+
*/
|
|
867
|
+
toSnakeCase(): string;
|
|
868
|
+
}
|
|
869
|
+
interface StrConstructor extends StringConstructor {
|
|
870
|
+
new (value?: any): Str;
|
|
871
|
+
readonly prototype: Str;
|
|
872
|
+
/**
|
|
873
|
+
* #### 根据字符串频率统计
|
|
874
|
+
* @param s
|
|
875
|
+
*/
|
|
876
|
+
frequencyStatistics(s: string): { [key: string]: number };
|
|
877
|
+
/**
|
|
878
|
+
* #### 是否是成对的括号
|
|
879
|
+
* @param str
|
|
880
|
+
*/
|
|
881
|
+
isValidBracket(str: string): boolean;
|
|
882
|
+
/**
|
|
883
|
+
* #### 根据长度获取随机字符串
|
|
884
|
+
* @param length
|
|
885
|
+
*/
|
|
886
|
+
random(length: number = 8): string;
|
|
887
|
+
/**
|
|
888
|
+
* #### 生成模板字符串
|
|
889
|
+
* @param template 模板字符串
|
|
890
|
+
* @param values
|
|
891
|
+
*/
|
|
892
|
+
template(template: string, values: Record<string, any>): string;
|
|
893
|
+
/**
|
|
894
|
+
* #### 转义HTML标签
|
|
895
|
+
* @param str 字符串
|
|
896
|
+
*/
|
|
897
|
+
escapeHtml(str: string): string;
|
|
898
|
+
/**
|
|
899
|
+
* #### 判断是否是邮箱号码
|
|
900
|
+
* @param str
|
|
901
|
+
*/
|
|
902
|
+
isEmail(str: string): boolean;
|
|
903
|
+
/**
|
|
904
|
+
* #### 判断是否是URL
|
|
905
|
+
* @param str
|
|
906
|
+
*/
|
|
907
|
+
isUrl(str: string): boolean;
|
|
851
908
|
}
|
|
852
909
|
declare var Str: StrConstructor;
|
|
910
|
+
|
|
911
|
+
interface RegConstructor {
|
|
912
|
+
/**
|
|
913
|
+
* #### 用于对字符串中的特殊字符进行转义处理
|
|
914
|
+
* - 这个方法用于转义正则表达式中的特殊字符
|
|
915
|
+
* - 它会在所有特殊字符前添加反斜杠,使这些字符被当作普通字符处理
|
|
916
|
+
* @param str 字符串
|
|
917
|
+
* @example
|
|
918
|
+
* ```ts
|
|
919
|
+
* const input = "price: $100.00?";
|
|
920
|
+
* const escaped = escape(input); // 输出: "price: \$100\.00\?"
|
|
921
|
+
* // 这样就可以安全地用作正则表达式模式了
|
|
922
|
+
* const regex = new RegExp(escaped); // 正则表达式: /price: \$100\.00\?/
|
|
923
|
+
* ```
|
|
924
|
+
*/
|
|
925
|
+
escape(str: string): string;
|
|
926
|
+
}
|
|
927
|
+
declare var Reg: RegConstructor;
|
|
928
|
+
|
|
929
|
+
interface FormatOptions {
|
|
930
|
+
/**
|
|
931
|
+
* #### 是否补零
|
|
932
|
+
*/
|
|
933
|
+
paddingZero?: boolean;
|
|
934
|
+
/**
|
|
935
|
+
* #### 语言
|
|
936
|
+
*/
|
|
937
|
+
locale?: string;
|
|
938
|
+
}
|
|
939
|
+
type Formatter = string | ((dateInfo: DateInfo) => string);
|
|
940
|
+
interface DateExConstructor {
|
|
941
|
+
/**
|
|
942
|
+
* #### 设置默认格式化选项
|
|
943
|
+
* @param options
|
|
944
|
+
*/
|
|
945
|
+
setDefaultOptions(options: Partial<FormatOptions>): void;
|
|
946
|
+
/**
|
|
947
|
+
* #### 格式化日期
|
|
948
|
+
* @param date 日期
|
|
949
|
+
* @param formatter 格式化器
|
|
950
|
+
* @param options
|
|
951
|
+
*/
|
|
952
|
+
format(
|
|
953
|
+
date: Date,
|
|
954
|
+
formatter: Formatter,
|
|
955
|
+
options: FormatOptions = {}
|
|
956
|
+
): string;
|
|
957
|
+
}
|
|
958
|
+
declare var DateEx: DateExConstructor;
|
|
959
|
+
|
|
960
|
+
interface FuncConstructor {
|
|
961
|
+
/**
|
|
962
|
+
* #### 延迟执行函数
|
|
963
|
+
* @param ms 毫秒
|
|
964
|
+
*/
|
|
965
|
+
sleep(ms: number): Promise<unknown>;
|
|
966
|
+
|
|
967
|
+
/**
|
|
968
|
+
* #### 二分查找万金油模板
|
|
969
|
+
* - 采用红绿灯模型
|
|
970
|
+
* 1. 抽象出一个单调的数组或函数
|
|
971
|
+
* 2. 按照给定的条件将它划分成绿色和红色
|
|
972
|
+
* 3. 用二分查找找到红绿边界
|
|
973
|
+
* 4. 根据边界计算最终值
|
|
974
|
+
* - isGreen:函数设计
|
|
975
|
+
* 1. 大于目标值的最小值
|
|
976
|
+
* ```ts
|
|
977
|
+
* function isGreen(val: number, target: number) {
|
|
978
|
+
* return val > target;
|
|
979
|
+
* }
|
|
980
|
+
* ```
|
|
981
|
+
* 2. 大于等于目标值的最小值
|
|
982
|
+
* ```ts
|
|
983
|
+
* function isGreen(val: number, target: number) {
|
|
984
|
+
* return val >= target;
|
|
985
|
+
* }
|
|
986
|
+
* ```
|
|
987
|
+
* 3. 小于目标值的最大值
|
|
988
|
+
* ```ts
|
|
989
|
+
* function isGreen(val: number, target: number) {
|
|
990
|
+
* return val < target;
|
|
991
|
+
* }
|
|
992
|
+
* ```
|
|
993
|
+
* 4. 小于等于目标值的最大值
|
|
994
|
+
* ```ts
|
|
995
|
+
* function isGreen(val: number, target: number) {
|
|
996
|
+
* return val <= target;
|
|
997
|
+
* }
|
|
998
|
+
* ```
|
|
999
|
+
* @param arr 单调数组
|
|
1000
|
+
* @param target 目标值
|
|
1001
|
+
* @param isGreen 红绿灯回调函数
|
|
1002
|
+
* @returns 查找目标的下标
|
|
1003
|
+
*/
|
|
1004
|
+
binarySearchTemplate(
|
|
1005
|
+
arr: number[],
|
|
1006
|
+
target: number,
|
|
1007
|
+
isGreen: (val: number, target: number) => boolean
|
|
1008
|
+
): number;
|
|
1009
|
+
|
|
1010
|
+
/**
|
|
1011
|
+
* #### 单例模式
|
|
1012
|
+
* @param classCtor 类
|
|
1013
|
+
*/
|
|
1014
|
+
singleton<T extends new (...args: any[]) => object>(classCtor: T): T;
|
|
1015
|
+
}
|
|
1016
|
+
declare var Func: FuncConstructor;
|
|
1017
|
+
|
|
1018
|
+
interface ObjConstructor {
|
|
1019
|
+
/**
|
|
1020
|
+
* #### Deep clone by JSON
|
|
1021
|
+
* 1. 函数全部丢失
|
|
1022
|
+
* 2. Symbol 键名丢失
|
|
1023
|
+
* 3. undefined 值被过滤
|
|
1024
|
+
* 4. Date 对象被转换为字符串
|
|
1025
|
+
* 5. RegExp 变成空对象
|
|
1026
|
+
* 6. 循环引用会报错
|
|
1027
|
+
* 7. NaN、Infinity 和 -Infinity 变成 null
|
|
1028
|
+
* @param obj
|
|
1029
|
+
* @returns
|
|
1030
|
+
*/
|
|
1031
|
+
jsonClone<T>(obj: T): T;
|
|
1032
|
+
/**
|
|
1033
|
+
* #### Deep clone by StructuredClone
|
|
1034
|
+
* 1. 函数报异常
|
|
1035
|
+
* 2. DOM节点报异常
|
|
1036
|
+
* 3. RegExp lastIndex 丢失
|
|
1037
|
+
*
|
|
1038
|
+
* @param obj
|
|
1039
|
+
* @returns
|
|
1040
|
+
*/
|
|
1041
|
+
structureClone(obj: any): any;
|
|
1042
|
+
/**
|
|
1043
|
+
* #### 深度克隆
|
|
1044
|
+
* @see https://juejin.cn/post/7545320732952903680
|
|
1045
|
+
* @param obj
|
|
1046
|
+
* @param visited
|
|
1047
|
+
* @returns
|
|
1048
|
+
*/
|
|
1049
|
+
deepClone(obj: unknown, visited = new WeakMap()): unknown;
|
|
1050
|
+
}
|
|
1051
|
+
declare var Obj: ObjConstructor;
|
|
1052
|
+
|
|
1053
|
+
interface ArrConstructor {
|
|
1054
|
+
/**
|
|
1055
|
+
* #### 根据属性或函数生成的键分组
|
|
1056
|
+
* @param arr 数组
|
|
1057
|
+
* @param generateKey 键或者生成键的函数
|
|
1058
|
+
*/
|
|
1059
|
+
groupBy<T, K extends string | number | symbol>(
|
|
1060
|
+
arr: T[],
|
|
1061
|
+
generateKey: string | ((item: T, index: number, arr: T[]) => K)
|
|
1062
|
+
): Record<K, T[]>;
|
|
1063
|
+
/**
|
|
1064
|
+
* #### 最长递增子序列
|
|
1065
|
+
* @param nums
|
|
1066
|
+
*/
|
|
1067
|
+
LIS(nums: number[]): number[];
|
|
1068
|
+
/**
|
|
1069
|
+
* #### 最长公共前缀
|
|
1070
|
+
* @param strs
|
|
1071
|
+
*/
|
|
1072
|
+
LCP(strs: string[]): string;
|
|
1073
|
+
}
|
|
1074
|
+
declare var Arr: ArrConstructor;
|
|
1075
|
+
|
|
1076
|
+
interface ColorConstructor {
|
|
1077
|
+
isValidHex(hex: string): boolean;
|
|
1078
|
+
isValidRGB(rgb: string): boolean;
|
|
1079
|
+
}
|
|
1080
|
+
declare var Color: ColorConstructor;
|
|
853
1081
|
}
|
package/package.json
CHANGED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
interface String {
|
|
2
|
-
/**
|
|
3
|
-
* #### 获取字符串码点长度,1个码点对应1个码元或2个码元,譬如 "👍" 长度为2,"a" 长度为1
|
|
4
|
-
* - 计算字符串的码点长度,考虑到 Unicode 字符的特殊性
|
|
5
|
-
* @returns {number} 字符串的码元长度
|
|
6
|
-
*/
|
|
7
|
-
pointLength(this: string): number;
|
|
8
|
-
/**
|
|
9
|
-
* #### 根据码点索引获取对应的字符
|
|
10
|
-
* - 处理 Unicode 字符,确保正确获取码点对应的字符
|
|
11
|
-
* @param index 码点索引
|
|
12
|
-
*/
|
|
13
|
-
pointAt(this: string, index: number): string | undefined;
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* #### 根据码点索引切割字符串
|
|
17
|
-
* - 按照码点索引切割字符串,确保不会破坏 Unicode 字符
|
|
18
|
-
* @param start 开始索引
|
|
19
|
-
* @param end 结束索引
|
|
20
|
-
*/
|
|
21
|
-
sliceByPoint(this: string, start: number, end?: number): string;
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* #### 字符串首字母大写
|
|
25
|
-
*/
|
|
26
|
-
capitalize(): string;
|
|
27
|
-
/**
|
|
28
|
-
* #### 字符串反转
|
|
29
|
-
*/
|
|
30
|
-
reverse(): string;
|
|
31
|
-
/**
|
|
32
|
-
* #### 字符串截断,超出长度时,添加后缀‘...’
|
|
33
|
-
* @param this 字符串实例
|
|
34
|
-
* @param length 指定长度,包含了后缀的长度
|
|
35
|
-
* @param suffix 后缀,默认为‘...’
|
|
36
|
-
*/
|
|
37
|
-
truncate(this: string, length: number, suffix?: string): string;
|
|
38
|
-
/**
|
|
39
|
-
* #### 判断字符串是否为回文
|
|
40
|
-
*/
|
|
41
|
-
isPalindrome(): boolean;
|
|
42
|
-
/**
|
|
43
|
-
* #### 子字符串在字符串中出现的次数
|
|
44
|
-
* @param substring 子字符串
|
|
45
|
-
*/
|
|
46
|
-
count(substring: string): number;
|
|
47
|
-
/**
|
|
48
|
-
* #### 字符串转驼峰命名
|
|
49
|
-
*/
|
|
50
|
-
toCamelCase(): string;
|
|
51
|
-
/**
|
|
52
|
-
* #### 字符串转下划线命名
|
|
53
|
-
*/
|
|
54
|
-
toSnakeCase(): string;
|
|
55
|
-
/**
|
|
56
|
-
* #### 模板字符串语法,将字符串中的占位符替换为对应的值
|
|
57
|
-
* @param args 占位符对应的值
|
|
58
|
-
* @example
|
|
59
|
-
* ```ts
|
|
60
|
-
* 'Hello, {name}!'.format({name: 'world'}) // 'Hello, world!'
|
|
61
|
-
* ```
|
|
62
|
-
*/
|
|
63
|
-
format(...args: any[]): string;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
interface StringConstructor {
|
|
67
|
-
/**
|
|
68
|
-
* #### 生成指定长度的随机字符串
|
|
69
|
-
* @param length 长度
|
|
70
|
-
*/
|
|
71
|
-
random(length?: number): string;
|
|
72
|
-
/**
|
|
73
|
-
* #### 模板字符串语法,将字符串中的占位符替换为对应的值
|
|
74
|
-
* @param template
|
|
75
|
-
* @param values
|
|
76
|
-
*/
|
|
77
|
-
template(template: string, values: Record<string, any>): string;
|
|
78
|
-
/**
|
|
79
|
-
* #### 安全转义 HTML 字符串,防止 XSS 攻击
|
|
80
|
-
* @param str
|
|
81
|
-
*/
|
|
82
|
-
escapeHtml(str: string): string;
|
|
83
|
-
/**
|
|
84
|
-
* #### 是否是有效的邮箱地址
|
|
85
|
-
* @param str
|
|
86
|
-
*/
|
|
87
|
-
isEmail(str: string): boolean;
|
|
88
|
-
/**
|
|
89
|
-
* #### 是否是URL地址
|
|
90
|
-
* @param str
|
|
91
|
-
*/
|
|
92
|
-
isUrl(str: string): boolean;
|
|
93
|
-
}
|