@tspro/ts-utils-lib 1.0.1 → 1.2.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/index.js ADDED
@@ -0,0 +1,1104 @@
1
+ /* TsUtilsLib v1.2.0 | (c) 2023 PahkaSoft | Licensed under the MIT License */
2
+ "use strict";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: true }), mod2);
21
+ var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
22
+
23
+ // src/index.ts
24
+ var index_exports = {};
25
+ __export(index_exports, {
26
+ Assert: () => Assert,
27
+ Cookies: () => Cookies,
28
+ Device: () => Device,
29
+ LRUCache: () => LRUCache,
30
+ SmallIntCache: () => SmallIntCache,
31
+ Stack: () => Stack,
32
+ Utils: () => utils_exports,
33
+ Vec2: () => Vec2
34
+ });
35
+ module.exports = __toCommonJS(index_exports);
36
+
37
+ // src/utils/index.ts
38
+ var utils_exports = {};
39
+ __export(utils_exports, {
40
+ Arr: () => arr_exports,
41
+ Dom: () => dom_exports,
42
+ Enum: () => enum_exports,
43
+ Map: () => map_exports,
44
+ Math: () => math_exports,
45
+ Obj: () => obj_exports,
46
+ Str: () => str_exports
47
+ });
48
+
49
+ // src/utils/arr/index.ts
50
+ var arr_exports = {};
51
+ __export(arr_exports, {
52
+ arrayContains: () => arrayContains,
53
+ chunckArray: () => chunckArray,
54
+ duplicate: () => duplicate,
55
+ fillArray: () => fillArray,
56
+ getRangeArray: () => getRangeArray,
57
+ getSequenceArray: () => getSequenceArray,
58
+ isArray: () => isArray,
59
+ mapRangeArray: () => mapRangeArray,
60
+ mapSequenceArray: () => mapSequenceArray,
61
+ removeDuplicates: () => removeDuplicates,
62
+ removeDuplicatesCmp: () => removeDuplicatesCmp,
63
+ toArray: () => toArray
64
+ });
65
+
66
+ // src/utils/math/index.ts
67
+ var math_exports = {};
68
+ __export(math_exports, {
69
+ calcNormal: () => calcNormal,
70
+ clamp: () => clamp,
71
+ interpolateCoord: () => interpolateCoord,
72
+ interpolateY: () => interpolateY,
73
+ isInteger: () => isInteger,
74
+ linearToDecibels: () => linearToDecibels,
75
+ mod: () => mod,
76
+ romanize: () => romanize,
77
+ sum: () => sum,
78
+ toOrdinalNumber: () => toOrdinalNumber
79
+ });
80
+ function isInteger(n) {
81
+ return typeof n === "number" && isFinite(n) && n === Math.trunc(n);
82
+ }
83
+ function linearToDecibels(linearVolume) {
84
+ if (!isFinite(linearVolume)) {
85
+ throw new Error("linearToDecibel: Invalid linearVolume = " + linearVolume);
86
+ } else if (linearVolume <= 0) {
87
+ return -Infinity;
88
+ } else {
89
+ return 20 * Math.log10(linearVolume);
90
+ }
91
+ }
92
+ function mod(m, n) {
93
+ return (m % n + n) % n;
94
+ }
95
+ function romanize(n) {
96
+ if (!isInteger(n) || n < 0) {
97
+ throw new Error("romanize: Invalid n = " + n);
98
+ }
99
+ var digits = String(+n).split("");
100
+ var key = [
101
+ "",
102
+ "C",
103
+ "CC",
104
+ "CCC",
105
+ "CD",
106
+ "D",
107
+ "DC",
108
+ "DCC",
109
+ "DCCC",
110
+ "CM",
111
+ "",
112
+ "X",
113
+ "XX",
114
+ "XXX",
115
+ "XL",
116
+ "L",
117
+ "LX",
118
+ "LXX",
119
+ "LXXX",
120
+ "XC",
121
+ "",
122
+ "I",
123
+ "II",
124
+ "III",
125
+ "IV",
126
+ "V",
127
+ "VI",
128
+ "VII",
129
+ "VIII",
130
+ "IX"
131
+ ];
132
+ var roman = "", i = 3;
133
+ while (i--) roman = (key[+digits.pop() + i * 10] || "") + roman;
134
+ return Array(+digits.join("") + 1).join("M") + roman;
135
+ }
136
+ function toOrdinalNumber(n) {
137
+ if (!isInteger(n)) {
138
+ throw new Error("toOrdinalNumber: Invalid n = " + n);
139
+ }
140
+ const nStr = n.toString();
141
+ const lastDigit = Number(nStr.charAt(nStr.length - 1));
142
+ if (n === 1 || n >= 20 && lastDigit === 1) {
143
+ return nStr + "st";
144
+ } else if (n === 2 || n >= 20 && lastDigit === 2) {
145
+ return nStr + "nd";
146
+ } else if (n === 3 || n >= 20 && lastDigit === 3) {
147
+ return nStr + "rd";
148
+ } else {
149
+ return nStr + "th";
150
+ }
151
+ }
152
+ function interpolateCoord(startX, startY, endX, endY, t) {
153
+ return {
154
+ x: startX + (endX - startX) * t,
155
+ y: startY + (endY - startY) * t
156
+ };
157
+ }
158
+ function interpolateY(startX, startY, endX, endY, x) {
159
+ let t = (x - startX) / (endX - startX);
160
+ return startY + (endY - startY) * t;
161
+ }
162
+ function clamp(num, min, max) {
163
+ return Math.min(Math.max(num, min), max);
164
+ }
165
+ function calcNormal(x1, y1, x2, y2) {
166
+ let dx = x2 - x1;
167
+ let dy = y2 - y1;
168
+ let nx = -dy;
169
+ let ny = dx;
170
+ let len = Math.sqrt(nx * nx + ny * ny);
171
+ if (len > 0) {
172
+ nx /= len;
173
+ ny /= len;
174
+ } else {
175
+ nx = 0;
176
+ ny = 1;
177
+ }
178
+ return { nx, ny };
179
+ }
180
+ function sum(arr) {
181
+ return arr.reduce((prev, cur) => cur + prev, 0);
182
+ }
183
+
184
+ // src/utils/arr/index.ts
185
+ function isArray(a) {
186
+ return !!a && Object.prototype.toString.call(a) === "[object Array]";
187
+ }
188
+ function toArray(a) {
189
+ return isArray(a) ? a : [a];
190
+ }
191
+ function duplicate(a) {
192
+ return a === void 0 ? a : a.slice();
193
+ }
194
+ function removeDuplicates(a) {
195
+ return a.filter((item, pos, arr) => arr.indexOf(item) === pos);
196
+ }
197
+ function removeDuplicatesCmp(arr, cmp) {
198
+ return arr.filter((t1, index, self) => index === self.findIndex((t2) => cmp(t1, t2)));
199
+ }
200
+ function fillArray(fillValue, fillCount) {
201
+ if (!isInteger(fillCount) || fillCount < 0) {
202
+ throw new Error("fillArray: Invalid fillCount = " + fillCount);
203
+ }
204
+ return new Array(fillCount).fill(fillValue);
205
+ }
206
+ function mapSequenceArray(len, fn) {
207
+ if (!isInteger(len) || len < 0) {
208
+ throw new Error("mapSequenceArray: Invalid len = " + len);
209
+ }
210
+ let arr = new Array(len);
211
+ for (let i = 0; i < len; i++) {
212
+ arr[i] = fn(i);
213
+ }
214
+ return arr;
215
+ }
216
+ function getSequenceArray(len) {
217
+ return mapSequenceArray(len, (i) => i);
218
+ }
219
+ function mapRangeArray(start, end, fn) {
220
+ if (!isInteger(start)) {
221
+ throw new Error("mapRangeArray: Invalid start = " + end);
222
+ }
223
+ if (!isInteger(end)) {
224
+ throw new Error("mapRangeArray: Invalid end = " + end);
225
+ }
226
+ let len = Math.abs(end - start) + 1;
227
+ let arr = new Array(len);
228
+ for (let i = 0, s = start, inc = Math.sign(end - start); i < len; s += inc, i++) {
229
+ arr[i] = fn(s);
230
+ }
231
+ return arr;
232
+ }
233
+ function getRangeArray(start, end) {
234
+ return mapRangeArray(start, end, (i) => i);
235
+ }
236
+ function arrayContains(arg, item) {
237
+ return arg.indexOf(item) >= 0;
238
+ }
239
+ function chunckArray(arr, chunckSize) {
240
+ if (!isInteger(chunckSize) || chunckSize < 1) {
241
+ throw new Error("chunckArray: Invalid chunckSize = " + chunckSize);
242
+ }
243
+ let result = [];
244
+ for (let i = 0; i < arr.length; i += chunckSize) {
245
+ result.push(arr.slice(i, i + chunckSize));
246
+ }
247
+ return result;
248
+ }
249
+
250
+ // src/utils/dom/index.ts
251
+ var dom_exports = {};
252
+ __export(dom_exports, {
253
+ addClass: () => addClass,
254
+ appendTo: () => appendTo,
255
+ getButton: () => getButton,
256
+ getCanvas: () => getCanvas,
257
+ getCanvasTextWidth: () => getCanvasTextWidth,
258
+ getDimension: () => getDimension,
259
+ getHeight: () => getHeight,
260
+ getOffset: () => getOffset,
261
+ getPadding: () => getPadding,
262
+ getWidth: () => getWidth,
263
+ hasClass: () => hasClass,
264
+ removeClass: () => removeClass,
265
+ removeFromParent: () => removeFromParent,
266
+ setHeight: () => setHeight,
267
+ setOffset: () => setOffset,
268
+ setRect: () => setRect,
269
+ setVisibility: () => setVisibility,
270
+ setWidth: () => setWidth,
271
+ styleLayoutChanged: () => styleLayoutChanged
272
+ });
273
+
274
+ // src/utils/enum/index.ts
275
+ var enum_exports = {};
276
+ __export(enum_exports, {
277
+ getEnumValues: () => getEnumValues
278
+ });
279
+ function getEnumValues(e) {
280
+ return Object.keys(e).filter((key) => Number.isNaN(Number(key))).map((key) => e[key]);
281
+ }
282
+
283
+ // src/modules/assert.ts
284
+ var Assert;
285
+ ((Assert2) => {
286
+ let errorConstructor = Error;
287
+ function setErrorClass(ec) {
288
+ errorConstructor = ec ?? Error;
289
+ }
290
+ Assert2.setErrorClass = setErrorClass;
291
+ function throwError(errorMsg, userMsg) {
292
+ throw new errorConstructor("Assertion Error: " + errorMsg + (userMsg ? " " + userMsg : ""));
293
+ }
294
+ function is_int(a) {
295
+ return typeof a === "number" && isFinite(a) && a === Math.trunc(a);
296
+ }
297
+ function is_number(a) {
298
+ return typeof a === "number";
299
+ }
300
+ function assert(a, userMsg) {
301
+ if (!a) {
302
+ throwError(userMsg ?? "Assertion failed!");
303
+ }
304
+ }
305
+ Assert2.assert = assert;
306
+ function assertEnum(value, enumObj, name = "value") {
307
+ if (!getEnumValues(enumObj).some((v) => v === value)) {
308
+ throw new TypeError(`Invalid ${name} enum value: ${value}`);
309
+ }
310
+ }
311
+ Assert2.assertEnum = assertEnum;
312
+ function interrupt(userMsg) {
313
+ throwError(userMsg ?? "Interrupted!");
314
+ }
315
+ Assert2.interrupt = interrupt;
316
+ function int(a, userMsg) {
317
+ if (!is_int(a)) {
318
+ throwError(`Expected ${a} to be integer.`, userMsg);
319
+ }
320
+ return a;
321
+ }
322
+ Assert2.int = int;
323
+ function eq(a, b, userMsg) {
324
+ if (a !== b) {
325
+ throwError(`Expected ${a} to equal ${b}.`, userMsg);
326
+ }
327
+ return a;
328
+ }
329
+ Assert2.eq = eq;
330
+ function int_eq(a, b, userMsg) {
331
+ if (!(is_int(a) && is_number(b) && a === b)) {
332
+ throwError(`Expected ${a} to be integer equal to ${b}.`, userMsg);
333
+ }
334
+ return a;
335
+ }
336
+ Assert2.int_eq = int_eq;
337
+ function int_lt(a, b, userMsg) {
338
+ if (!(is_int(a) && is_number(b) && a < b)) {
339
+ throwError(`Expected ${a} to be integer less than ${b}.`, userMsg);
340
+ }
341
+ return a;
342
+ }
343
+ Assert2.int_lt = int_lt;
344
+ function int_lte(a, b, userMsg) {
345
+ if (!(is_int(a) && is_number(b) && a <= b)) {
346
+ throwError(`Expected ${a} to be integer less than or equal to ${b}.`, userMsg);
347
+ }
348
+ return a;
349
+ }
350
+ Assert2.int_lte = int_lte;
351
+ function int_gt(a, b, userMsg) {
352
+ if (!(is_int(a) && is_number(b) && a > b)) {
353
+ throwError(`Expected ${a} to be integer greater than ${b}.`, userMsg);
354
+ }
355
+ return a;
356
+ }
357
+ Assert2.int_gt = int_gt;
358
+ function int_gte(a, b, userMsg) {
359
+ if (!(is_int(a) && is_number(b) && a >= b)) {
360
+ throwError(`Expected ${a} to be integer greater than or equal to ${b}.`, userMsg);
361
+ }
362
+ return a;
363
+ }
364
+ Assert2.int_gte = int_gte;
365
+ function int_between(a, min, max, userMsg) {
366
+ if (!(is_int(a) && is_number(min) && is_number(max) && a >= min && a <= max)) {
367
+ throwError(`Expected ${a} to be integer between ${min} and ${max}.`, userMsg);
368
+ }
369
+ return a;
370
+ }
371
+ Assert2.int_between = int_between;
372
+ function odd(a, userMsg) {
373
+ if (!(is_int(a) && a % 2 === 1)) {
374
+ throwError(`Expected ${a} to be odd number.`, userMsg);
375
+ }
376
+ return a;
377
+ }
378
+ Assert2.odd = odd;
379
+ function even(a, userMsg) {
380
+ if (!(is_int(a) && a % 2 === 0)) {
381
+ throwError(`Expected ${a} to be even number.`, userMsg);
382
+ }
383
+ return a;
384
+ }
385
+ Assert2.even = even;
386
+ function in_group(a, group, userMsg) {
387
+ if (!group.some((e) => e === a)) {
388
+ let strGroup = group.map((v) => String(v)).join(", ");
389
+ throwError(`Expected ${a} to be in group [${strGroup}].`, userMsg);
390
+ }
391
+ return a;
392
+ }
393
+ Assert2.in_group = in_group;
394
+ function finite(a, userMsg) {
395
+ if (!(is_number(a) && isFinite(a))) {
396
+ throwError(`Expected ${a} to be finite number.`, userMsg);
397
+ }
398
+ return a;
399
+ }
400
+ Assert2.finite = finite;
401
+ function array_id(arr, id, userMsg) {
402
+ if (!(is_int(id) && id >= 0 && id < arr.length)) {
403
+ throwError(`Expected ${id} to be array index in bounds [0..${arr.length - 1}].`, userMsg);
404
+ }
405
+ return id;
406
+ }
407
+ Assert2.array_id = array_id;
408
+ function array_elem(arr, id, userMsg) {
409
+ return arr[array_id(arr, id, userMsg)];
410
+ }
411
+ Assert2.array_elem = array_elem;
412
+ function require2(arg, userMsg) {
413
+ if (arg === void 0) {
414
+ throwError("Required value is undefined.", userMsg);
415
+ } else {
416
+ return arg;
417
+ }
418
+ }
419
+ Assert2.require = require2;
420
+ })(Assert || (Assert = {}));
421
+
422
+ // src/modules/device.ts
423
+ var Device;
424
+ ((Device2) => {
425
+ function getDPI() {
426
+ let el = document.createElement("div");
427
+ el.style.width = "1in";
428
+ document.body.appendChild(el);
429
+ let dpi = el.offsetWidth;
430
+ el.remove();
431
+ return dpi || 96;
432
+ }
433
+ function getScrollBarWidth() {
434
+ try {
435
+ let outer = document.createElement("div");
436
+ outer.style.visibility = "hidden";
437
+ outer.style.width = "100px";
438
+ document.body.appendChild(outer);
439
+ let widthNoScroll = outer.offsetWidth;
440
+ outer.style.overflow = "scroll";
441
+ let inner = document.createElement("div");
442
+ inner.style.width = "100%";
443
+ outer.appendChild(inner);
444
+ let widthWithScroll = inner.offsetWidth;
445
+ if (outer.parentNode) {
446
+ outer.parentNode.removeChild(outer);
447
+ }
448
+ return widthNoScroll - widthWithScroll;
449
+ } catch (e) {
450
+ return 0;
451
+ }
452
+ }
453
+ function getSystemFontSize() {
454
+ let tmpDiv = document.createElement("div");
455
+ tmpDiv.style.cssText = "display:inline-block; padding:0; line-height:1; position:absolute; visibility:hidden; font-size:1em";
456
+ tmpDiv.appendChild(document.createTextNode("M"));
457
+ document.body.appendChild(tmpDiv);
458
+ let fontsize = tmpDiv.offsetHeight;
459
+ document.body.removeChild(tmpDiv);
460
+ return fontsize;
461
+ }
462
+ function getIsTouchDevice() {
463
+ if ("ontouchstart" in window || "DocumentTouch" in window || "createTouch" in document && "createTouchList" in document) {
464
+ return true;
465
+ }
466
+ var prefixes = " -webkit- -moz- -o- -ms- ".split(" ");
467
+ var mq = function(query2) {
468
+ return window.matchMedia(query2).matches;
469
+ };
470
+ var query = ["(", prefixes.join("touch-enabled),("), "heartz", ")"].join("");
471
+ return mq(query);
472
+ }
473
+ function getIsMobileDevice() {
474
+ let a = navigator.userAgent || navigator.vendor || window.opera;
475
+ return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4));
476
+ }
477
+ function getHostAddress() {
478
+ return location.protocol + "//" + location.host;
479
+ }
480
+ const UnitRegExp = /^(mm|cm|in|inch|px|em)$/;
481
+ const ValueUnitRegExp = /^([0-9\\.]+)(.*)$/;
482
+ Device2.DPI = getDPI();
483
+ Device2.PxPerMm = Device2.DPI / 25.4;
484
+ Device2.ScrollbarWidth = getScrollBarWidth();
485
+ Device2.FontSize = getSystemFontSize();
486
+ Device2.IsTouchDevice = getIsTouchDevice();
487
+ Device2.IsMobileDevice = getIsMobileDevice();
488
+ Device2.HostAddress = getHostAddress();
489
+ function pxToMm(px) {
490
+ return px / Device2.PxPerMm;
491
+ }
492
+ Device2.pxToMm = pxToMm;
493
+ function mmToPx(mm) {
494
+ return mm * Device2.PxPerMm;
495
+ }
496
+ Device2.mmToPx = mmToPx;
497
+ function toPx2(input) {
498
+ if (typeof input === "number") {
499
+ return input;
500
+ }
501
+ let value = NaN;
502
+ let unit = void 0;
503
+ let match = input.toString().match(ValueUnitRegExp);
504
+ if (match && match[1]) {
505
+ value = parseFloat(match[1]);
506
+ let unitStr = match[2] ? match[2].toLowerCase() : "undefined";
507
+ let unitStrOk = UnitRegExp.test(unitStr);
508
+ unit = unitStrOk ? unitStr : void 0;
509
+ if (!unit) {
510
+ console.log("Unknown unit '" + unitStr + "' => using 'px'.");
511
+ }
512
+ } else {
513
+ value = parseFloat(input);
514
+ }
515
+ Assert.finite(value, "value in function toPx");
516
+ switch (unit) {
517
+ case "mm":
518
+ return mmToPx(value);
519
+ case "cm":
520
+ return mmToPx(value) * 10;
521
+ case "in":
522
+ case "inch":
523
+ return mmToPx(value) * 25.4;
524
+ case "em":
525
+ return Device2.FontSize * value;
526
+ default:
527
+ case "px":
528
+ return value;
529
+ }
530
+ }
531
+ Device2.toPx = toPx2;
532
+ })(Device || (Device = {}));
533
+
534
+ // src/utils/dom/index.ts
535
+ function toPx(value) {
536
+ return value === void 0 ? void 0 : Device.toPx(value);
537
+ }
538
+ function hasClass(el, className) {
539
+ if (className.length === 0) {
540
+ return false;
541
+ } else if (el.classList) {
542
+ return el.classList.contains(className);
543
+ } else {
544
+ return !!el.className.match(new RegExp("(\\s|^)" + className + "(\\s|$)"));
545
+ }
546
+ }
547
+ function addClass(el, className) {
548
+ if (className.length === 0) {
549
+ return;
550
+ } else if (el.classList) {
551
+ el.classList.add(className);
552
+ } else if (!hasClass(el, className)) {
553
+ el.className += " " + className;
554
+ }
555
+ }
556
+ function removeClass(el, className) {
557
+ if (className.length === 0) {
558
+ return;
559
+ } else if (el.classList) {
560
+ el.classList.remove(className);
561
+ } else if (hasClass(el, className)) {
562
+ var reg = new RegExp("(\\s|^)" + className + "(\\s|$)");
563
+ el.className = el.className.replace(reg, " ");
564
+ }
565
+ }
566
+ function setOffset(el, left, top, unit = "px") {
567
+ el.style.left = left + unit;
568
+ el.style.top = top + unit;
569
+ }
570
+ function getOffset(el) {
571
+ let box = el.getBoundingClientRect();
572
+ let docElem = document.documentElement;
573
+ return {
574
+ top: box.top + window.pageYOffset - docElem.clientTop,
575
+ left: box.left + window.pageXOffset - docElem.clientLeft
576
+ };
577
+ }
578
+ function getWidth(el) {
579
+ if (el instanceof Window) {
580
+ return el.innerWidth;
581
+ } else {
582
+ let w = parseFloat(getComputedStyle(el, null).width.replace("px", ""));
583
+ return isNaN(w) ? 0 : w;
584
+ }
585
+ }
586
+ function setWidth(el, val) {
587
+ el.style.width = val + "px";
588
+ }
589
+ function getHeight(el) {
590
+ if (el instanceof Window) {
591
+ return el.innerHeight;
592
+ } else {
593
+ let h = parseFloat(getComputedStyle(el, null).height.replace("px", ""));
594
+ return isNaN(h) ? 0 : h;
595
+ }
596
+ }
597
+ function setHeight(el, val) {
598
+ el.style.height = val + "px";
599
+ }
600
+ function appendTo(el, to) {
601
+ to.appendChild(el);
602
+ }
603
+ function removeFromParent(el) {
604
+ el.remove();
605
+ }
606
+ function setVisibility(el, visible) {
607
+ el.style.display = visible ? "block" : "none";
608
+ }
609
+ function setRect(el, left, top, width, height, unit = "px") {
610
+ el.style.left = left + unit;
611
+ el.style.top = top + unit;
612
+ el.style.width = width + unit;
613
+ el.style.height = height + unit;
614
+ }
615
+ function getButton(btn) {
616
+ let el = typeof btn === "string" ? document.getElementById(btn) : btn;
617
+ return el instanceof HTMLButtonElement ? el : void 0;
618
+ }
619
+ function getCanvas(canvas2) {
620
+ let el = typeof canvas2 === "string" ? document.getElementById(canvas2) : canvas2;
621
+ return el instanceof HTMLCanvasElement ? el : void 0;
622
+ }
623
+ function getPadding(style) {
624
+ if (!style) {
625
+ return { top: 0, right: 0, bottom: 0, left: 0 };
626
+ }
627
+ let top = toPx(style.paddingTop);
628
+ let right = toPx(style.paddingRight);
629
+ let bottom = toPx(style.paddingBottom);
630
+ let left = toPx(style.paddingLeft);
631
+ let padding = (style.padding ?? "").toString().split(" ").filter((s) => s.length > 0);
632
+ switch (padding.length) {
633
+ case 0:
634
+ break;
635
+ case 1:
636
+ top ?? (top = toPx(padding[0]));
637
+ right ?? (right = toPx(padding[0]));
638
+ bottom ?? (bottom = toPx(padding[0]));
639
+ left ?? (left = toPx(padding[0]));
640
+ break;
641
+ case 2:
642
+ top ?? (top = toPx(padding[0]));
643
+ right ?? (right = toPx(padding[1]));
644
+ bottom ?? (bottom = toPx(padding[0]));
645
+ left ?? (left = toPx(padding[1]));
646
+ break;
647
+ case 3:
648
+ top ?? (top = toPx(padding[0]));
649
+ right ?? (right = toPx(padding[1]));
650
+ bottom ?? (bottom = toPx(padding[2]));
651
+ left ?? (left = toPx(padding[1]));
652
+ break;
653
+ case 4:
654
+ default:
655
+ top ?? (top = toPx(padding[0]));
656
+ right ?? (right = toPx(padding[1]));
657
+ bottom ?? (bottom = toPx(padding[2]));
658
+ left ?? (left = toPx(padding[3]));
659
+ break;
660
+ }
661
+ top ?? (top = 0);
662
+ right ?? (right = 0);
663
+ bottom ?? (bottom = 0);
664
+ left ?? (left = 0);
665
+ return { top, right, bottom, left };
666
+ }
667
+ function getDimension(style) {
668
+ let left = toPx(style?.left);
669
+ let right = toPx(style?.right);
670
+ let top = toPx(style?.top);
671
+ let bottom = toPx(style?.bottom);
672
+ let width = toPx(style?.width);
673
+ let height = toPx(style?.height);
674
+ if (width === void 0 && left !== void 0 && right !== void 0) {
675
+ width = right - left;
676
+ }
677
+ if (height === void 0 && top !== void 0 && bottom !== void 0) {
678
+ height = bottom - top;
679
+ }
680
+ return { left, top, width, height };
681
+ }
682
+ function styleLayoutChanged(style1, style2) {
683
+ if (!style1 && !style2) {
684
+ return false;
685
+ } else if (!style1 || !style2) {
686
+ return true;
687
+ } else {
688
+ return style1.left !== style2.left || style1.top !== style2.top || style1.right !== style2.right || style1.bottom !== style2.bottom || style1.width !== style2.width || style1.height !== style2.height;
689
+ }
690
+ }
691
+ var canvas;
692
+ function getCanvasTextWidth(text, font) {
693
+ canvas ?? (canvas = document.createElement("canvas"));
694
+ let ctx = canvas.getContext("2d");
695
+ if (!ctx) {
696
+ return 0;
697
+ }
698
+ ctx.font = font;
699
+ return ctx.measureText(text).width;
700
+ }
701
+
702
+ // src/utils/map/index.ts
703
+ var map_exports = {};
704
+ __export(map_exports, {
705
+ getMapKeys: () => getMapKeys
706
+ });
707
+ function getMapKeys(map) {
708
+ let keys = [];
709
+ map.forEach((value, key) => keys.push(key));
710
+ return keys;
711
+ }
712
+
713
+ // src/utils/obj/index.ts
714
+ var obj_exports = {};
715
+ __export(obj_exports, {
716
+ isObject: () => isObject
717
+ });
718
+ function isObject(value) {
719
+ return typeof value === "object" && value !== null && !isArray(value);
720
+ }
721
+
722
+ // src/utils/str/index.ts
723
+ var str_exports = {};
724
+ __export(str_exports, {
725
+ chunkString: () => chunkString,
726
+ insertAt: () => insertAt,
727
+ makeSentenceFromPascal: () => makeSentenceFromPascal,
728
+ removeAt: () => removeAt,
729
+ repeatString: () => repeatString,
730
+ replaceAt: () => replaceAt,
731
+ toCharArray: () => toCharArray
732
+ });
733
+ function toCharArray(str) {
734
+ return str.split("");
735
+ }
736
+ function repeatString(repeatString2, repeatCount) {
737
+ if (!isInteger(repeatCount) || repeatCount < 0) {
738
+ throw new Error("repeatStr: Invalid repeatCount = " + repeatCount);
739
+ }
740
+ return new Array(repeatCount + 1).join(repeatString2);
741
+ }
742
+ function chunkString(str, chunkSize) {
743
+ if (!isInteger(chunkSize) || chunkSize < 1) {
744
+ throw new Error("chunckString: Invalid chuckSize = " + chunkSize);
745
+ }
746
+ let result = [];
747
+ for (let i = 0; i < str.length; i += chunkSize) {
748
+ result.push(str.slice(i, i + chunkSize));
749
+ }
750
+ return result;
751
+ }
752
+ function replaceAt(str, pos, removeCount, insert) {
753
+ if (!isInteger(removeCount) || removeCount < 0) {
754
+ throw new Error("replaceAt: Invalid removeCount = " + removeCount);
755
+ } else if (!isInteger(pos) || pos < 0 || pos + removeCount > str.length) {
756
+ throw new Error("replaceAt: Invalid pos = " + pos + ", removeCount = " + removeCount + ", str.length = " + str.length);
757
+ } else {
758
+ return str.substring(0, pos) + insert + str.substring(pos + removeCount);
759
+ }
760
+ }
761
+ function insertAt(str, pos, insertStr) {
762
+ return replaceAt(str, pos, 0, insertStr);
763
+ }
764
+ function removeAt(str, pos, removeCount) {
765
+ return replaceAt(str, pos, removeCount, "");
766
+ }
767
+ function makeSentenceFromPascal(PascalString) {
768
+ if (PascalString === "") {
769
+ return "";
770
+ }
771
+ let word = PascalString.charAt(0);
772
+ let sentence = "";
773
+ const addWord = () => {
774
+ if (word !== "") {
775
+ if (sentence === "") {
776
+ sentence += word.charAt(0).toUpperCase() + word.substring(1);
777
+ } else {
778
+ sentence += " " + word;
779
+ }
780
+ word = "";
781
+ }
782
+ };
783
+ const isLetterAndCapital = (c) => {
784
+ return c.toUpperCase() !== c.toLowerCase() && c === c.toUpperCase();
785
+ };
786
+ for (let i = 1; i < PascalString.length; i++) {
787
+ let c = PascalString.charAt(i);
788
+ if (isLetterAndCapital(c)) {
789
+ addWord();
790
+ }
791
+ word += c.toLowerCase();
792
+ }
793
+ addWord();
794
+ return sentence;
795
+ }
796
+
797
+ // src/modules/cookies.ts
798
+ var Cookies;
799
+ ((Cookies2) => {
800
+ const ConsentCookieName = "ConsentCookie";
801
+ let ConsentState;
802
+ ((ConsentState2) => {
803
+ ConsentState2["Accept"] = "accept";
804
+ ConsentState2["Decline"] = "decline";
805
+ })(ConsentState || (ConsentState = {}));
806
+ let _consent;
807
+ let _expires;
808
+ let str = _read(ConsentCookieName);
809
+ _consent = str === "accept" /* Accept */ || str === "decline" /* Decline */ ? str : void 0;
810
+ function setExpireDays(days) {
811
+ _expires = /* @__PURE__ */ new Date();
812
+ _expires.setDate(_expires.getDate() + days);
813
+ }
814
+ Cookies2.setExpireDays = setExpireDays;
815
+ function isConsentPending() {
816
+ return _consent === void 0;
817
+ }
818
+ Cookies2.isConsentPending = isConsentPending;
819
+ function accept() {
820
+ _consent = "accept" /* Accept */;
821
+ _save(ConsentCookieName, _consent);
822
+ }
823
+ Cookies2.accept = accept;
824
+ function decline() {
825
+ _consent = "decline" /* Decline */;
826
+ _save(ConsentCookieName, _consent);
827
+ }
828
+ Cookies2.decline = decline;
829
+ function _getList() {
830
+ let s = document.cookie;
831
+ return s.split(";").map((c) => c.trim());
832
+ }
833
+ function _save(name, value) {
834
+ let cookie = name + "=" + value.toString() + ";sameSite=Lax;";
835
+ if (_expires) {
836
+ cookie += "expires=" + _expires.toUTCString() + ";";
837
+ }
838
+ document.cookie = cookie;
839
+ return value;
840
+ }
841
+ function _read(name, defaultValue) {
842
+ let str2 = _getList().find((c) => c.startsWith(name + "="));
843
+ return str2 === void 0 ? defaultValue : str2.substring(name.length + 1);
844
+ }
845
+ function _erase(name) {
846
+ document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 UTC;";
847
+ }
848
+ function save(name, value) {
849
+ if (_consent === "accept" /* Accept */) {
850
+ _save(name, value);
851
+ }
852
+ return value;
853
+ }
854
+ Cookies2.save = save;
855
+ function read(name, defaultValue) {
856
+ if (_consent === "accept" /* Accept */) {
857
+ return _read(name, defaultValue) || defaultValue;
858
+ } else {
859
+ return defaultValue;
860
+ }
861
+ }
862
+ Cookies2.read = read;
863
+ function readInt(name, defaultValue) {
864
+ if (_consent === "accept" /* Accept */) {
865
+ let str2 = _read(name);
866
+ return str2 === void 0 ? defaultValue : parseInt(str2);
867
+ } else {
868
+ return defaultValue;
869
+ }
870
+ }
871
+ Cookies2.readInt = readInt;
872
+ function readBool(name, defaultValue) {
873
+ if (_consent === "accept" /* Accept */) {
874
+ let str2 = _read(name);
875
+ return str2 === void 0 ? defaultValue : /true|1/i.test(str2);
876
+ } else {
877
+ return defaultValue;
878
+ }
879
+ }
880
+ Cookies2.readBool = readBool;
881
+ function erase(name) {
882
+ if (_consent === "accept" /* Accept */ || name === ConsentCookieName) {
883
+ _erase(name);
884
+ }
885
+ }
886
+ Cookies2.erase = erase;
887
+ function eraseAll() {
888
+ document.cookie.split(";").forEach((c) => erase(c.trim().split("=")[0]));
889
+ }
890
+ Cookies2.eraseAll = eraseAll;
891
+ })(Cookies || (Cookies = {}));
892
+
893
+ // src/core/stack.ts
894
+ var Stack = class {
895
+ constructor() {
896
+ __publicField(this, "list", []);
897
+ }
898
+ push(e) {
899
+ this.list.push(e);
900
+ return e;
901
+ }
902
+ pop() {
903
+ Assert.int_gt(this.list.length, 0);
904
+ return this.list.pop();
905
+ }
906
+ top() {
907
+ return Assert.array_elem(this.list, this.list.length - 1, "Stack is empty!");
908
+ }
909
+ toArray() {
910
+ return this.list;
911
+ }
912
+ get length() {
913
+ return this.list.length;
914
+ }
915
+ clear() {
916
+ this.list.length = 0;
917
+ }
918
+ };
919
+
920
+ // src/core/vec2.ts
921
+ var Vec2 = class _Vec2 {
922
+ constructor(x, y) {
923
+ __publicField(this, "x");
924
+ __publicField(this, "y");
925
+ this.x = x ?? 0;
926
+ this.y = y ?? 0;
927
+ }
928
+ length() {
929
+ return Math.sqrt(this.x * this.x + this.y * this.y);
930
+ }
931
+ add(a) {
932
+ return new _Vec2(this.x + a.x, this.y + a.y);
933
+ }
934
+ sub(a) {
935
+ return new _Vec2(this.x - a.x, this.y - a.y);
936
+ }
937
+ mul(a) {
938
+ return new _Vec2(this.x * a, this.y * a);
939
+ }
940
+ div(a) {
941
+ return new _Vec2(this.x / a, this.y / a);
942
+ }
943
+ };
944
+
945
+ // src/core/LRU-cache.ts
946
+ var LRUCache = class {
947
+ // Maximum key length.
948
+ constructor(maxSize, maxKeyLength = Infinity) {
949
+ __publicField(this, "cache");
950
+ // Stores the actual key-value pairs
951
+ __publicField(this, "next");
952
+ // Linked list: points to the next newer key
953
+ __publicField(this, "prev");
954
+ // Linked list: points to the previous older key
955
+ __publicField(this, "head");
956
+ // The least recently used key (oldest)
957
+ __publicField(this, "tail");
958
+ // The most recently used key (newest)
959
+ __publicField(this, "capacity");
960
+ // Maximum number of items allowed
961
+ __publicField(this, "size");
962
+ // Current number of items
963
+ __publicField(this, "maxKeyLength");
964
+ this.cache = /* @__PURE__ */ Object.create(null);
965
+ this.next = /* @__PURE__ */ Object.create(null);
966
+ this.prev = /* @__PURE__ */ Object.create(null);
967
+ this.head = null;
968
+ this.tail = null;
969
+ this.capacity = maxSize;
970
+ this.size = 0;
971
+ this.maxKeyLength = maxKeyLength;
972
+ }
973
+ // Retrieves a value from the cache
974
+ get(key) {
975
+ if (key.length > this.maxKeyLength) return void 0;
976
+ if (this.cache[key] !== void 0) {
977
+ this.touch(key);
978
+ return this.cache[key];
979
+ }
980
+ return void 0;
981
+ }
982
+ set(key, value) {
983
+ if (key.length > this.maxKeyLength) {
984
+ return;
985
+ }
986
+ if (this.cache[key] !== void 0) {
987
+ this.cache[key] = value;
988
+ this.touch(key);
989
+ return;
990
+ }
991
+ if (this.size >= this.capacity) {
992
+ this.evict();
993
+ }
994
+ this.cache[key] = value;
995
+ this.addToTail(key);
996
+ this.size++;
997
+ }
998
+ // Marks a key as most recently used
999
+ touch(key) {
1000
+ if (this.tail === key) return;
1001
+ this.removeKey(key);
1002
+ this.addToTail(key);
1003
+ }
1004
+ // Evicts the least recently used item (at the head)
1005
+ evict() {
1006
+ if (this.head !== null) {
1007
+ const oldestKey = this.head;
1008
+ this.removeKey(oldestKey);
1009
+ delete this.cache[oldestKey];
1010
+ this.size--;
1011
+ }
1012
+ }
1013
+ // Removes a key from the linked list
1014
+ removeKey(key) {
1015
+ const prevKey = this.prev[key];
1016
+ const nextKey = this.next[key];
1017
+ if (prevKey !== void 0) {
1018
+ this.next[prevKey] = nextKey;
1019
+ } else {
1020
+ this.head = nextKey ?? null;
1021
+ }
1022
+ if (nextKey !== void 0) {
1023
+ this.prev[nextKey] = prevKey;
1024
+ } else {
1025
+ this.tail = prevKey ?? null;
1026
+ }
1027
+ delete this.prev[key];
1028
+ delete this.next[key];
1029
+ }
1030
+ // Adds a key to the tail (most recently used position)
1031
+ addToTail(key) {
1032
+ if (this.tail !== null) {
1033
+ this.next[this.tail] = key;
1034
+ this.prev[key] = this.tail;
1035
+ } else {
1036
+ this.head = key;
1037
+ }
1038
+ this.tail = key;
1039
+ }
1040
+ };
1041
+
1042
+ // src/core/small-int-cache.ts
1043
+ var SmallIntCache = class {
1044
+ // for keys < 0
1045
+ constructor() {
1046
+ __publicField(this, "pos");
1047
+ // for keys >= 0
1048
+ __publicField(this, "neg");
1049
+ this.pos = [];
1050
+ this.neg = [];
1051
+ }
1052
+ set(key, value) {
1053
+ if (!isInteger(key)) {
1054
+ throw new Error("Key must be an integer");
1055
+ } else if (key >= 0) {
1056
+ this.pos[key] = value;
1057
+ } else {
1058
+ this.neg[-key - 1] = value;
1059
+ }
1060
+ }
1061
+ get(key) {
1062
+ if (!isInteger(key)) {
1063
+ throw new Error("Key must be an integer");
1064
+ } else if (key >= 0) {
1065
+ return this.pos[key];
1066
+ } else {
1067
+ return this.neg[-key - 1];
1068
+ }
1069
+ }
1070
+ has(key) {
1071
+ if (!isInteger(key)) {
1072
+ return false;
1073
+ } else if (key >= 0) {
1074
+ return key in this.pos;
1075
+ } else {
1076
+ return -key - 1 in this.neg;
1077
+ }
1078
+ }
1079
+ delete(key) {
1080
+ if (!isInteger(key)) {
1081
+ return;
1082
+ } else if (key >= 0) {
1083
+ delete this.pos[key];
1084
+ } else {
1085
+ delete this.neg[-key - 1];
1086
+ }
1087
+ }
1088
+ clear() {
1089
+ this.pos = [];
1090
+ this.neg = [];
1091
+ }
1092
+ };
1093
+ // Annotate the CommonJS export names for ESM import in node:
1094
+ 0 && (module.exports = {
1095
+ Assert,
1096
+ Cookies,
1097
+ Device,
1098
+ LRUCache,
1099
+ SmallIntCache,
1100
+ Stack,
1101
+ Utils,
1102
+ Vec2
1103
+ });
1104
+ //# sourceMappingURL=index.js.map