jc-structure 0.0.8 → 0.1.0
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 +726 -70
- package/dist/jc-structure.umd.cjs +2 -2
- package/index.d.ts +227 -0
- package/package.json +4 -1
- package/types/extend.d.ts +22 -0
- package/types/global.d.ts +4 -0
package/dist/jc-structure.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
class
|
|
1
|
+
class z {
|
|
2
2
|
items = {};
|
|
3
3
|
count = 0;
|
|
4
4
|
lowestCount = 0;
|
|
@@ -30,7 +30,7 @@ class f {
|
|
|
30
30
|
return this.isEmpty() ? "" : `Queue(size: ${this.size()}):[${this.items[this.lowestCount]},...rest]`;
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
-
class
|
|
33
|
+
class j {
|
|
34
34
|
items = {};
|
|
35
35
|
count = 0;
|
|
36
36
|
constructor() {
|
|
@@ -62,13 +62,13 @@ class g {
|
|
|
62
62
|
return this.isEmpty() ? "" : `Stack(count: ${this.count}):[${this.items[this.count - 1]},...rest]`;
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
|
-
function
|
|
66
|
-
return
|
|
65
|
+
function N(n, t) {
|
|
66
|
+
return n === t ? 0 : n < t ? -1 : 1;
|
|
67
67
|
}
|
|
68
|
-
class
|
|
68
|
+
class g {
|
|
69
69
|
heap = [];
|
|
70
70
|
compareFn;
|
|
71
|
-
constructor(t =
|
|
71
|
+
constructor(t = N) {
|
|
72
72
|
this.compareFn = t;
|
|
73
73
|
}
|
|
74
74
|
static getLeftIndex(t) {
|
|
@@ -80,8 +80,8 @@ class n {
|
|
|
80
80
|
static getParentIndex(t) {
|
|
81
81
|
return t === 0 ? void 0 : Math.floor((t - 1) / 2);
|
|
82
82
|
}
|
|
83
|
-
static swap(t, e,
|
|
84
|
-
[t[e], t[
|
|
83
|
+
static swap(t, e, s) {
|
|
84
|
+
[t[e], t[s]] = [t[s], t[e]];
|
|
85
85
|
}
|
|
86
86
|
find() {
|
|
87
87
|
return this.isEmpty() ? void 0 : this.heap[0];
|
|
@@ -99,7 +99,7 @@ class n {
|
|
|
99
99
|
return this.heap.toString();
|
|
100
100
|
}
|
|
101
101
|
}
|
|
102
|
-
class
|
|
102
|
+
class A extends g {
|
|
103
103
|
insert(t) {
|
|
104
104
|
return t ? !1 : (this.heap.push(t), this.siftUp(this.heap.length - 1), !0);
|
|
105
105
|
}
|
|
@@ -110,24 +110,24 @@ class l extends n {
|
|
|
110
110
|
return this.heap[0] = this.heap.pop(), this.siftDown(0), t;
|
|
111
111
|
}
|
|
112
112
|
siftUp(t) {
|
|
113
|
-
let e = t,
|
|
114
|
-
|
|
113
|
+
let e = t, s = g.getLeftIndex(e), i = g.getRightIndex(e), r = this.size();
|
|
114
|
+
s < r && this.compareFn(this.heap[e], this.heap[s]) === -1 && (e = s), i < r && this.compareFn(this.heap[e], this.heap[i]) === 1 && (e = i), e !== t && (g.swap(this.heap, t, e), this.siftUp(e));
|
|
115
115
|
}
|
|
116
116
|
siftDown(t) {
|
|
117
|
-
let e =
|
|
117
|
+
let e = g.getParentIndex(t);
|
|
118
118
|
for (; t > 0 && e && this.compareFn(this.heap[e], this.heap[t]) === 1; )
|
|
119
|
-
|
|
119
|
+
g.swap(this.heap, e, t), t = e, e = g.getParentIndex(t);
|
|
120
120
|
}
|
|
121
121
|
}
|
|
122
|
-
class
|
|
123
|
-
constructor(t = (e,
|
|
122
|
+
class R extends A {
|
|
123
|
+
constructor(t = (e, s) => N(s, e)) {
|
|
124
124
|
super(t);
|
|
125
125
|
}
|
|
126
126
|
}
|
|
127
|
-
function
|
|
128
|
-
return { value:
|
|
127
|
+
function C(n) {
|
|
128
|
+
return { value: n };
|
|
129
129
|
}
|
|
130
|
-
class
|
|
130
|
+
class V {
|
|
131
131
|
capacity;
|
|
132
132
|
length = 0;
|
|
133
133
|
head = null;
|
|
@@ -156,29 +156,29 @@ class v {
|
|
|
156
156
|
return this.detach(e), this.prepend(e), e.value;
|
|
157
157
|
}
|
|
158
158
|
update(t, e) {
|
|
159
|
-
let
|
|
160
|
-
|
|
159
|
+
let s = this.lookup.get(t);
|
|
160
|
+
s ? (this.detach(s), this.prepend(s), s.value = e) : (s = C(e), this.length++, this.prepend(s), this.trimCache(), this.lookup.set(t, s), this.reverseLookup);
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
|
-
class
|
|
163
|
+
let I = class {
|
|
164
164
|
value;
|
|
165
165
|
next = void 0;
|
|
166
|
-
}
|
|
167
|
-
class
|
|
166
|
+
};
|
|
167
|
+
class W {
|
|
168
168
|
count = 0;
|
|
169
169
|
head = void 0;
|
|
170
170
|
constructor() {
|
|
171
171
|
}
|
|
172
172
|
indexOf(t) {
|
|
173
|
-
let e = this.head,
|
|
173
|
+
let e = this.head, s = 0, i = !1;
|
|
174
174
|
for (; e; ) {
|
|
175
175
|
if (this.equals(e.value, t)) {
|
|
176
|
-
|
|
176
|
+
i = !0;
|
|
177
177
|
break;
|
|
178
178
|
}
|
|
179
|
-
|
|
179
|
+
s++, e = e.next;
|
|
180
180
|
}
|
|
181
|
-
return
|
|
181
|
+
return i ? s : -1;
|
|
182
182
|
}
|
|
183
183
|
equals(t, e) {
|
|
184
184
|
return !1;
|
|
@@ -189,7 +189,7 @@ class x {
|
|
|
189
189
|
if (t === 0)
|
|
190
190
|
return this.head;
|
|
191
191
|
let e = this.head;
|
|
192
|
-
for (let
|
|
192
|
+
for (let s = 0; s < t; s++)
|
|
193
193
|
e = e?.next;
|
|
194
194
|
return e;
|
|
195
195
|
}
|
|
@@ -197,25 +197,25 @@ class x {
|
|
|
197
197
|
return this.getElementAt(t)?.value;
|
|
198
198
|
}
|
|
199
199
|
insert(t, e) {
|
|
200
|
-
let
|
|
201
|
-
if (
|
|
200
|
+
let s = new I();
|
|
201
|
+
if (s.value = t, e > this.count || e < 0)
|
|
202
202
|
throw new Error("index error");
|
|
203
203
|
this.count++;
|
|
204
|
-
let
|
|
204
|
+
let i, r;
|
|
205
205
|
if (e === 0) {
|
|
206
|
-
|
|
206
|
+
s.next = this.head, this.head = s;
|
|
207
207
|
return;
|
|
208
208
|
}
|
|
209
|
-
|
|
209
|
+
i = this.getElementAt(e - 1), r = i.next, i.next = s, s.next = r;
|
|
210
210
|
}
|
|
211
211
|
push(t) {
|
|
212
|
-
let e = new
|
|
212
|
+
let e = new I();
|
|
213
213
|
if (e.value = t, this.count++, this.isEmpty()) {
|
|
214
214
|
this.head = e;
|
|
215
215
|
return;
|
|
216
216
|
}
|
|
217
|
-
let
|
|
218
|
-
|
|
217
|
+
let s = this.getElementAt(this.count - 1);
|
|
218
|
+
s.next = e;
|
|
219
219
|
}
|
|
220
220
|
remove(t) {
|
|
221
221
|
const e = this.indexOf(t);
|
|
@@ -224,8 +224,8 @@ class x {
|
|
|
224
224
|
removeAt(t) {
|
|
225
225
|
if (this.isEmpty() || t < 0 || t >= this.count)
|
|
226
226
|
return;
|
|
227
|
-
let e = this.getElementAt(t),
|
|
228
|
-
return t === 0 && (this.head =
|
|
227
|
+
let e = this.getElementAt(t), s = this.getElementAt(t - 1), i = e?.next;
|
|
228
|
+
return t === 0 && (this.head = i), s && (s.next = i), this.count--, e?.value;
|
|
229
229
|
}
|
|
230
230
|
isEmpty() {
|
|
231
231
|
return this.count === 0;
|
|
@@ -243,37 +243,37 @@ class x {
|
|
|
243
243
|
return t = t.slice(0, -1), t;
|
|
244
244
|
}
|
|
245
245
|
}
|
|
246
|
-
class
|
|
246
|
+
class O {
|
|
247
247
|
key;
|
|
248
248
|
value;
|
|
249
249
|
constructor(t, e) {
|
|
250
250
|
this.key = t, this.value = e;
|
|
251
251
|
}
|
|
252
252
|
}
|
|
253
|
-
function
|
|
254
|
-
return
|
|
253
|
+
function M(n, t = { emptyString: !1, zeroNumber: !1 }) {
|
|
254
|
+
return n == null ? !(t.emptyString && n === "" || t.zeroNumber && n === 0) : !1;
|
|
255
255
|
}
|
|
256
|
-
class
|
|
256
|
+
class k {
|
|
257
257
|
table = [];
|
|
258
258
|
constructor() {
|
|
259
259
|
}
|
|
260
260
|
getItemIndex(t) {
|
|
261
|
-
for (let e = 0,
|
|
261
|
+
for (let e = 0, s = this.table.length; e < s; e++)
|
|
262
262
|
if (this.table[e].key === t)
|
|
263
263
|
return e;
|
|
264
264
|
return -1;
|
|
265
265
|
}
|
|
266
266
|
set(t, e) {
|
|
267
|
-
if (
|
|
267
|
+
if (M(t))
|
|
268
268
|
throw new Error("key is required");
|
|
269
|
-
if (
|
|
269
|
+
if (M(e))
|
|
270
270
|
throw new Error("value is required");
|
|
271
271
|
if (this.has(t)) {
|
|
272
|
-
let
|
|
273
|
-
this.table[
|
|
272
|
+
let s = this.getItemIndex(t);
|
|
273
|
+
this.table[s].value = e;
|
|
274
274
|
} else {
|
|
275
|
-
const
|
|
276
|
-
this.table.push(
|
|
275
|
+
const s = new O(t, e);
|
|
276
|
+
this.table.push(s);
|
|
277
277
|
}
|
|
278
278
|
}
|
|
279
279
|
remove(t) {
|
|
@@ -301,9 +301,9 @@ class d {
|
|
|
301
301
|
return this.table.map((t) => [t.key, t.value]);
|
|
302
302
|
}
|
|
303
303
|
forEach(t) {
|
|
304
|
-
for (let e = 0,
|
|
305
|
-
let
|
|
306
|
-
if (!t(
|
|
304
|
+
for (let e = 0, s = this.size(); e < s; e++) {
|
|
305
|
+
let i = this.table[e];
|
|
306
|
+
if (!t(i.key, i.value))
|
|
307
307
|
break;
|
|
308
308
|
}
|
|
309
309
|
}
|
|
@@ -318,17 +318,17 @@ class d {
|
|
|
318
318
|
}
|
|
319
319
|
toString() {
|
|
320
320
|
let t = "";
|
|
321
|
-
for (let e = 0,
|
|
321
|
+
for (let e = 0, s = this.table.length; e < s; e++)
|
|
322
322
|
t += this.table[e].toString(), t += ",";
|
|
323
323
|
return t = t.slice(0, -1), t;
|
|
324
324
|
}
|
|
325
325
|
}
|
|
326
|
-
class
|
|
326
|
+
class D {
|
|
327
327
|
isDirected;
|
|
328
328
|
vertices;
|
|
329
329
|
adjList;
|
|
330
330
|
constructor(t = !1) {
|
|
331
|
-
this.isDirected = t, this.vertices = [], this.adjList = new
|
|
331
|
+
this.isDirected = t, this.vertices = [], this.adjList = new k();
|
|
332
332
|
}
|
|
333
333
|
addVertex(t) {
|
|
334
334
|
this.vertices.includes(t) || (this.vertices.push(t), this.adjList.set(t, []));
|
|
@@ -350,27 +350,683 @@ class y {
|
|
|
350
350
|
return t;
|
|
351
351
|
}
|
|
352
352
|
}
|
|
353
|
-
|
|
353
|
+
class f {
|
|
354
|
+
_data;
|
|
355
|
+
static zero(t) {
|
|
356
|
+
return new f(...Array(t).fill(0));
|
|
357
|
+
}
|
|
358
|
+
constructor(...t) {
|
|
359
|
+
this._data = t;
|
|
360
|
+
}
|
|
361
|
+
get dimension() {
|
|
362
|
+
return this._data.length;
|
|
363
|
+
}
|
|
364
|
+
get norm() {
|
|
365
|
+
return Math.hypot(...this._data);
|
|
366
|
+
}
|
|
367
|
+
getItem(t) {
|
|
368
|
+
return this._data[t];
|
|
369
|
+
}
|
|
370
|
+
normalize() {
|
|
371
|
+
const t = this.norm;
|
|
372
|
+
if (t === 0)
|
|
373
|
+
throw new Error("Cannot normalize a zero vector");
|
|
374
|
+
const e = this._data.map((s) => s / t);
|
|
375
|
+
return new f(...e);
|
|
376
|
+
}
|
|
377
|
+
add(t) {
|
|
378
|
+
if (this.dimension !== t.dimension)
|
|
379
|
+
throw new Error("Vectors must have the same dimension to add");
|
|
380
|
+
const e = this._data.map(
|
|
381
|
+
(s, i) => s + t._data[i]
|
|
382
|
+
);
|
|
383
|
+
return new f(...e);
|
|
384
|
+
}
|
|
385
|
+
sub(t) {
|
|
386
|
+
if (this.dimension !== t.dimension)
|
|
387
|
+
throw new Error("Vectors must have the same dimension to subtract");
|
|
388
|
+
const e = this._data.map(
|
|
389
|
+
(s, i) => s - t._data[i]
|
|
390
|
+
);
|
|
391
|
+
return new f(...e);
|
|
392
|
+
}
|
|
393
|
+
mul(t) {
|
|
394
|
+
return new f(...this._data.map((e) => e * t));
|
|
395
|
+
}
|
|
396
|
+
dot(t) {
|
|
397
|
+
if (this.dimension !== t.dimension)
|
|
398
|
+
throw new Error("Vectors must have the same dimension to dot product");
|
|
399
|
+
return this._data.reduce(
|
|
400
|
+
(e, s, i) => e + s * t._data[i],
|
|
401
|
+
0
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
pos() {
|
|
405
|
+
return this.mul(1);
|
|
406
|
+
}
|
|
407
|
+
neg() {
|
|
408
|
+
return this.mul(-1);
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
class y {
|
|
412
|
+
_matrix;
|
|
413
|
+
static zero(t, e) {
|
|
414
|
+
return new y(
|
|
415
|
+
Array.from({ length: t }, () => Array.from({ length: e }, () => 0))
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
constructor(t) {
|
|
419
|
+
this._matrix = t;
|
|
420
|
+
}
|
|
421
|
+
get shape() {
|
|
422
|
+
return [this._matrix.length, this._matrix[0].length];
|
|
423
|
+
}
|
|
424
|
+
get row() {
|
|
425
|
+
return this.shape[0];
|
|
426
|
+
}
|
|
427
|
+
get col() {
|
|
428
|
+
return this.shape[1];
|
|
429
|
+
}
|
|
430
|
+
get size() {
|
|
431
|
+
return this.row * this.col;
|
|
432
|
+
}
|
|
433
|
+
rowVector(t) {
|
|
434
|
+
return new f(...this._matrix[t]);
|
|
435
|
+
}
|
|
436
|
+
colVector(t) {
|
|
437
|
+
return new f(...this._matrix.map((e) => e[t]));
|
|
438
|
+
}
|
|
439
|
+
getItem(t) {
|
|
440
|
+
return this._matrix[t[0]][t[1]];
|
|
441
|
+
}
|
|
442
|
+
setItem(t, e) {
|
|
443
|
+
return this._matrix[t[0]][t[1]] = e, this;
|
|
444
|
+
}
|
|
445
|
+
mul(t) {
|
|
446
|
+
return new y(this._matrix.map((e) => e.map((s) => s * t)));
|
|
447
|
+
}
|
|
448
|
+
div(t) {
|
|
449
|
+
return this.mul(1 / t);
|
|
450
|
+
}
|
|
451
|
+
add(t) {
|
|
452
|
+
if (this.row !== t.row || this.col !== t.col)
|
|
453
|
+
throw new Error("Matrix dimensions do not match");
|
|
454
|
+
return new y(
|
|
455
|
+
this._matrix.map(
|
|
456
|
+
(e, s) => e.map((i, r) => i + t.getItem([s, r]))
|
|
457
|
+
)
|
|
458
|
+
);
|
|
459
|
+
}
|
|
460
|
+
sub(t) {
|
|
461
|
+
return this.add(t.neg());
|
|
462
|
+
}
|
|
463
|
+
pos() {
|
|
464
|
+
return this.mul(1);
|
|
465
|
+
}
|
|
466
|
+
neg() {
|
|
467
|
+
return this.mul(-1);
|
|
468
|
+
}
|
|
469
|
+
mulVector(t) {
|
|
470
|
+
if (this.col !== t.dimension)
|
|
471
|
+
throw new Error("Matrix dimensions do not match");
|
|
472
|
+
return new y(
|
|
473
|
+
this._matrix.map((e) => e.map((s, i) => s * t.getItem(i)))
|
|
474
|
+
);
|
|
475
|
+
}
|
|
476
|
+
mulMatrix(t) {
|
|
477
|
+
if (this.col !== t.row)
|
|
478
|
+
throw new Error("Matrix dimensions do not match");
|
|
479
|
+
const e = y.zero(this.row, t.col);
|
|
480
|
+
for (let s = 0; s < this.row; s++) {
|
|
481
|
+
const i = this.rowVector(s);
|
|
482
|
+
for (let r = 0; r < this.col; r++)
|
|
483
|
+
e.setItem([s, r], i.dot(t.colVector(r)));
|
|
484
|
+
}
|
|
485
|
+
return e;
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
class o {
|
|
489
|
+
static distance(t, e) {
|
|
490
|
+
return Math.hypot(e.x - t.x, e.y - t.y);
|
|
491
|
+
}
|
|
492
|
+
x;
|
|
493
|
+
y;
|
|
494
|
+
constructor(t, e) {
|
|
495
|
+
this.x = t, this.y = e;
|
|
496
|
+
}
|
|
497
|
+
distanceTo(t) {
|
|
498
|
+
return o.distance(this, t);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
class c {
|
|
502
|
+
// 使用更合适的精度阈值常量
|
|
503
|
+
static EPSILON = 1e-10;
|
|
504
|
+
// 静态方法:计算斜率
|
|
505
|
+
static sloped(t) {
|
|
506
|
+
const e = t.p2.x - t.p1.x, s = t.p2.y - t.p1.y;
|
|
507
|
+
return Math.abs(e) < c.EPSILON ? Math.abs(s) < c.EPSILON ? 0 : null : s / e;
|
|
508
|
+
}
|
|
509
|
+
// 静态方法:判断两条线是否平行
|
|
510
|
+
static isParallel(t, e) {
|
|
511
|
+
const s = c.sloped(t), i = c.sloped(e);
|
|
512
|
+
return s === null && i === null ? !0 : s === null || i === null ? !1 : Math.abs(s - i) < c.EPSILON;
|
|
513
|
+
}
|
|
514
|
+
// 静态方法:获取两条线的交点
|
|
515
|
+
static getIntersection(t, e) {
|
|
516
|
+
if (c.isParallel(t, e)) return null;
|
|
517
|
+
const s = t.p1.x, i = t.p1.y, r = t.p2.x, a = t.p2.y, l = e.p1.x, u = e.p1.y, p = e.p2.x, m = e.p2.y, d = (s - r) * (u - m) - (i - a) * (l - p);
|
|
518
|
+
if (Math.abs(d) < c.EPSILON) return null;
|
|
519
|
+
const w = ((s - l) * (u - m) - (i - u) * (l - p)) / d, E = -((s - r) * (i - u) - (i - a) * (s - l)) / d;
|
|
520
|
+
if (w >= 0 && w <= 1 && E >= 0 && E <= 1) {
|
|
521
|
+
const P = s + w * (r - s), L = i + w * (a - i);
|
|
522
|
+
return new o(P, L);
|
|
523
|
+
}
|
|
524
|
+
return null;
|
|
525
|
+
}
|
|
526
|
+
// 静态方法:判断两条线段是否相交
|
|
527
|
+
static isIntersecting(t, e) {
|
|
528
|
+
return c.getIntersection(t, e) !== null;
|
|
529
|
+
}
|
|
530
|
+
// 静态方法:计算点到线段的距离
|
|
531
|
+
static distanceToPoint(t, e) {
|
|
532
|
+
const s = e.x - t.p1.x, i = e.y - t.p1.y, r = t.p2.x - t.p1.x, a = t.p2.y - t.p1.y, l = s * r + i * a, u = r * r + a * a;
|
|
533
|
+
let p = -1;
|
|
534
|
+
u > c.EPSILON && (p = l / u);
|
|
535
|
+
let m, d;
|
|
536
|
+
p < 0 ? (m = t.p1.x, d = t.p1.y) : p > 1 ? (m = t.p2.x, d = t.p2.y) : (m = t.p1.x + p * r, d = t.p1.y + p * a);
|
|
537
|
+
const w = e.x - m, E = e.y - d;
|
|
538
|
+
return Math.hypot(w + E);
|
|
539
|
+
}
|
|
540
|
+
p1;
|
|
541
|
+
p2;
|
|
542
|
+
constructor(t, e) {
|
|
543
|
+
this.p1 = t, this.p2 = e;
|
|
544
|
+
}
|
|
545
|
+
// 获取线段长度
|
|
546
|
+
get length() {
|
|
547
|
+
const t = this.p2.x - this.p1.x, e = this.p2.y - this.p1.y;
|
|
548
|
+
return Math.sqrt(t * t + e * e);
|
|
549
|
+
}
|
|
550
|
+
// 获取线段中点
|
|
551
|
+
get midpoint() {
|
|
552
|
+
const t = (this.p1.x + this.p2.x) / 2, e = (this.p1.y + this.p2.y) / 2;
|
|
553
|
+
return new o(t, e);
|
|
554
|
+
}
|
|
555
|
+
// 获取线段的角度(弧度)
|
|
556
|
+
get angle() {
|
|
557
|
+
return Math.atan2(this.p2.y - this.p1.y, this.p2.x - this.p1.x);
|
|
558
|
+
}
|
|
559
|
+
// 判断点是否在线段上
|
|
560
|
+
containsPoint(t) {
|
|
561
|
+
const e = (t.x - this.p1.x) * (this.p2.y - this.p1.y) - (t.y - this.p1.y) * (this.p2.x - this.p1.x);
|
|
562
|
+
return Math.abs(e) > c.EPSILON ? !1 : (t.x - this.p1.x) * (t.x - this.p2.x) + (t.y - this.p1.y) * (t.y - this.p2.y) <= c.EPSILON;
|
|
563
|
+
}
|
|
564
|
+
// 获取线段的方向向量
|
|
565
|
+
get direction() {
|
|
566
|
+
const t = this.length;
|
|
567
|
+
if (t < c.EPSILON) return new o(0, 0);
|
|
568
|
+
const e = (this.p2.x - this.p1.x) / t, s = (this.p2.y - this.p1.y) / t;
|
|
569
|
+
return new o(e, s);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
class S {
|
|
573
|
+
static EPSILON = 1e-10;
|
|
574
|
+
name;
|
|
575
|
+
constructor(t) {
|
|
576
|
+
this.name = t;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
class h extends S {
|
|
580
|
+
static isValid(t, e, s) {
|
|
581
|
+
return t <= 0 || e <= 0 || s <= 0 ? !1 : t + e > s && t + s > e && e + s > t;
|
|
582
|
+
}
|
|
583
|
+
static area(t, e, s) {
|
|
584
|
+
if (!h.isValid(t, e, s))
|
|
585
|
+
throw new Error("Invalid triangle");
|
|
586
|
+
const i = (t + e + s) / 2;
|
|
587
|
+
return Math.sqrt(i * (i - t) * (i - e) * (i - s));
|
|
588
|
+
}
|
|
589
|
+
static getType(t, e, s) {
|
|
590
|
+
if (!h.isValid(t, e, s))
|
|
591
|
+
throw new Error("Invalid triangle sides");
|
|
592
|
+
const i = [t, e, s].sort((u, p) => u - p), [r, a, l] = i;
|
|
593
|
+
return Math.abs(r - a) < h.EPSILON && Math.abs(a - l) < h.EPSILON ? "equilateral" : Math.abs(r - a) < h.EPSILON || Math.abs(a - l) < h.EPSILON ? "isosceles" : "scalene";
|
|
594
|
+
}
|
|
595
|
+
static getAngles(t, e, s) {
|
|
596
|
+
if (!h.isValid(t, e, s))
|
|
597
|
+
throw new Error("Invalid triangle sides");
|
|
598
|
+
const i = Math.acos((e * e + s * s - t * t) / (2 * e * s)), r = Math.acos((t * t + s * s - e * e) / (2 * t * s)), a = Math.PI - i - r;
|
|
599
|
+
return [i, r, a];
|
|
600
|
+
}
|
|
601
|
+
p1;
|
|
602
|
+
p2;
|
|
603
|
+
p3;
|
|
604
|
+
constructor(t, e, s, i = "triangle") {
|
|
605
|
+
if (super(i), this.p1 = t, this.p2 = e, this.p3 = s, this.areCollinear())
|
|
606
|
+
throw new Error("Points are collinear, cannot form a triangle");
|
|
607
|
+
}
|
|
608
|
+
// 检查三点是否共线
|
|
609
|
+
areCollinear() {
|
|
610
|
+
return Math.abs(
|
|
611
|
+
(this.p2.x - this.p1.x) * (this.p3.y - this.p1.y) - (this.p3.x - this.p1.x) * (this.p2.y - this.p1.y)
|
|
612
|
+
) < S.EPSILON;
|
|
613
|
+
}
|
|
614
|
+
get side() {
|
|
615
|
+
return [
|
|
616
|
+
o.distance(this.p1, this.p2),
|
|
617
|
+
o.distance(this.p2, this.p3),
|
|
618
|
+
o.distance(this.p3, this.p1)
|
|
619
|
+
];
|
|
620
|
+
}
|
|
621
|
+
perimeter() {
|
|
622
|
+
return h.isValid(this.side[0], this.side[1], this.side[2]), this.side.reduce((t, e) => t + e, 0);
|
|
623
|
+
}
|
|
624
|
+
area() {
|
|
625
|
+
const [t, e, s] = this.side;
|
|
626
|
+
return h.area(t, e, s);
|
|
627
|
+
}
|
|
628
|
+
get type() {
|
|
629
|
+
const [t, e, s] = this.side;
|
|
630
|
+
return h.getType(t, e, s);
|
|
631
|
+
}
|
|
632
|
+
get angles() {
|
|
633
|
+
const [t, e, s] = this.side;
|
|
634
|
+
return h.getAngles(t, e, s);
|
|
635
|
+
}
|
|
636
|
+
get centroid() {
|
|
637
|
+
return new o(
|
|
638
|
+
(this.p1.x + this.p2.x + this.p3.x) / 3,
|
|
639
|
+
(this.p1.y + this.p2.y + this.p3.y) / 3
|
|
640
|
+
);
|
|
641
|
+
}
|
|
642
|
+
get incenter() {
|
|
643
|
+
const [t, e, s] = this.side, i = this.perimeter() / 2, r = (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;
|
|
644
|
+
return new o(r, a);
|
|
645
|
+
}
|
|
646
|
+
get circumcenter() {
|
|
647
|
+
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));
|
|
648
|
+
if (Math.abs(t) < h.EPSILON)
|
|
649
|
+
throw new Error("Cannot calculate circumcenter for collinear points");
|
|
650
|
+
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;
|
|
651
|
+
return new o(e, s);
|
|
652
|
+
}
|
|
653
|
+
containsPoint(t) {
|
|
654
|
+
const e = h.area(
|
|
655
|
+
o.distance(t, this.p1),
|
|
656
|
+
o.distance(t, this.p2),
|
|
657
|
+
o.distance(this.p1, this.p2)
|
|
658
|
+
), s = h.area(
|
|
659
|
+
o.distance(t, this.p2),
|
|
660
|
+
o.distance(t, this.p3),
|
|
661
|
+
o.distance(this.p2, this.p3)
|
|
662
|
+
), i = h.area(
|
|
663
|
+
o.distance(t, this.p3),
|
|
664
|
+
o.distance(t, this.p1),
|
|
665
|
+
o.distance(this.p3, this.p1)
|
|
666
|
+
);
|
|
667
|
+
return Math.abs(e + s + i - this.area()) < h.EPSILON;
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
function F(n) {
|
|
671
|
+
return new Promise((t) => setTimeout(t, n));
|
|
672
|
+
}
|
|
673
|
+
function $(n) {
|
|
674
|
+
const t = [], e = {
|
|
675
|
+
"(": ")",
|
|
676
|
+
"[": "]",
|
|
677
|
+
"{": "}"
|
|
678
|
+
}, s = new Set(Object.values(e));
|
|
679
|
+
for (const i of n)
|
|
680
|
+
if (i in e)
|
|
681
|
+
t.push(e[i]);
|
|
682
|
+
else if (s.has(i) && i !== t.pop())
|
|
683
|
+
return !1;
|
|
684
|
+
return t.length === 0;
|
|
685
|
+
}
|
|
686
|
+
function b(n) {
|
|
687
|
+
return n !== null && (typeof n == "object" || typeof n == "function");
|
|
688
|
+
}
|
|
689
|
+
class H {
|
|
690
|
+
map = /* @__PURE__ */ new Map();
|
|
691
|
+
weakMap = /* @__PURE__ */ new WeakMap();
|
|
692
|
+
set(t, e) {
|
|
693
|
+
b(t) ? this.weakMap.set(t, e) : this.map.set(t, e);
|
|
694
|
+
}
|
|
695
|
+
get(t) {
|
|
696
|
+
return b(t) ? this.weakMap.get(t) : this.map.get(t);
|
|
697
|
+
}
|
|
698
|
+
has(t) {
|
|
699
|
+
return b(t) ? this.weakMap.has(t) : this.map.has(t);
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
function U(n) {
|
|
703
|
+
if (!n.length) return [];
|
|
704
|
+
const t = [[n[0]]];
|
|
705
|
+
for (let s = 1, i = n.length; s < i; s++) {
|
|
706
|
+
const r = n[s];
|
|
707
|
+
e(r);
|
|
708
|
+
}
|
|
709
|
+
function e(s) {
|
|
710
|
+
for (let i = t.length - 1; i >= 0; i--) {
|
|
711
|
+
const r = t[i], a = r[t[i].length - 1];
|
|
712
|
+
if (a < s) {
|
|
713
|
+
t[i + 1] = [...r, s];
|
|
714
|
+
break;
|
|
715
|
+
} else a > s && i === 0 && (t[i] = [s]);
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
return t[t.length - 1];
|
|
719
|
+
}
|
|
720
|
+
class B {
|
|
721
|
+
static ROMAN_MAP = /* @__PURE__ */ new Map([
|
|
722
|
+
["M", 1e3],
|
|
723
|
+
["CM", 900],
|
|
724
|
+
["D", 500],
|
|
725
|
+
["CD", 400],
|
|
726
|
+
["C", 100],
|
|
727
|
+
["XC", 90],
|
|
728
|
+
["L", 50],
|
|
729
|
+
["XL", 40],
|
|
730
|
+
["X", 10],
|
|
731
|
+
["IX", 9],
|
|
732
|
+
["V", 5],
|
|
733
|
+
["IV", 4],
|
|
734
|
+
["I", 1]
|
|
735
|
+
]);
|
|
736
|
+
static toInteger(t) {
|
|
737
|
+
if (t.length === 0)
|
|
738
|
+
throw new Error("Input cannot be empty");
|
|
739
|
+
const e = /* @__PURE__ */ new Set(["I", "V", "X", "L", "C", "D", "M"]);
|
|
740
|
+
for (const a of t)
|
|
741
|
+
if (!e.has(a))
|
|
742
|
+
throw new Error(`Invalid Roman numeral character: ${a}`);
|
|
743
|
+
let s = 0, i = 0;
|
|
744
|
+
for (; i < t.length; ) {
|
|
745
|
+
const a = t.slice(i, i + 2);
|
|
746
|
+
if (this.ROMAN_MAP.has(a))
|
|
747
|
+
s += this.ROMAN_MAP.get(a), i += 2;
|
|
748
|
+
else {
|
|
749
|
+
const l = t[i], u = this.ROMAN_MAP.get(l);
|
|
750
|
+
if (!u)
|
|
751
|
+
throw new Error(`Invalid Roman numeral sequence at position ${i}`);
|
|
752
|
+
s += u, i += 1;
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
if (this.toRoman(s) !== t)
|
|
756
|
+
throw new Error("Invalid Roman numeral sequence");
|
|
757
|
+
return s;
|
|
758
|
+
}
|
|
759
|
+
static toRoman(t) {
|
|
760
|
+
if (t <= 0 || t >= 4e3)
|
|
761
|
+
throw new Error("Number must be between 1 and 3999");
|
|
762
|
+
if (!Number.isInteger(t))
|
|
763
|
+
throw new Error("Number must be an integer");
|
|
764
|
+
let e = "";
|
|
765
|
+
for (const [s, i] of this.ROMAN_MAP)
|
|
766
|
+
for (; t >= i; )
|
|
767
|
+
e += s, t -= i;
|
|
768
|
+
return e;
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
function X(n) {
|
|
354
772
|
let t;
|
|
355
|
-
const e = new Proxy(
|
|
356
|
-
construct(i, r
|
|
773
|
+
const e = new Proxy(n, {
|
|
774
|
+
construct(s, i, r) {
|
|
357
775
|
return t || (t = Reflect.construct(
|
|
776
|
+
s,
|
|
358
777
|
i,
|
|
359
|
-
r
|
|
360
|
-
h
|
|
778
|
+
r
|
|
361
779
|
)), t;
|
|
362
780
|
}
|
|
363
781
|
});
|
|
364
|
-
return
|
|
782
|
+
return n.prototype.constructor = e, e;
|
|
783
|
+
}
|
|
784
|
+
const x = {
|
|
785
|
+
scriptRegex: /<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
|
|
786
|
+
javascriptRegex: /javascript:/gi,
|
|
787
|
+
eventHandlerRegex: /on\w+\s*=/gi,
|
|
788
|
+
allowedTags: /* @__PURE__ */ new Set([
|
|
789
|
+
"div",
|
|
790
|
+
"span",
|
|
791
|
+
"p",
|
|
792
|
+
"a",
|
|
793
|
+
"img",
|
|
794
|
+
"button",
|
|
795
|
+
"input",
|
|
796
|
+
"form",
|
|
797
|
+
"label",
|
|
798
|
+
"select",
|
|
799
|
+
"option",
|
|
800
|
+
"textarea",
|
|
801
|
+
"ul",
|
|
802
|
+
"ol",
|
|
803
|
+
"li",
|
|
804
|
+
"table",
|
|
805
|
+
"tr",
|
|
806
|
+
"td",
|
|
807
|
+
"th",
|
|
808
|
+
"thead",
|
|
809
|
+
"tbody",
|
|
810
|
+
"tfoot",
|
|
811
|
+
"h1",
|
|
812
|
+
"h2",
|
|
813
|
+
"h3",
|
|
814
|
+
"h4",
|
|
815
|
+
"h5",
|
|
816
|
+
"h6",
|
|
817
|
+
"hr",
|
|
818
|
+
"br",
|
|
819
|
+
"section",
|
|
820
|
+
"article",
|
|
821
|
+
"nav",
|
|
822
|
+
"header",
|
|
823
|
+
"footer",
|
|
824
|
+
"main",
|
|
825
|
+
"aside",
|
|
826
|
+
"figure",
|
|
827
|
+
"figcaption"
|
|
828
|
+
]),
|
|
829
|
+
allowedAttributes: /* @__PURE__ */ new Set(["class", "id", "href", "src", "alt", "title"])
|
|
830
|
+
};
|
|
831
|
+
class v {
|
|
832
|
+
static instance;
|
|
833
|
+
constructor() {
|
|
834
|
+
}
|
|
835
|
+
static getInstance() {
|
|
836
|
+
return v.instance || (v.instance = new v()), v.instance;
|
|
837
|
+
}
|
|
838
|
+
/**
|
|
839
|
+
* 创建DOM元素
|
|
840
|
+
* @param tagName 标签名
|
|
841
|
+
* @param attributes 属性对象
|
|
842
|
+
* @param content 元素内容
|
|
843
|
+
* @returns 创建的HTMLElement
|
|
844
|
+
*/
|
|
845
|
+
createElement(t, e = {}, s = "") {
|
|
846
|
+
if (!x.allowedTags.has(t.toLowerCase()))
|
|
847
|
+
throw new Error(`Unsupported tag: ${t}`);
|
|
848
|
+
const i = document.createElement(t);
|
|
849
|
+
return this._processAttributes(i, e), this._processContent(i, s), i;
|
|
850
|
+
}
|
|
851
|
+
/**
|
|
852
|
+
* 批量创建元素
|
|
853
|
+
* @param items 元素配置数组
|
|
854
|
+
* @param container 容器元素
|
|
855
|
+
*/
|
|
856
|
+
createBatch(t, e) {
|
|
857
|
+
const s = document.createDocumentFragment();
|
|
858
|
+
t.forEach((i) => {
|
|
859
|
+
const r = this.createElement(
|
|
860
|
+
i.tag,
|
|
861
|
+
i.attributes || {},
|
|
862
|
+
i.content || ""
|
|
863
|
+
);
|
|
864
|
+
s.appendChild(r);
|
|
865
|
+
}), e.appendChild(s);
|
|
866
|
+
}
|
|
867
|
+
/**
|
|
868
|
+
* 安全地设置HTML内容
|
|
869
|
+
* @param element 目标元素
|
|
870
|
+
* @param html HTML字符串
|
|
871
|
+
*/
|
|
872
|
+
setHtml(t, e) {
|
|
873
|
+
const s = this._sanitizeHtml(e);
|
|
874
|
+
t.innerHTML = s;
|
|
875
|
+
}
|
|
876
|
+
/**
|
|
877
|
+
* 处理元素属性
|
|
878
|
+
* @private
|
|
879
|
+
*/
|
|
880
|
+
_processAttributes(t, e) {
|
|
881
|
+
Object.entries(e).forEach(([s, i]) => {
|
|
882
|
+
if (!x.allowedAttributes.has(s) && !s.startsWith("data-")) {
|
|
883
|
+
console.warn(`Potentially unsafe attribute: ${s}`);
|
|
884
|
+
return;
|
|
885
|
+
}
|
|
886
|
+
if (typeof i == "function")
|
|
887
|
+
s.startsWith("on") && t.addEventListener(
|
|
888
|
+
s.slice(2).toLowerCase(),
|
|
889
|
+
i
|
|
890
|
+
);
|
|
891
|
+
else
|
|
892
|
+
switch (s) {
|
|
893
|
+
case "className":
|
|
894
|
+
t.className = i;
|
|
895
|
+
break;
|
|
896
|
+
case "dataset":
|
|
897
|
+
Object.assign(t.dataset, i);
|
|
898
|
+
break;
|
|
899
|
+
case "style":
|
|
900
|
+
Object.assign(t.style, i);
|
|
901
|
+
break;
|
|
902
|
+
default:
|
|
903
|
+
t.setAttribute(s, i);
|
|
904
|
+
}
|
|
905
|
+
});
|
|
906
|
+
}
|
|
907
|
+
/**
|
|
908
|
+
* 处理元素内容
|
|
909
|
+
* @private
|
|
910
|
+
*/
|
|
911
|
+
_processContent(t, e) {
|
|
912
|
+
typeof e == "string" ? t.textContent = e : e instanceof Node ? t.appendChild(e) : Array.isArray(e) && e.forEach((s) => {
|
|
913
|
+
typeof s == "string" ? t.appendChild(document.createTextNode(s)) : t.appendChild(s);
|
|
914
|
+
});
|
|
915
|
+
}
|
|
916
|
+
/**
|
|
917
|
+
* 清理HTML字符串
|
|
918
|
+
* @private
|
|
919
|
+
*/
|
|
920
|
+
_sanitizeHtml(t) {
|
|
921
|
+
return t.replace(x.scriptRegex, "").replace(x.javascriptRegex, "").replace(x.eventHandlerRegex, "");
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
class G {
|
|
925
|
+
features;
|
|
926
|
+
constructor() {
|
|
927
|
+
this.features = this.detectFeatures();
|
|
928
|
+
}
|
|
929
|
+
detectFeatures() {
|
|
930
|
+
return {
|
|
931
|
+
geolocation: "geolocation" in navigator,
|
|
932
|
+
notification: "Notification" in window,
|
|
933
|
+
serviceWorker: "serviceWorker" in navigator,
|
|
934
|
+
webShare: "share" in navigator,
|
|
935
|
+
deviceOrientation: "DeviceOrientationEvent" in window,
|
|
936
|
+
battery: "getBattery" in navigator,
|
|
937
|
+
online: "onLine" in navigator
|
|
938
|
+
};
|
|
939
|
+
}
|
|
940
|
+
async getLocation(t = {}) {
|
|
941
|
+
if (!this.features.geolocation)
|
|
942
|
+
throw new Error("Geolocation is not supported");
|
|
943
|
+
const e = {
|
|
944
|
+
enableHighAccuracy: !0,
|
|
945
|
+
timeout: 10 * 1e3,
|
|
946
|
+
maximumAge: 300 * 1e3
|
|
947
|
+
};
|
|
948
|
+
return new Promise((s, i) => {
|
|
949
|
+
navigator.geolocation.getCurrentPosition(
|
|
950
|
+
(r) => s({
|
|
951
|
+
latitude: r.coords.latitude,
|
|
952
|
+
longitude: r.coords.longitude,
|
|
953
|
+
accuracy: r.coords.accuracy,
|
|
954
|
+
timstamp: r.timestamp
|
|
955
|
+
}),
|
|
956
|
+
(r) => {
|
|
957
|
+
const a = {
|
|
958
|
+
1: "User denied the request for Geolocation.",
|
|
959
|
+
2: "Position information is unavailable.",
|
|
960
|
+
3: "The request to get user location timed out."
|
|
961
|
+
};
|
|
962
|
+
i(new Error(a[r.code] || "Unknown error"));
|
|
963
|
+
},
|
|
964
|
+
{ ...e, ...t }
|
|
965
|
+
);
|
|
966
|
+
});
|
|
967
|
+
}
|
|
968
|
+
async sendNotification(t, e) {
|
|
969
|
+
if (!this.features.notification)
|
|
970
|
+
throw new Error("Notification is not supported");
|
|
971
|
+
if (Notification.permission === "default" && await Notification.requestPermission() !== "granted")
|
|
972
|
+
throw new Error("Notification permission is not granted");
|
|
973
|
+
if (Notification.permission !== "granted")
|
|
974
|
+
throw new Error("Notification permission is not granted");
|
|
975
|
+
return new Notification(t, {
|
|
976
|
+
icon: e.icon,
|
|
977
|
+
badge: e.badge,
|
|
978
|
+
...e
|
|
979
|
+
});
|
|
980
|
+
}
|
|
981
|
+
async registerServiceWorker(t) {
|
|
982
|
+
if (!this.features.serviceWorker)
|
|
983
|
+
throw new Error("Service Worker is not supported");
|
|
984
|
+
try {
|
|
985
|
+
const e = await navigator.serviceWorker.register(t);
|
|
986
|
+
return console.log("Service Worker registered with scope:", e), e;
|
|
987
|
+
} catch (e) {
|
|
988
|
+
throw console.error("Service Worker registration failed:", e), e;
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
async shareContent(t) {
|
|
992
|
+
if (this.features.webShare)
|
|
993
|
+
try {
|
|
994
|
+
return await navigator.share(t), !0;
|
|
995
|
+
} catch (e) {
|
|
996
|
+
return e instanceof Error && e.name != "AbortError" && console.error("Error sharing content:", e), !1;
|
|
997
|
+
}
|
|
998
|
+
else
|
|
999
|
+
try {
|
|
1000
|
+
return await navigator.clipboard.writeText(
|
|
1001
|
+
t.url || t.text || ""
|
|
1002
|
+
), this.sendNotification("Copied to clipboard", {
|
|
1003
|
+
body: "Link copied to clipboard"
|
|
1004
|
+
}), !0;
|
|
1005
|
+
} catch (e) {
|
|
1006
|
+
return console.error("Error copying to clipboard:", e), !1;
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
365
1009
|
}
|
|
366
1010
|
export {
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
1011
|
+
k as Dictionary,
|
|
1012
|
+
v as DomHelper,
|
|
1013
|
+
D as Graph,
|
|
1014
|
+
U as LIS,
|
|
1015
|
+
V as LRU,
|
|
1016
|
+
c as Line,
|
|
1017
|
+
W as LinkedList,
|
|
1018
|
+
y as Matrix,
|
|
1019
|
+
R as MaxHeap,
|
|
1020
|
+
H as MemoizeMap,
|
|
1021
|
+
A as MinHeap,
|
|
1022
|
+
o as Point,
|
|
1023
|
+
z as Queue,
|
|
1024
|
+
B as Roman,
|
|
1025
|
+
j as Stack,
|
|
1026
|
+
h as Triangle,
|
|
1027
|
+
f as Vector,
|
|
1028
|
+
G as WebAppManager,
|
|
1029
|
+
$ as isValidBracket,
|
|
1030
|
+
X as singleton,
|
|
1031
|
+
F as sleep
|
|
376
1032
|
};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(
|
|
2
|
-
`;return t}}function x(s){let t;const e=new Proxy(s,{construct(i,r,n){return t||(t=Reflect.construct(i,r,n)),t}});return s.prototype.constructor=e,e}h.Dictionary=d,h.Graph=w,h.LRU=v,h.LinkedList=y,h.MaxHeap=g,h.MinHeap=l,h.Queue=a,h.Stack=f,h.singleton=x,Object.defineProperty(h,Symbol.toStringTag,{value:"Module"})}));
|
|
1
|
+
(function(o,E){typeof exports=="object"&&typeof module<"u"?E(exports):typeof define=="function"&&define.amd?define(["exports"],E):(o=typeof globalThis<"u"?globalThis:o||self,E(o["jc-structure"]={}))})(this,(function(o){"use strict";class E{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){t.forEach(e=>{this.items[this.count]=e,this.count++})}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 O{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){t.forEach(e=>{this.items[this.count]=e,this.count++})}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]`}}function S(n,t){return n===t?0:n<t?-1:1}class g{heap=[];compareFn;constructor(t=S){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 L extends g{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=g.getLeftIndex(e),i=g.getRightIndex(e),r=this.size();s<r&&this.compareFn(this.heap[e],this.heap[s])===-1&&(e=s),i<r&&this.compareFn(this.heap[e],this.heap[i])===1&&(e=i),e!==t&&(g.swap(this.heap,t,e),this.siftUp(e))}siftDown(t){let e=g.getParentIndex(t);for(;t>0&&e&&this.compareFn(this.heap[e],this.heap[t])===1;)g.swap(this.heap,e,t),t=e,e=g.getParentIndex(t)}}class k extends L{constructor(t=(e,s)=>S(s,e)){super(t)}}function z(n){return{value:n}}class j{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=z(e),this.length++,this.prepend(s),this.trimCache(),this.lookup.set(t,s),this.reverseLookup)}}let N=class{value;next=void 0};class R{count=0;head=void 0;constructor(){}indexOf(t){let e=this.head,s=0,i=!1;for(;e;){if(this.equals(e.value,t)){i=!0;break}s++,e=e.next}return i?s:-1}equals(t,e){return!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 N;if(s.value=t,e>this.count||e<0)throw new Error("index error");this.count++;let i,r;if(e===0){s.next=this.head,this.head=s;return}i=this.getElementAt(e-1),r=i.next,i.next=s,s.next=r}push(t){let e=new N;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),i=e?.next;return t===0&&(this.head=i),s&&(s.next=i),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 V{key;value;constructor(t,e){this.key=t,this.value=e}}function P(n,t={emptyString:!1,zeroNumber:!1}){return n==null?!(t.emptyString&&n===""||t.zeroNumber&&n===0):!1}class A{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(P(t))throw new Error("key is required");if(P(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 V(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 i=this.table[e];if(!t(i.key,i.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 q{isDirected;vertices;adjList;constructor(t=!1){this.isDirected=t,this.vertices=[],this.adjList=new A}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 f{_data;static zero(t){return new f(...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 f(...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 f(...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 f(...e)}mul(t){return new f(...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 w{_matrix;static zero(t,e){return new w(Array.from({length:t},()=>Array.from({length:e},()=>0)))}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 f(...this._matrix[t])}colVector(t){return new f(...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 w(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 w(this._matrix.map((e,s)=>e.map((i,r)=>i+t.getItem([s,r]))))}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 w(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=w.zero(this.row,t.col);for(let s=0;s<this.row;s++){const i=this.rowVector(s);for(let r=0;r<this.col;r++)e.setItem([s,r],i.dot(t.colVector(r)))}return e}}class h{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 h.distance(this,t)}}class u{static EPSILON=1e-10;static sloped(t){const e=t.p2.x-t.p1.x,s=t.p2.y-t.p1.y;return Math.abs(e)<u.EPSILON?Math.abs(s)<u.EPSILON?0:null:s/e}static isParallel(t,e){const s=u.sloped(t),i=u.sloped(e);return s===null&&i===null?!0:s===null||i===null?!1:Math.abs(s-i)<u.EPSILON}static getIntersection(t,e){if(u.isParallel(t,e))return null;const s=t.p1.x,i=t.p1.y,r=t.p2.x,a=t.p2.y,p=e.p1.x,l=e.p1.y,d=e.p2.x,y=e.p2.y,m=(s-r)*(l-y)-(i-a)*(p-d);if(Math.abs(m)<u.EPSILON)return null;const v=((s-p)*(l-y)-(i-l)*(p-d))/m,I=-((s-r)*(i-l)-(i-a)*(s-p))/m;if(v>=0&&v<=1&&I>=0&&I<=1){const X=s+v*(r-s),G=i+v*(a-i);return new h(X,G)}return null}static isIntersecting(t,e){return u.getIntersection(t,e)!==null}static distanceToPoint(t,e){const s=e.x-t.p1.x,i=e.y-t.p1.y,r=t.p2.x-t.p1.x,a=t.p2.y-t.p1.y,p=s*r+i*a,l=r*r+a*a;let d=-1;l>u.EPSILON&&(d=p/l);let y,m;d<0?(y=t.p1.x,m=t.p1.y):d>1?(y=t.p2.x,m=t.p2.y):(y=t.p1.x+d*r,m=t.p1.y+d*a);const v=e.x-y,I=e.y-m;return Math.hypot(v+I)}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 h(t,e)}get angle(){return Math.atan2(this.p2.y-this.p1.y,this.p2.x-this.p1.x)}containsPoint(t){const e=(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(e)>u.EPSILON?!1:(t.x-this.p1.x)*(t.x-this.p2.x)+(t.y-this.p1.y)*(t.y-this.p2.y)<=u.EPSILON}get direction(){const t=this.length;if(t<u.EPSILON)return new h(0,0);const e=(this.p2.x-this.p1.x)/t,s=(this.p2.y-this.p1.y)/t;return new h(e,s)}}class C{static EPSILON=1e-10;name;constructor(t){this.name=t}}class c 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(!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((l,d)=>l-d),[r,a,p]=i;return Math.abs(r-a)<c.EPSILON&&Math.abs(a-p)<c.EPSILON?"equilateral":Math.abs(r-a)<c.EPSILON||Math.abs(a-p)<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)),r=Math.acos((t*t+s*s-e*e)/(2*t*s)),a=Math.PI-i-r;return[i,r,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))<C.EPSILON}get side(){return[h.distance(this.p1,this.p2),h.distance(this.p2,this.p3),h.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 h((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,r=(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 h(r,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 h(e,s)}containsPoint(t){const e=c.area(h.distance(t,this.p1),h.distance(t,this.p2),h.distance(this.p1,this.p2)),s=c.area(h.distance(t,this.p2),h.distance(t,this.p3),h.distance(this.p2,this.p3)),i=c.area(h.distance(t,this.p3),h.distance(t,this.p1),h.distance(this.p3,this.p1));return Math.abs(e+s+i-this.area())<c.EPSILON}}function D(n){return new Promise(t=>setTimeout(t,n))}function W(n){const t=[],e={"(":")","[":"]","{":"}"},s=new Set(Object.values(e));for(const i of n)if(i in e)t.push(e[i]);else if(s.has(i)&&i!==t.pop())return!1;return t.length===0}function M(n){return n!==null&&(typeof n=="object"||typeof n=="function")}class H{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)}}function F(n){if(!n.length)return[];const t=[[n[0]]];for(let s=1,i=n.length;s<i;s++){const r=n[s];e(r)}function e(s){for(let i=t.length-1;i>=0;i--){const r=t[i],a=r[t[i].length-1];if(a<s){t[i+1]=[...r,s];break}else a>s&&i===0&&(t[i]=[s])}}return t[t.length-1]}class ${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 p=t[i],l=this.ROMAN_MAP.get(p);if(!l)throw new Error(`Invalid Roman numeral sequence at position ${i}`);s+=l,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}}function U(n){let t;const e=new Proxy(n,{construct(s,i,r){return t||(t=Reflect.construct(s,i,r)),t}});return n.prototype.constructor=e,e}const b={scriptRegex:/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,javascriptRegex:/javascript:/gi,eventHandlerRegex:/on\w+\s*=/gi,allowedTags:new Set(["div","span","p","a","img","button","input","form","label","select","option","textarea","ul","ol","li","table","tr","td","th","thead","tbody","tfoot","h1","h2","h3","h4","h5","h6","hr","br","section","article","nav","header","footer","main","aside","figure","figcaption"]),allowedAttributes:new Set(["class","id","href","src","alt","title"])};class x{static instance;constructor(){}static getInstance(){return x.instance||(x.instance=new x),x.instance}createElement(t,e={},s=""){if(!b.allowedTags.has(t.toLowerCase()))throw new Error(`Unsupported tag: ${t}`);const i=document.createElement(t);return this._processAttributes(i,e),this._processContent(i,s),i}createBatch(t,e){const s=document.createDocumentFragment();t.forEach(i=>{const r=this.createElement(i.tag,i.attributes||{},i.content||"");s.appendChild(r)}),e.appendChild(s)}setHtml(t,e){const s=this._sanitizeHtml(e);t.innerHTML=s}_processAttributes(t,e){Object.entries(e).forEach(([s,i])=>{if(!b.allowedAttributes.has(s)&&!s.startsWith("data-")){console.warn(`Potentially unsafe attribute: ${s}`);return}if(typeof i=="function")s.startsWith("on")&&t.addEventListener(s.slice(2).toLowerCase(),i);else switch(s){case"className":t.className=i;break;case"dataset":Object.assign(t.dataset,i);break;case"style":Object.assign(t.style,i);break;default:t.setAttribute(s,i)}})}_processContent(t,e){typeof e=="string"?t.textContent=e:e instanceof Node?t.appendChild(e):Array.isArray(e)&&e.forEach(s=>{typeof s=="string"?t.appendChild(document.createTextNode(s)):t.appendChild(s)})}_sanitizeHtml(t){return t.replace(b.scriptRegex,"").replace(b.javascriptRegex,"").replace(b.eventHandlerRegex,"")}}class B{features;constructor(){this.features=this.detectFeatures()}detectFeatures(){return{geolocation:"geolocation"in navigator,notification:"Notification"in window,serviceWorker:"serviceWorker"in navigator,webShare:"share"in navigator,deviceOrientation:"DeviceOrientationEvent"in window,battery:"getBattery"in navigator,online:"onLine"in navigator}}async getLocation(t={}){if(!this.features.geolocation)throw new Error("Geolocation is not supported");const e={enableHighAccuracy:!0,timeout:10*1e3,maximumAge:300*1e3};return new Promise((s,i)=>{navigator.geolocation.getCurrentPosition(r=>s({latitude:r.coords.latitude,longitude:r.coords.longitude,accuracy:r.coords.accuracy,timstamp:r.timestamp}),r=>{const a={1:"User denied the request for Geolocation.",2:"Position information is unavailable.",3:"The request to get user location timed out."};i(new Error(a[r.code]||"Unknown error"))},{...e,...t})})}async sendNotification(t,e){if(!this.features.notification)throw new Error("Notification is not supported");if(Notification.permission==="default"&&await Notification.requestPermission()!=="granted")throw new Error("Notification permission is not granted");if(Notification.permission!=="granted")throw new Error("Notification permission is not granted");return new Notification(t,{icon:e.icon,badge:e.badge,...e})}async registerServiceWorker(t){if(!this.features.serviceWorker)throw new Error("Service Worker is not supported");try{const e=await navigator.serviceWorker.register(t);return console.log("Service Worker registered with scope:",e),e}catch(e){throw console.error("Service Worker registration failed:",e),e}}async shareContent(t){if(this.features.webShare)try{return await navigator.share(t),!0}catch(e){return e instanceof Error&&e.name!="AbortError"&&console.error("Error sharing content:",e),!1}else try{return await navigator.clipboard.writeText(t.url||t.text||""),this.sendNotification("Copied to clipboard",{body:"Link copied to clipboard"}),!0}catch(e){return console.error("Error copying to clipboard:",e),!1}}}o.Dictionary=A,o.DomHelper=x,o.Graph=q,o.LIS=F,o.LRU=j,o.Line=u,o.LinkedList=R,o.Matrix=w,o.MaxHeap=k,o.MemoizeMap=H,o.MinHeap=L,o.Point=h,o.Queue=E,o.Roman=$,o.Stack=O,o.Triangle=c,o.Vector=f,o.WebAppManager=B,o.isValidBracket=W,o.singleton=U,o.sleep=D,Object.defineProperty(o,Symbol.toStringTag,{value:"Module"})}));
|
package/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { Vector } from "./lib/dataStructure";
|
|
2
|
+
|
|
1
3
|
declare module "jc-structure" {
|
|
2
4
|
/**
|
|
3
5
|
* 栈类,采用object实现
|
|
@@ -292,6 +294,214 @@ declare module "jc-structure" {
|
|
|
292
294
|
getAdjacencyList(): IDictionary<T, Array<T>>;
|
|
293
295
|
}
|
|
294
296
|
|
|
297
|
+
/**
|
|
298
|
+
* ### 缓存类
|
|
299
|
+
*/
|
|
300
|
+
export class MemoizeMap {
|
|
301
|
+
/**
|
|
302
|
+
* 根据键的类型,判断缓存在 Map 还是 WeakMap中
|
|
303
|
+
* @param key 键值
|
|
304
|
+
* @param value 值
|
|
305
|
+
*/
|
|
306
|
+
set(key: unknown, value: unknown): void;
|
|
307
|
+
/**
|
|
308
|
+
* #### 根据键获取缓存的值
|
|
309
|
+
* @param key
|
|
310
|
+
*/
|
|
311
|
+
get(key: unknown): any;
|
|
312
|
+
/**
|
|
313
|
+
* #### 判断缓存中是否存在该键
|
|
314
|
+
* @param key
|
|
315
|
+
*/
|
|
316
|
+
has(key: unknown): boolean;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* 罗马数字类
|
|
321
|
+
*/
|
|
322
|
+
export class Roman {
|
|
323
|
+
/**
|
|
324
|
+
* #### 转阿拉伯数字
|
|
325
|
+
* @param str 罗马数字文本
|
|
326
|
+
*/
|
|
327
|
+
static toInteger(str: string): number;
|
|
328
|
+
/**
|
|
329
|
+
* #### 转罗马数字
|
|
330
|
+
* @param num 阿拉伯整数
|
|
331
|
+
*/
|
|
332
|
+
static toRoman(num: number): string;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
export class Point {
|
|
336
|
+
/**
|
|
337
|
+
* #### 点类构造函数
|
|
338
|
+
* @param x x坐标
|
|
339
|
+
* @param y y坐标
|
|
340
|
+
*/
|
|
341
|
+
constructor(x: number, y: number);
|
|
342
|
+
/**
|
|
343
|
+
* #### 计算两点之间的距离
|
|
344
|
+
* @param p1 点1
|
|
345
|
+
* @param p2 点2
|
|
346
|
+
*/
|
|
347
|
+
static distance(p1: Point, p2: Point): number;
|
|
348
|
+
/**
|
|
349
|
+
* #### 计算点与点之间的距离,实例方法
|
|
350
|
+
* @param p 点p
|
|
351
|
+
*/
|
|
352
|
+
distanceTo(p: Point): number;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
export class line {
|
|
356
|
+
/**
|
|
357
|
+
* #### 线段长度
|
|
358
|
+
*/
|
|
359
|
+
get length(): number;
|
|
360
|
+
/**
|
|
361
|
+
* #### 线段中点
|
|
362
|
+
*/
|
|
363
|
+
get midpoint(): Point;
|
|
364
|
+
/**
|
|
365
|
+
* #### 线段角度(弧度)
|
|
366
|
+
*/
|
|
367
|
+
get angle(): number;
|
|
368
|
+
/**
|
|
369
|
+
* #### 获取线段的方向向量
|
|
370
|
+
*/
|
|
371
|
+
get direction(): Point;
|
|
372
|
+
/**
|
|
373
|
+
* #### 判断点是否在线段上
|
|
374
|
+
* @param point
|
|
375
|
+
*/
|
|
376
|
+
containsPoint(point: Point): boolean;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
/**
|
|
380
|
+
* ### 三角形类
|
|
381
|
+
*/
|
|
382
|
+
export class Triangle {
|
|
383
|
+
/**
|
|
384
|
+
* #### 判断三条边是否能构成三角形
|
|
385
|
+
* @param a 边长
|
|
386
|
+
* @param b 边长
|
|
387
|
+
* @param c 边长
|
|
388
|
+
*/
|
|
389
|
+
static isValid(a: number, b: number, c: number): boolean;
|
|
390
|
+
/**
|
|
391
|
+
* #### 计算三角形的面积,采用秦九昭公式或叫海伦面积公式
|
|
392
|
+
* @param a 边长
|
|
393
|
+
* @param b 边长
|
|
394
|
+
* @param c 边长
|
|
395
|
+
*/
|
|
396
|
+
static area(a: number, b: number, c: number): number;
|
|
397
|
+
/**
|
|
398
|
+
* #### 获取三角形的角度
|
|
399
|
+
* @param a 边长
|
|
400
|
+
* @param b 边长
|
|
401
|
+
* @param c 边长
|
|
402
|
+
*/
|
|
403
|
+
static getAngles(a: number, b: number, c: number): [number, number, number];
|
|
404
|
+
constructor(p1: Point, p2: Point, p3: Point): Triangle;
|
|
405
|
+
/**
|
|
406
|
+
* #### 获取三角形的边长
|
|
407
|
+
*/
|
|
408
|
+
get side(): [number, number, number];
|
|
409
|
+
/**
|
|
410
|
+
* #### 获取三角形的内心点
|
|
411
|
+
*/
|
|
412
|
+
get centroid(): Point;
|
|
413
|
+
/**
|
|
414
|
+
* #### 获取三角形的外切园心点
|
|
415
|
+
*/
|
|
416
|
+
get circumcenter(): Point;
|
|
417
|
+
/**
|
|
418
|
+
* #### 获取三角形的内切园心点
|
|
419
|
+
*/
|
|
420
|
+
get incenter(): Point;
|
|
421
|
+
/**
|
|
422
|
+
* #### 获取三角形的周长
|
|
423
|
+
*/
|
|
424
|
+
perimeter(): number;
|
|
425
|
+
/**
|
|
426
|
+
* #### 获取三角形的面积
|
|
427
|
+
*/
|
|
428
|
+
area(): number;
|
|
429
|
+
/**
|
|
430
|
+
* #### 判断点是否在三角形内
|
|
431
|
+
* @param point
|
|
432
|
+
*/
|
|
433
|
+
containsPoint(point: Point): boolean;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* ### 向量类
|
|
438
|
+
*/
|
|
439
|
+
export class Vector {
|
|
440
|
+
/**
|
|
441
|
+
* #### 获取向量的维度
|
|
442
|
+
*/
|
|
443
|
+
get dimension(): number;
|
|
444
|
+
/**
|
|
445
|
+
* #### 获取向量的模
|
|
446
|
+
*/
|
|
447
|
+
get norm(): number;
|
|
448
|
+
/**
|
|
449
|
+
* #### 根据索引获取向量元素
|
|
450
|
+
* @param index 索引
|
|
451
|
+
*/
|
|
452
|
+
getItem(index: number): number;
|
|
453
|
+
/**
|
|
454
|
+
* #### 标准化向量
|
|
455
|
+
*/
|
|
456
|
+
normalize(): Vector;
|
|
457
|
+
/**
|
|
458
|
+
* #### 向量加法
|
|
459
|
+
* @param v
|
|
460
|
+
*/
|
|
461
|
+
add(v: Vector): Vector;
|
|
462
|
+
/**
|
|
463
|
+
* #### 向量减法
|
|
464
|
+
* @param v
|
|
465
|
+
* */
|
|
466
|
+
sub(v: Vector): Vector;
|
|
467
|
+
/**
|
|
468
|
+
* #### 向量乘法
|
|
469
|
+
* @param k
|
|
470
|
+
* */
|
|
471
|
+
mul(k: number): Vector;
|
|
472
|
+
/**
|
|
473
|
+
* #### 向量点积
|
|
474
|
+
* @param v
|
|
475
|
+
* */
|
|
476
|
+
dot(v: Vector): number;
|
|
477
|
+
/**
|
|
478
|
+
* #### 向量取正
|
|
479
|
+
*/
|
|
480
|
+
pos(): Vector;
|
|
481
|
+
/**
|
|
482
|
+
* #### 向量取反
|
|
483
|
+
*/
|
|
484
|
+
neg(): Vector;
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
export class Matrix {
|
|
488
|
+
get row(): number;
|
|
489
|
+
get col(): number;
|
|
490
|
+
get size(): number;
|
|
491
|
+
rowVector(row: number): Vector;
|
|
492
|
+
colVector(col: number): Vector;
|
|
493
|
+
getItem(position: [number, number]): number;
|
|
494
|
+
setItem(position: [number, number], value: number): Matrix;
|
|
495
|
+
mul(k: number): Matrix;
|
|
496
|
+
div(k: number): Matrix;
|
|
497
|
+
add(matrix: Matrix): Matrix;
|
|
498
|
+
sub(matrix: Matrix): Matrix;
|
|
499
|
+
pos(): Matrix;
|
|
500
|
+
neg(): Matrix;
|
|
501
|
+
mulVector(vector: Vector): Vector;
|
|
502
|
+
mulMatrix(matrix: Matrix): Matrix;
|
|
503
|
+
}
|
|
504
|
+
|
|
295
505
|
/**
|
|
296
506
|
* #### 单例模式
|
|
297
507
|
* @param classCtor 类构造函数
|
|
@@ -299,4 +509,21 @@ declare module "jc-structure" {
|
|
|
299
509
|
export function singleton<T extends new (...args: any[]) => object>(
|
|
300
510
|
classCtor: T
|
|
301
511
|
): T;
|
|
512
|
+
|
|
513
|
+
/**
|
|
514
|
+
* #### 最长递增子序列
|
|
515
|
+
* @param nums
|
|
516
|
+
*/
|
|
517
|
+
export function LIS(nums: Array<number>): Array<number>;
|
|
518
|
+
/**
|
|
519
|
+
* #### 睡眠函数
|
|
520
|
+
* @param ms 毫秒
|
|
521
|
+
*/
|
|
522
|
+
export function sleep(ms: number): Promise<void>;
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* #### 判断字符串是否是有效的成对括号
|
|
526
|
+
* @param str 含括号的字符串
|
|
527
|
+
*/
|
|
528
|
+
export function isValidBracket(str: string): boolean;
|
|
302
529
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jc-structure",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.0
|
|
4
|
+
"version": "0.1.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist",
|
|
@@ -37,5 +37,8 @@
|
|
|
37
37
|
"typescript": "~5.9.2",
|
|
38
38
|
"vite": "^7.1.5",
|
|
39
39
|
"vitest": "^4.0.15"
|
|
40
|
+
},
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"es-toolkit": "^1.42.0"
|
|
40
43
|
}
|
|
41
44
|
}
|
|
@@ -0,0 +1,22 @@
|
|
|
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
|
+
}
|