@pacem/pacem-foundation 1.0.0-bessel → 1.0.0-binet
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/browser/pacem-foundation.js +296 -1
- package/dist/browser/pacem-foundation.js.map +1 -1
- package/dist/browser/pacem-foundation.min.js +1 -1
- package/dist/bundle/pacem-foundation.min.mjs +1 -1
- package/dist/bundle/pacem-foundation.mjs +258 -1
- package/dist/bundle/pacem-foundation.mjs.map +2 -2
- package/dist/docs/pacem-foundation.json +8941 -0
- package/dist/esm/array-extensions.js +1 -1
- package/dist/esm/arrays.js +8 -1
- package/dist/esm/blobs.js +24 -1
- package/dist/esm/browser.js +6 -1
- package/dist/esm/colors.js +15 -1
- package/dist/esm/dates.js +37 -1
- package/dist/esm/deepmerger.js +10 -1
- package/dist/esm/geom.js +33 -1
- package/dist/esm/history-svc.js +15 -1
- package/dist/esm/imaging.js +7 -1
- package/dist/esm/index-compile-markdown.js +1 -1
- package/dist/esm/index-compile.js +1 -1
- package/dist/esm/index-iife.js +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/keygenerator.js +15 -1
- package/dist/esm/matrix2d.js +36 -1
- package/dist/esm/null-checker.js +16 -1
- package/dist/esm/number-extensions.js +1 -1
- package/dist/esm/numbers.js +20 -1
- package/dist/esm/rect.js +12 -1
- package/dist/esm/strings.js +23 -1
- package/package.json +2 -1
- package/typings/index.d.ts +451 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*!
|
|
2
|
-
* @pacem/pacem-foundation v1.0.0-
|
|
2
|
+
* @pacem/pacem-foundation v1.0.0-binet (https://js.pacem.it)
|
|
3
3
|
* Pacem (https://pacem.it)
|
|
4
4
|
* Licensed under Apache-2.0
|
|
5
5
|
*/
|
|
@@ -45,6 +45,12 @@ Number.prototype.toBase36 = function() {
|
|
|
45
45
|
// packages/foundation/dist/esm/dates.js
|
|
46
46
|
var JSON_DATE_PATTERN = /^\/Date\([\d]+\)\/$/i;
|
|
47
47
|
var Dates = class _Dates {
|
|
48
|
+
/**
|
|
49
|
+
* Parses a value into a `Date`. Accepts ISO/parseable date strings, ASP.NET-style
|
|
50
|
+
* `/Date(ticks)/` JSON date strings, numeric timestamps, or a `Date` instance (returned as-is).
|
|
51
|
+
* @param input Value to parse.
|
|
52
|
+
* @returns The resulting `Date`.
|
|
53
|
+
*/
|
|
48
54
|
static parse(input) {
|
|
49
55
|
let d;
|
|
50
56
|
if (typeof input === "string") {
|
|
@@ -58,9 +64,19 @@ var Dates = class _Dates {
|
|
|
58
64
|
} else
|
|
59
65
|
return input;
|
|
60
66
|
}
|
|
67
|
+
/**
|
|
68
|
+
* Gets whether the given year is a leap year.
|
|
69
|
+
* @param year Year to check.
|
|
70
|
+
*/
|
|
61
71
|
static isLeapYear(year) {
|
|
62
72
|
return year % 4 === 0 && year % 100 !== 0 || year % 400 === 0;
|
|
63
73
|
}
|
|
74
|
+
/**
|
|
75
|
+
* Gets the number of days in a given month of a given year.
|
|
76
|
+
* @param year Year (used to account for leap Februaries).
|
|
77
|
+
* @param month Zero-based month index (0 = January, ..., 11 = December).
|
|
78
|
+
* @returns Number of days in the month.
|
|
79
|
+
*/
|
|
64
80
|
static daysInMonth(year, month) {
|
|
65
81
|
return [31, _Dates.isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
|
|
66
82
|
}
|
|
@@ -78,6 +94,13 @@ var Dates = class _Dates {
|
|
|
78
94
|
static dateOnly(datetime) {
|
|
79
95
|
return new Date(datetime.getFullYear(), datetime.getMonth(), datetime.getDate());
|
|
80
96
|
}
|
|
97
|
+
/**
|
|
98
|
+
* Returns a new date obtained by adding a (possibly negative) number of months to `input`,
|
|
99
|
+
* clamping the day-of-month to the target month's length (e.g. Jan 31 + 1 month => Feb 28/29).
|
|
100
|
+
* @param input Starting date.
|
|
101
|
+
* @param value Number of months to add.
|
|
102
|
+
* @returns The resulting date.
|
|
103
|
+
*/
|
|
81
104
|
static addMonths(input, value) {
|
|
82
105
|
let n = input.getDate(), i = new Date(input), month = i.getMonth() + value, years = 0;
|
|
83
106
|
while (month < 0) {
|
|
@@ -90,9 +113,21 @@ var Dates = class _Dates {
|
|
|
90
113
|
i.setDate(Math.min(n, _Dates.daysInMonth(i.getFullYear(), i.getMonth())));
|
|
91
114
|
return i;
|
|
92
115
|
}
|
|
116
|
+
/**
|
|
117
|
+
* Returns a new date obtained by adding a (possibly negative) number of days to `input`.
|
|
118
|
+
* @param input Starting date.
|
|
119
|
+
* @param value Number of days to add.
|
|
120
|
+
* @returns The resulting date.
|
|
121
|
+
*/
|
|
93
122
|
static addDays(input, value) {
|
|
94
123
|
return new Date(input.valueOf() + value * 864e5);
|
|
95
124
|
}
|
|
125
|
+
/**
|
|
126
|
+
* Computes the number of days (possibly fractional) between two dates.
|
|
127
|
+
* @param start Start date.
|
|
128
|
+
* @param end End date.
|
|
129
|
+
* @returns Number of days between `start` and `end` (negative if `end` precedes `start`).
|
|
130
|
+
*/
|
|
96
131
|
static daysBetween(start, end) {
|
|
97
132
|
return (end.valueOf() - start.valueOf()) / 864e5;
|
|
98
133
|
}
|
|
@@ -100,9 +135,19 @@ var Dates = class _Dates {
|
|
|
100
135
|
|
|
101
136
|
// packages/foundation/dist/esm/null-checker.js
|
|
102
137
|
var NullChecker = class _NullChecker {
|
|
138
|
+
/**
|
|
139
|
+
* Returns whether the given value is `null` or `undefined`.
|
|
140
|
+
* @param o Value to check.
|
|
141
|
+
*/
|
|
103
142
|
static isNull(o) {
|
|
104
143
|
return o === null || o === void 0;
|
|
105
144
|
}
|
|
145
|
+
/**
|
|
146
|
+
* Returns whether the given value is "empty": an empty array, an empty string, or a
|
|
147
|
+
* plain object with no own enumerable keys (dates, regexes and file-system handles are never
|
|
148
|
+
* considered empty).
|
|
149
|
+
* @param o Value to check.
|
|
150
|
+
*/
|
|
106
151
|
static isEmpty(o) {
|
|
107
152
|
try {
|
|
108
153
|
return Array.isArray(o) && o.length === 0 || typeof o === "string" && o === "" || typeof o === "object" && Object.keys(o).length === 0 && !Dates.isDate(o) && !(o instanceof RegExp) && !(o instanceof FileSystemDirectoryHandle) && !(o instanceof FileSystemFileHandle);
|
|
@@ -110,6 +155,10 @@ var NullChecker = class _NullChecker {
|
|
|
110
155
|
return false;
|
|
111
156
|
}
|
|
112
157
|
}
|
|
158
|
+
/**
|
|
159
|
+
* Returns whether the given value is `null`, `undefined`, or "empty" (see {@link NullChecker.isEmpty}).
|
|
160
|
+
* @param o Value to check.
|
|
161
|
+
*/
|
|
113
162
|
static isNullOrEmpty(o) {
|
|
114
163
|
return _NullChecker.isNull(o) || _NullChecker.isEmpty(o);
|
|
115
164
|
}
|
|
@@ -202,6 +251,14 @@ function deepMerge(target, source) {
|
|
|
202
251
|
var DeepMerger = class {
|
|
203
252
|
constructor() {
|
|
204
253
|
}
|
|
254
|
+
/**
|
|
255
|
+
* Recursively merges `source` into `target`, in place: plain-object properties are merged
|
|
256
|
+
* recursively (into a fresh object, never adopted by reference), arrays are shallow-copied,
|
|
257
|
+
* and any other value overwrites the target's.
|
|
258
|
+
* @param source Object whose properties are merged into `target`.
|
|
259
|
+
* @param target Object to merge into (defaults to, and lazily creates, the global `Pacem` namespace object).
|
|
260
|
+
* @returns The mutated `target`, typed as the union of both inputs.
|
|
261
|
+
*/
|
|
205
262
|
static merge(source, target) {
|
|
206
263
|
target ??= globalThis["Pacem"] ??= {};
|
|
207
264
|
return deepMerge(target, source);
|
|
@@ -226,6 +283,12 @@ var Arrays = class {
|
|
|
226
283
|
}
|
|
227
284
|
return output;
|
|
228
285
|
}
|
|
286
|
+
/**
|
|
287
|
+
* Splits an array into chunks of a given size.
|
|
288
|
+
* @param source Array to split.
|
|
289
|
+
* @param size Maximum size of each chunk (must be a positive integer).
|
|
290
|
+
* @returns Array of chunks; an empty array if `source` is null or empty.
|
|
291
|
+
*/
|
|
229
292
|
static chunkify(source, size) {
|
|
230
293
|
if (NullChecker.isNullOrEmpty(source)) {
|
|
231
294
|
return [];
|
|
@@ -243,6 +306,11 @@ var Arrays = class {
|
|
|
243
306
|
|
|
244
307
|
// packages/foundation/dist/esm/blobs.js
|
|
245
308
|
var Blobs = class _Blobs {
|
|
309
|
+
/**
|
|
310
|
+
* Reads a `Blob` and resolves it as a base64-encoded data URL.
|
|
311
|
+
* @param blob Blob to read.
|
|
312
|
+
* @returns A promise resolving with the data URL string.
|
|
313
|
+
*/
|
|
246
314
|
static blobToDataURL(blob) {
|
|
247
315
|
return new Promise((resolve, _) => {
|
|
248
316
|
const a = new FileReader();
|
|
@@ -260,10 +328,21 @@ var Blobs = class _Blobs {
|
|
|
260
328
|
}
|
|
261
329
|
return u8arr;
|
|
262
330
|
}
|
|
331
|
+
/**
|
|
332
|
+
* Converts a base64-encoded string into a `Blob`.
|
|
333
|
+
* @param bstr Base64-encoded string (without the `data:...;base64,` prefix).
|
|
334
|
+
* @param options Blob options (e.g. MIME `type`).
|
|
335
|
+
* @returns The resulting `Blob`.
|
|
336
|
+
*/
|
|
263
337
|
static base64ToBlob(bstr, options) {
|
|
264
338
|
const u8arr = _Blobs._b64ToUint8Array(atob(bstr));
|
|
265
339
|
return new Blob([u8arr], options);
|
|
266
340
|
}
|
|
341
|
+
/**
|
|
342
|
+
* Converts a data URL (`data:<mime>;base64,<data>`) into a `Blob`, inferring the MIME type when present.
|
|
343
|
+
* @param dataurl Data URL to convert.
|
|
344
|
+
* @returns The resulting `Blob`.
|
|
345
|
+
*/
|
|
267
346
|
static dataURLToBlob(dataurl) {
|
|
268
347
|
const coma = dataurl.indexOf(",");
|
|
269
348
|
if (coma === -1) {
|
|
@@ -274,6 +353,12 @@ var Blobs = class _Blobs {
|
|
|
274
353
|
return _Blobs.base64ToBlob(bstr, { type: mime });
|
|
275
354
|
}
|
|
276
355
|
}
|
|
356
|
+
/**
|
|
357
|
+
* Reads a `Blob` and decodes it as text.
|
|
358
|
+
* @param blob Blob to read.
|
|
359
|
+
* @param encoding Text encoding to use for decoding (defaults to the platform's default, typically UTF-8).
|
|
360
|
+
* @returns A promise resolving with the decoded text.
|
|
361
|
+
*/
|
|
277
362
|
static async blobToText(blob, encoding) {
|
|
278
363
|
const buffer = await blob.arrayBuffer();
|
|
279
364
|
const decoder = new TextDecoder(encoding, { fatal: false });
|
|
@@ -532,6 +617,11 @@ var Colors = class _Colors {
|
|
|
532
617
|
static _normalize(rgb) {
|
|
533
618
|
return [rgb[0] / 255, rgb[1] / 255, rgb[2] / 255, rgb[3]];
|
|
534
619
|
}
|
|
620
|
+
/**
|
|
621
|
+
* Parses a CSS color string (`rgb()`, `rgba()`, `#rrggbb`, `#rgb`, `hsl()` or `hsla()`) into an {@link Rgba} value.
|
|
622
|
+
* @param clr CSS color string.
|
|
623
|
+
* @returns The parsed color, or `undefined` if the string does not match any supported format.
|
|
624
|
+
*/
|
|
535
625
|
static parse(clr) {
|
|
536
626
|
clr = (clr || "").toLowerCase();
|
|
537
627
|
if (RGB_PATTERN.test(clr)) {
|
|
@@ -562,6 +652,11 @@ var Colors = class _Colors {
|
|
|
562
652
|
return this.rgb(hsla);
|
|
563
653
|
}
|
|
564
654
|
}
|
|
655
|
+
/**
|
|
656
|
+
* Converts an {@link Rgba} color into its {@link Hsla} equivalent.
|
|
657
|
+
* @param rgb Color to convert.
|
|
658
|
+
* @returns The converted color.
|
|
659
|
+
*/
|
|
565
660
|
static hsl(rgb) {
|
|
566
661
|
const l = luminance(rgb), s = saturation(rgb, l), h = hueCircle(rgb);
|
|
567
662
|
return { h, s, l, a: rgb.a };
|
|
@@ -709,6 +804,10 @@ function parseAsNumericalArray(input) {
|
|
|
709
804
|
return arr;
|
|
710
805
|
}
|
|
711
806
|
var Angle = class _Angle {
|
|
807
|
+
/**
|
|
808
|
+
* Type-guards a value as a valid {@link Angle} object.
|
|
809
|
+
* @param obj Value to check.
|
|
810
|
+
*/
|
|
712
811
|
static isAngle(obj) {
|
|
713
812
|
return typeof obj === "object" && "vertex" in obj && Point.isPoint(obj["vertex"]) && "start" in obj && Point.isPoint(obj["start"]) && "end" in obj && Point.isPoint(obj["end"]);
|
|
714
813
|
}
|
|
@@ -739,6 +838,12 @@ var Angle = class _Angle {
|
|
|
739
838
|
}
|
|
740
839
|
};
|
|
741
840
|
var Size = class {
|
|
841
|
+
/**
|
|
842
|
+
* Parses a string containing exactly two numbers into a {@link Size}.
|
|
843
|
+
* @param sz String to parse (e.g. `"100 50"`).
|
|
844
|
+
* @returns The parsed size.
|
|
845
|
+
* @throws If `sz` does not contain exactly two numbers.
|
|
846
|
+
*/
|
|
742
847
|
static parse(sz) {
|
|
743
848
|
let arr = parseAsNumericalArray(sz);
|
|
744
849
|
if (arr && arr.length === 2) {
|
|
@@ -746,11 +851,21 @@ var Size = class {
|
|
|
746
851
|
}
|
|
747
852
|
throw new Error(`Cannot parse "${sz}" as a valid Size.`);
|
|
748
853
|
}
|
|
854
|
+
/**
|
|
855
|
+
* Type-guards a value as a valid {@link Size} object.
|
|
856
|
+
* @param obj Value to check.
|
|
857
|
+
*/
|
|
749
858
|
static isSize(obj) {
|
|
750
859
|
return typeof obj === "object" && "width" in obj && typeof obj["width"] === "number" && "height" in obj && typeof obj["height"] === "number";
|
|
751
860
|
}
|
|
752
861
|
};
|
|
753
862
|
var Point = class {
|
|
863
|
+
/**
|
|
864
|
+
* Parses a string containing exactly two numbers into a {@link Point}.
|
|
865
|
+
* @param pt String to parse (e.g. `"10 20"`).
|
|
866
|
+
* @returns The parsed point.
|
|
867
|
+
* @throws If `pt` does not contain exactly two numbers.
|
|
868
|
+
*/
|
|
754
869
|
static parse(pt) {
|
|
755
870
|
let arr = parseAsNumericalArray(pt);
|
|
756
871
|
if (arr && arr.length === 2) {
|
|
@@ -758,6 +873,10 @@ var Point = class {
|
|
|
758
873
|
}
|
|
759
874
|
throw new Error(`Cannot parse "${pt}" as a valid Point.`);
|
|
760
875
|
}
|
|
876
|
+
/**
|
|
877
|
+
* Type-guards a value as a valid {@link Point} object.
|
|
878
|
+
* @param obj Value to check.
|
|
879
|
+
*/
|
|
761
880
|
static isPoint(obj) {
|
|
762
881
|
return typeof obj === "object" && "x" in obj && typeof obj["x"] === "number" && "y" in obj && typeof obj["y"] === "number";
|
|
763
882
|
}
|
|
@@ -802,21 +921,40 @@ var Point = class {
|
|
|
802
921
|
|
|
803
922
|
// packages/foundation/dist/esm/matrix2d.js
|
|
804
923
|
var Matrix2D = class _Matrix2D {
|
|
924
|
+
/**
|
|
925
|
+
* Returns whether the given matrix is the identity matrix.
|
|
926
|
+
* @param m Matrix to check.
|
|
927
|
+
*/
|
|
805
928
|
static isIdentity(m) {
|
|
806
929
|
return m.a === 1 && m.d === 1 && m.b === 0 && m.f === 0 && m.c === 0 && m.e === 0;
|
|
807
930
|
}
|
|
931
|
+
/** Gets a fresh identity matrix. @readonly */
|
|
808
932
|
static get identity() {
|
|
809
933
|
return { a: 1, b: 0, c: 0, d: 1, e: 0, f: 0 };
|
|
810
934
|
}
|
|
935
|
+
/**
|
|
936
|
+
* Returns a shallow copy of the given matrix.
|
|
937
|
+
* @param m Matrix to copy.
|
|
938
|
+
*/
|
|
811
939
|
static copy(m) {
|
|
812
940
|
return { a: m.a, b: m.b, c: m.c, d: m.d, e: m.e, f: m.f };
|
|
813
941
|
}
|
|
814
942
|
static scale(m, sx, sy = sx) {
|
|
815
943
|
return { a: m.a * sx, b: m.b, c: m.c, d: m.d * sy, e: m.e, f: m.f };
|
|
816
944
|
}
|
|
945
|
+
/**
|
|
946
|
+
* Returns a copy of `m` translated by the given vector.
|
|
947
|
+
* @param m Matrix to translate.
|
|
948
|
+
* @param t Translation vector.
|
|
949
|
+
*/
|
|
817
950
|
static translate(m, t) {
|
|
818
951
|
return { a: m.a, b: m.b, c: m.c, d: m.d, e: m.e + t.x, f: m.f + t.y };
|
|
819
952
|
}
|
|
953
|
+
/**
|
|
954
|
+
* Returns a copy of `m` rotated (about the origin) by the given angle.
|
|
955
|
+
* @param m Matrix to rotate.
|
|
956
|
+
* @param rad Rotation angle, in radians.
|
|
957
|
+
*/
|
|
820
958
|
static rotate(m, rad) {
|
|
821
959
|
const cos = Math.cos(rad), sin = Math.sin(rad);
|
|
822
960
|
return _Matrix2D.multiply(m, { a: cos, b: sin, c: -sin, d: cos, e: 0, f: 0 });
|
|
@@ -848,9 +986,18 @@ var Matrix2D = class _Matrix2D {
|
|
|
848
986
|
f: m1.e * m2.b + m1.f * m2.d + m2.f
|
|
849
987
|
};
|
|
850
988
|
}
|
|
989
|
+
/**
|
|
990
|
+
* Computes the determinant of the matrix's linear part.
|
|
991
|
+
* @param m Matrix to compute the determinant of.
|
|
992
|
+
*/
|
|
851
993
|
static det(m) {
|
|
852
994
|
return m.a * m.d - m.c * m.b;
|
|
853
995
|
}
|
|
996
|
+
/**
|
|
997
|
+
* Computes the inverse of the given matrix.
|
|
998
|
+
* @param m Matrix to invert.
|
|
999
|
+
* @returns The inverse matrix, or `null` if `m` is singular (determinant is zero).
|
|
1000
|
+
*/
|
|
854
1001
|
static invert(m) {
|
|
855
1002
|
const det = this.det(m);
|
|
856
1003
|
if (det === 0) {
|
|
@@ -866,6 +1013,12 @@ var Matrix2D = class _Matrix2D {
|
|
|
866
1013
|
f: m.e * m.b - m.a * m.f
|
|
867
1014
|
}, invdet);
|
|
868
1015
|
}
|
|
1016
|
+
/**
|
|
1017
|
+
* Decomposes a matrix into its scale, rotation and translation components.
|
|
1018
|
+
* @param m Matrix to decompose.
|
|
1019
|
+
* @param transformOrigin Origin about which the rotation/scale are considered to be applied (defaults to `{x:0, y:0}`).
|
|
1020
|
+
* @returns The decomposed `scaleX`, `scaleY`, `rotation` (radians) and `translation`.
|
|
1021
|
+
*/
|
|
869
1022
|
static toComponents(m, transformOrigin = { x: 0, y: 0 }) {
|
|
870
1023
|
const scaleX = Math.sqrt(m.a * m.a + m.c * m.c);
|
|
871
1024
|
const scaleY = Math.sqrt(m.b * m.b + m.d * m.d);
|
|
@@ -919,6 +1072,12 @@ var Matrix2D = class _Matrix2D {
|
|
|
919
1072
|
|
|
920
1073
|
// packages/foundation/dist/esm/rect.js
|
|
921
1074
|
var Rect = class _Rect {
|
|
1075
|
+
/**
|
|
1076
|
+
* Parses a string containing exactly four numbers into a {@link Rect}.
|
|
1077
|
+
* @param rect String to parse (e.g. `"0 0 100 50"`, in `x y width height` order).
|
|
1078
|
+
* @returns The parsed rect.
|
|
1079
|
+
* @throws If `rect` does not contain exactly four numbers.
|
|
1080
|
+
*/
|
|
922
1081
|
static parse(rect) {
|
|
923
1082
|
let arr = parseAsNumericalArray(rect);
|
|
924
1083
|
if (arr && arr.length === 4) {
|
|
@@ -926,6 +1085,10 @@ var Rect = class _Rect {
|
|
|
926
1085
|
}
|
|
927
1086
|
throw new Error(`Cannot parse "${rect}" as a valid Rect.`);
|
|
928
1087
|
}
|
|
1088
|
+
/**
|
|
1089
|
+
* Type-guards a value as a valid {@link Rect} object.
|
|
1090
|
+
* @param obj Value to check.
|
|
1091
|
+
*/
|
|
929
1092
|
static isRect(obj) {
|
|
930
1093
|
return Point.isPoint(obj) && Size.isSize(obj);
|
|
931
1094
|
}
|
|
@@ -1039,6 +1202,10 @@ var Rect = class _Rect {
|
|
|
1039
1202
|
|
|
1040
1203
|
// packages/foundation/dist/esm/history-svc.js
|
|
1041
1204
|
var HistoryService = class {
|
|
1205
|
+
/**
|
|
1206
|
+
* @param state Initial state.
|
|
1207
|
+
* @param maxlength Maximum number of stored states (undo queue + redo stack); unbounded when omitted.
|
|
1208
|
+
*/
|
|
1042
1209
|
constructor(state, maxlength) {
|
|
1043
1210
|
this.#current = state;
|
|
1044
1211
|
this.#maxlength = maxlength;
|
|
@@ -1056,9 +1223,11 @@ var HistoryService = class {
|
|
|
1056
1223
|
get current() {
|
|
1057
1224
|
return this.#current;
|
|
1058
1225
|
}
|
|
1226
|
+
/** Gets whether there is a previous state to revert to. @readonly */
|
|
1059
1227
|
get canUndo() {
|
|
1060
1228
|
return this.#backwards.length > 0;
|
|
1061
1229
|
}
|
|
1230
|
+
/** Gets whether there is a subsequent state to reapply. @readonly */
|
|
1062
1231
|
get canRedo() {
|
|
1063
1232
|
return this.#forwards.length > 0;
|
|
1064
1233
|
}
|
|
@@ -1067,6 +1236,7 @@ var HistoryService = class {
|
|
|
1067
1236
|
set maxlength(v) {
|
|
1068
1237
|
this.#maxlength = v;
|
|
1069
1238
|
}
|
|
1239
|
+
/** Reverts to the previous state, if any (see {@link canUndo}), moving the current state onto the redo stack. */
|
|
1070
1240
|
undo() {
|
|
1071
1241
|
if (this.canUndo) {
|
|
1072
1242
|
const back = this.#backwards, fore = this.#forwards, current = this.#current;
|
|
@@ -1074,6 +1244,7 @@ var HistoryService = class {
|
|
|
1074
1244
|
this.#current = back.pop();
|
|
1075
1245
|
}
|
|
1076
1246
|
}
|
|
1247
|
+
/** Reapplies the next state, if any (see {@link canRedo}), moving the current state onto the undo queue. */
|
|
1077
1248
|
redo() {
|
|
1078
1249
|
if (this.canRedo) {
|
|
1079
1250
|
const back = this.#backwards, fore = this.#forwards, current = this.#current;
|
|
@@ -1081,6 +1252,11 @@ var HistoryService = class {
|
|
|
1081
1252
|
this.#current = fore.shift();
|
|
1082
1253
|
}
|
|
1083
1254
|
}
|
|
1255
|
+
/**
|
|
1256
|
+
* Pushes a new current state, clearing the redo stack and enqueuing the previous current state for undo.
|
|
1257
|
+
* Trims the undo queue to `maxlength`, if set.
|
|
1258
|
+
* @param state New current state.
|
|
1259
|
+
*/
|
|
1084
1260
|
push(state) {
|
|
1085
1261
|
this.#forwards.splice(0);
|
|
1086
1262
|
this.#backwards.push(this.#current);
|
|
@@ -1090,6 +1266,7 @@ var HistoryService = class {
|
|
|
1090
1266
|
queue.splice(0, queue.length - max);
|
|
1091
1267
|
}
|
|
1092
1268
|
}
|
|
1269
|
+
/** Clears both the undo queue and the redo stack, leaving the current state untouched. */
|
|
1093
1270
|
reset() {
|
|
1094
1271
|
this.#forwards.splice(0);
|
|
1095
1272
|
this.#backwards.splice(0);
|
|
@@ -1105,6 +1282,11 @@ var DefaultImagingResizeOptions = {
|
|
|
1105
1282
|
type: "image/jpeg"
|
|
1106
1283
|
};
|
|
1107
1284
|
var Imaging = class _Imaging {
|
|
1285
|
+
/**
|
|
1286
|
+
* Fetches an image from a URL as a `Blob`.
|
|
1287
|
+
* @param url URL of the image to load.
|
|
1288
|
+
* @returns A promise resolving with the loaded `Blob`, or `null` if the fetch response was not OK.
|
|
1289
|
+
*/
|
|
1108
1290
|
static async loadImage(url) {
|
|
1109
1291
|
const response = await fetch(url);
|
|
1110
1292
|
if (!response.ok) {
|
|
@@ -1144,14 +1326,27 @@ var Imaging = class _Imaging {
|
|
|
1144
1326
|
// packages/foundation/dist/esm/keygenerator.js
|
|
1145
1327
|
var Keys = class _Keys {
|
|
1146
1328
|
static #seed;
|
|
1329
|
+
/**
|
|
1330
|
+
* Generates a process-wide monotonically increasing numeric id, seeded from the current timestamp.
|
|
1331
|
+
* @returns A new unique numeric id.
|
|
1332
|
+
*/
|
|
1147
1333
|
static uniqueId() {
|
|
1148
1334
|
let seed = _Keys.#seed || Date.now();
|
|
1149
1335
|
return _Keys.#seed = ++seed;
|
|
1150
1336
|
}
|
|
1337
|
+
/**
|
|
1338
|
+
* Generates a process-wide unique id, base-62 encoded.
|
|
1339
|
+
* @returns A new unique string code.
|
|
1340
|
+
*/
|
|
1151
1341
|
static uniqueCode() {
|
|
1152
1342
|
const newid = _Keys.uniqueId();
|
|
1153
1343
|
return newid.toBase62();
|
|
1154
1344
|
}
|
|
1345
|
+
/**
|
|
1346
|
+
* Generates a random base-62 string of at least the given length.
|
|
1347
|
+
* @param length Minimum length of the generated string.
|
|
1348
|
+
* @returns A random string.
|
|
1349
|
+
*/
|
|
1155
1350
|
static randomString(length) {
|
|
1156
1351
|
let retval = "";
|
|
1157
1352
|
do {
|
|
@@ -1163,12 +1358,30 @@ var Keys = class _Keys {
|
|
|
1163
1358
|
|
|
1164
1359
|
// packages/foundation/dist/esm/numbers.js
|
|
1165
1360
|
var Numbers = class {
|
|
1361
|
+
/**
|
|
1362
|
+
* Rounds a number to the nearest multiple of `step`.
|
|
1363
|
+
* @param x Value to round.
|
|
1364
|
+
* @param step Rounding step/increment (defaults to 1).
|
|
1365
|
+
* @returns The rounded value.
|
|
1366
|
+
*/
|
|
1166
1367
|
static round(x, step = 1) {
|
|
1167
1368
|
return Math.round(x / step) * step;
|
|
1168
1369
|
}
|
|
1370
|
+
/**
|
|
1371
|
+
* Computes the logarithm of `x` in an arbitrary `base`.
|
|
1372
|
+
* @param x Value to compute the logarithm of.
|
|
1373
|
+
* @param base Logarithm base.
|
|
1374
|
+
*/
|
|
1169
1375
|
static log(x, base) {
|
|
1170
1376
|
return Math.log10(x) / Math.log10(base);
|
|
1171
1377
|
}
|
|
1378
|
+
/**
|
|
1379
|
+
* Converts a number (or numeric string) from one base to another.
|
|
1380
|
+
* @param v Value to convert, expressed in base `from`.
|
|
1381
|
+
* @param from Source base (2-36).
|
|
1382
|
+
* @param to Target base (2-36).
|
|
1383
|
+
* @returns The value re-expressed in base `to`, as a string; `"NaN"` if `v` is not a valid number in base `from`.
|
|
1384
|
+
*/
|
|
1172
1385
|
static rebase(v, from, to) {
|
|
1173
1386
|
const vStr = v.toString();
|
|
1174
1387
|
const firstPass = parseInt(vStr, from);
|
|
@@ -1264,6 +1477,14 @@ var Strings = class {
|
|
|
1264
1477
|
let retval = v.toString();
|
|
1265
1478
|
return retval.padStart(targetLength, padChar);
|
|
1266
1479
|
}
|
|
1480
|
+
/**
|
|
1481
|
+
* Formats a template string, replacing `{0}`, `{1}`, ... placeholders with the corresponding arguments.
|
|
1482
|
+
* Doubled braces (`{{`/`}}`) escape a placeholder.
|
|
1483
|
+
* @param template Template string containing `{n}` placeholders.
|
|
1484
|
+
* @param args Values to substitute into the placeholders, by index.
|
|
1485
|
+
* @returns The formatted string.
|
|
1486
|
+
* @throws If the template references an argument index that was not supplied.
|
|
1487
|
+
*/
|
|
1267
1488
|
static format(template, ...args) {
|
|
1268
1489
|
const array = Array.from(args);
|
|
1269
1490
|
let retval = template;
|
|
@@ -1279,6 +1500,13 @@ var Strings = class {
|
|
|
1279
1500
|
}
|
|
1280
1501
|
return retval;
|
|
1281
1502
|
}
|
|
1503
|
+
/**
|
|
1504
|
+
* Computes a diff between two strings, using the Longest Common Subsequence algorithm.
|
|
1505
|
+
* @param a First (original) string.
|
|
1506
|
+
* @param b Second (modified) string.
|
|
1507
|
+
* @param mode Diffing granularity: `'char'` (default), `'word'` or `'line'`.
|
|
1508
|
+
* @returns Array of {@link DiffToken}s describing unchanged, removed and added chunks.
|
|
1509
|
+
*/
|
|
1282
1510
|
static diff(a, b, mode = "char") {
|
|
1283
1511
|
switch (mode) {
|
|
1284
1512
|
case "line":
|
|
@@ -1289,6 +1517,12 @@ var Strings = class {
|
|
|
1289
1517
|
return diffChars(a, b);
|
|
1290
1518
|
}
|
|
1291
1519
|
}
|
|
1520
|
+
/**
|
|
1521
|
+
* Computes the cryptographic hash of a string using the SubtleCrypto API.
|
|
1522
|
+
* @param input String to hash.
|
|
1523
|
+
* @param algo Hash algorithm to use (defaults to `SHA-256`).
|
|
1524
|
+
* @returns A promise resolving with the hash, hex-encoded.
|
|
1525
|
+
*/
|
|
1292
1526
|
static async hash(input, algo = "SHA-256") {
|
|
1293
1527
|
const hashBuffer = await crypto.subtle.digest(algo, new TextEncoder().encode(input));
|
|
1294
1528
|
return Array.from(new Uint8Array(hashBuffer)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
@@ -1337,9 +1571,19 @@ var LexerClass = class {
|
|
|
1337
1571
|
}
|
|
1338
1572
|
};
|
|
1339
1573
|
var Parser = class {
|
|
1574
|
+
/**
|
|
1575
|
+
* @param _lexer Lexer implementation to use (defaults to a built-in greedy, rule-ordered lexer).
|
|
1576
|
+
*/
|
|
1340
1577
|
constructor(_lexer = new LexerClass()) {
|
|
1341
1578
|
this._lexer = _lexer;
|
|
1342
1579
|
}
|
|
1580
|
+
/**
|
|
1581
|
+
* Tokenizes `input` against `grammar` and renders the resulting token tree.
|
|
1582
|
+
* @param input String to parse.
|
|
1583
|
+
* @param grammar Ordered list of rules describing the grammar.
|
|
1584
|
+
* @param renderer Renderer used to turn the token tree into the output string.
|
|
1585
|
+
* @returns The rendered output.
|
|
1586
|
+
*/
|
|
1343
1587
|
parse(input, grammar, renderer) {
|
|
1344
1588
|
const tokens = this._lexer.tokenize(input, grammar);
|
|
1345
1589
|
return renderer.render(tokens);
|
|
@@ -1975,6 +2219,13 @@ function isRenderer(obj) {
|
|
|
1975
2219
|
return obj && typeof obj === "object" && typeof obj.render === "function";
|
|
1976
2220
|
}
|
|
1977
2221
|
var Parser2 = class extends Parser {
|
|
2222
|
+
/**
|
|
2223
|
+
* Parses Markdown `input` and renders it to an HTML string.
|
|
2224
|
+
* @param input Markdown source.
|
|
2225
|
+
* @param extraGrammar Additional grammar rules to extend the built-in Markdown syntax.
|
|
2226
|
+
* @param extraItemRenderer Fallback renderer invoked for token types not natively handled (e.g. tokens produced by `extraGrammar`); defaults to returning the token's `text`.
|
|
2227
|
+
* @returns The rendered HTML string.
|
|
2228
|
+
*/
|
|
1978
2229
|
toHtml(input, extraGrammar, extraItemRenderer) {
|
|
1979
2230
|
const renderer = new HtmlRenderer(extraItemRenderer);
|
|
1980
2231
|
if (NullChecker.isNullOrEmpty(extraGrammar)) {
|
|
@@ -1982,6 +2233,12 @@ var Parser2 = class extends Parser {
|
|
|
1982
2233
|
}
|
|
1983
2234
|
return this.parse(input, getGrammar(extraGrammar), renderer);
|
|
1984
2235
|
}
|
|
2236
|
+
/**
|
|
2237
|
+
* Parses Markdown `input` and returns its token tree as a plain (JSON-serializable) array, useful for inspection/debugging.
|
|
2238
|
+
* @param input Markdown source.
|
|
2239
|
+
* @param extraGrammar Additional grammar rules to extend the built-in Markdown syntax.
|
|
2240
|
+
* @returns The parsed token tree.
|
|
2241
|
+
*/
|
|
1985
2242
|
tokenize(input, extraGrammar) {
|
|
1986
2243
|
const json = this.parse(input, getGrammar(extraGrammar), new TokenRenderer());
|
|
1987
2244
|
return JSON.parse(json);
|