@jackens/nnn 2023.11.1 → 2023.11.4

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.
Files changed (2) hide show
  1. package/nnn.js +537 -415
  2. package/package.json +1 -1
package/nnn.js CHANGED
@@ -1,111 +1,26 @@
1
- // src/eq.js
2
- var eq = (
3
- /** @return {boolean} */
4
- (x, y) => {
5
- if (x === y) {
6
- return true;
7
- }
8
- const xConstructor = x?.constructor;
9
- if (xConstructor === y?.constructor) {
10
- if (xConstructor === Number) {
11
- return isNaN(x) && isNaN(y) || +x === +y;
12
- }
13
- if (xConstructor === Date) {
14
- return +x === +y;
15
- }
16
- if (xConstructor === String || xConstructor === RegExp) {
17
- return "" + x === "" + y;
18
- }
19
- if (xConstructor === Array) {
20
- return x.length === y.length && x.every((item, index) => eq(item, y[index]));
21
- }
22
- if (xConstructor === Object) {
23
- const keysOfX = Object.keys(x);
24
- return keysOfX.length === Object.keys(y).length && keysOfX.every((key) => eq(x[key], y[key]));
25
- }
26
- if (xConstructor === Set || xConstructor === Map) {
27
- if (x.size !== y.size) {
28
- return false;
29
- }
30
- const xa = [...x];
31
- const ya = [...y];
32
- return xa.every((xv) => ya.find((yv) => eq(xv, yv)));
33
- }
34
- }
35
- return false;
36
- }
37
- );
38
-
39
- // src/is.js
40
- var is = (type, arg) => arg?.constructor === type;
41
-
42
- // src/h.js
43
- var _NS = {
44
- xlink: "http://www.w3.org/1999/xlink"
45
- };
46
- var _h = (namespaceURI) => {
47
- const createElement = namespaceURI == null ? (tag) => document.createElement(tag) : (tag) => document.createElementNS(namespaceURI, tag);
48
- const h2 = (tagOrNode, ...args) => {
49
- const node = is(String, tagOrNode) ? createElement(tagOrNode) : tagOrNode;
50
- for (const arg of args) {
51
- let child = null;
52
- if (arg instanceof Node) {
53
- child = arg;
54
- } else if (is(String, arg) || is(Number, arg)) {
55
- child = new Text(arg);
56
- } else if (is(Array, arg)) {
57
- child = h2(...arg);
58
- } else if (arg != null) {
59
- for (const name in arg) {
60
- const value = arg[name];
61
- if (name[0] === "$") {
62
- const name1 = name.slice(1);
63
- if (is(Object, value)) {
64
- node[name1] = node[name1] ?? {};
65
- Object.assign(node[name1], value);
66
- } else {
67
- node[name1] = value;
68
- }
69
- } else if (node instanceof Element) {
70
- const indexOfColon = name.indexOf(":");
71
- if (indexOfColon >= 0) {
72
- const ns = _NS[name.slice(0, indexOfColon)];
73
- if (ns != null) {
74
- const basename = name.slice(indexOfColon + 1);
75
- if (value === true) {
76
- node.setAttributeNS(ns, basename, "");
77
- } else if (value === false) {
78
- node.removeAttributeNS(ns, basename);
79
- } else {
80
- node.setAttributeNS(ns, basename, is(String, value) ? value : "" + value);
81
- }
82
- }
83
- } else {
84
- if (value === true) {
85
- node.setAttribute(name, "");
86
- } else if (value === false) {
87
- node.removeAttribute(name);
88
- } else {
89
- node.setAttribute(name, is(String, value) ? value : "" + value);
90
- }
91
- }
92
- }
93
- }
94
- }
95
- if (child != null) {
96
- node.appendChild(child);
97
- }
98
- }
99
- return node;
100
- };
101
- return h2;
102
- };
103
- var h = _h();
104
- var s = _h("http://www.w3.org/2000/svg");
105
-
106
- // src/chartable.js
107
- var _COLORS = ["#e22", "#e73", "#fc3", "#ad4", "#4d9", "#3be", "#45d", "#c3e"];
108
- var chartable = ({
1
+ const _COLORS = ['#e22', '#e73', '#fc3', '#ad4', '#4d9', '#3be', '#45d', '#c3e']
2
+
3
+ /**
4
+ * @param {{
5
+ * bottom?: number;
6
+ * gapX?: number;
7
+ * gapY?: number;
8
+ * headerColumn?: boolean;
9
+ * headerRow?: boolean;
10
+ * id?: string;
11
+ * left?: number;
12
+ * maxY?: number;
13
+ * right?: number;
14
+ * singleScale?: boolean;
15
+ * table?: HTMLTableElement;
16
+ * title?: string;
17
+ * top?: number;
18
+ * xLabels?: string[];
19
+ * zLabels?: string[];
20
+ * zxY?: number[][];
21
+ * }} options
22
+ */
23
+ export const chartable = ({
109
24
  bottom = 50,
110
25
  gapX = 70,
111
26
  gapY = 30,
@@ -124,405 +39,612 @@ var chartable = ({
124
39
  zxY = []
125
40
  } = {}) => {
126
41
  if (table != null) {
127
- const zxYNotPassed = !zxY.length;
128
- const xLabelsNotPassed = !xLabels.length;
129
- const zLabelsNotPassed = !zLabels.length;
130
- table.querySelectorAll("tr").forEach((row, r) => row.querySelectorAll("td,th").forEach((col, c) => {
131
- const x = r - +headerRow;
132
- const z = c - +headerColumn;
133
- const value = col.innerText;
42
+ const zxYNotPassed = !zxY.length
43
+ const xLabelsNotPassed = !xLabels.length
44
+ const zLabelsNotPassed = !zLabels.length
45
+
46
+ table.querySelectorAll('tr').forEach((row, r) => row.querySelectorAll('td,th').forEach((col, c) => {
47
+ const x = r - +headerRow
48
+ const z = c - +headerColumn
49
+ // @ts-expect-error
50
+ const value = col.innerText
51
+
134
52
  if (x >= 0 && z >= 0 && zxYNotPassed) {
135
- zxY[z] = zxY[z] ?? [];
136
- zxY[z][x] = parseFloat(value);
53
+ zxY[z] = zxY[z] ?? []
54
+ zxY[z][x] = parseFloat(value)
137
55
  } else if (x >= 0 && z < 0 && xLabelsNotPassed) {
138
- xLabels[x] = value;
56
+ xLabels[x] = value
139
57
  } else if (x < 0 && z >= 0 && zLabelsNotPassed) {
140
- zLabels[z] = value;
58
+ zLabels[z] = value
141
59
  }
142
- }));
60
+ }))
143
61
  }
144
- let bestScales = [Infinity, -Infinity, Infinity, -Infinity, Infinity];
145
- const ranges = zxY.map((xY) => {
146
- xY = xY.filter((y) => !isNaN(y));
147
- return [Math.min(...xY), Math.max(...xY)];
148
- });
62
+
63
+ let bestScales = [Infinity, -Infinity, Infinity, -Infinity, Infinity]
64
+
65
+ const ranges = zxY.map(xY => {
66
+ xY = xY.filter(y => !isNaN(y))
67
+ return [Math.min(...xY), Math.max(...xY)]
68
+ })
69
+
149
70
  if (singleScale) {
150
- bestScales = ranges.reduce(([totalMin, totalMax], [min, max]) => [Math.min(totalMin, min), Math.max(totalMax, max)], bestScales);
71
+ bestScales = ranges.reduce(([totalMin, totalMax], [min, max]) => [Math.min(totalMin, min), Math.max(totalMax, max)], bestScales)
151
72
  } else {
152
- ranges.forEach(([min12, max0]) => ranges.forEach(([min0, max12]) => {
153
- if (min0 >= min12 && max12 >= max0) {
154
- let min22 = Infinity;
155
- let max22 = -Infinity;
73
+ ranges.forEach(([min1, max0]) => ranges.forEach(([min0, max1]) => {
74
+ if (min0 >= min1 && max1 >= max0) {
75
+ let min2 = Infinity
76
+ let max2 = -Infinity
77
+
156
78
  ranges.forEach(([min, max]) => {
157
- if (min < min12 || max12 < max) {
158
- if (min22 > min) {
159
- min22 = min;
79
+ if (min < min1 || max1 < max) {
80
+ if (min2 > min) {
81
+ min2 = min
160
82
  }
161
- if (max22 < max) {
162
- max22 = max;
83
+ if (max2 < max) {
84
+ max2 = max
163
85
  }
164
86
  }
165
- });
166
- let cost = 0;
87
+ })
88
+
89
+ let cost = 0
90
+
167
91
  ranges.forEach(([min, max]) => {
168
92
  if (min < max) {
169
- cost += 1 - (max - min) / (min12 <= min && max <= max12 ? max12 - min12 : max22 - min22);
93
+ cost += 1 - (max - min) / (min1 <= min && max <= max1 ? max1 - min1 : max2 - min2)
170
94
  }
171
- });
95
+ })
96
+
172
97
  if (bestScales[4] > cost) {
173
- bestScales = [min12, max12, min22, max22, cost];
98
+ bestScales = [min1, max1, min2, max2, cost]
174
99
  }
175
100
  }
176
- }));
101
+ }))
177
102
  }
178
- const [min1, max1, min2, max2] = bestScales;
179
- const maxX = zxY[0].length;
180
- const xi = Array.from({ length: maxX }, (_, x) => x * gapX);
181
- const yi = Array.from({ length: maxY }, (_, y) => y * gapY);
182
- const w = gapX * (maxX - 1);
183
- const h2 = gapY * (maxY - 1);
184
- const svgW = left + w + right;
185
- const svgH = top + h2 + bottom;
186
- const graph = [
187
- "g",
188
- { transform: `translate(${left} ${top})` },
189
- ...yi.map((y) => ["line", { x1: 0, x2: w, y1: y, y2: y, stroke: "#8888" }]),
190
- ...xi.map((x) => ["line", { x1: x, x2: x, y1: 0, y2: h2, stroke: "#8888" }])
191
- ];
192
- const lColors = ["g", { class: "chartable-z-colors", transform: "translate(-80 0)" }];
193
- const lLabels = ["g", { class: "chartable-z-labels", transform: "translate(-95 0)" }];
194
- const rColors = ["g", { class: "chartable-z-colors", transform: "translate(80 0)" }];
195
- const rLabels = ["g", { class: "chartable-z-labels", transform: "translate(95 0)" }];
196
- const yLabel = (min, max, y) => (min + (max - min) * (maxY - 1 - y) / (maxY - 1)).toFixed(2).replace(/\.?0+$/, "");
103
+
104
+ const [min1, max1, min2, max2] = bestScales
105
+ const maxX = zxY[0].length
106
+ const xi = Array.from({ length: maxX }, (_, x) => x * gapX)
107
+ const yi = Array.from({ length: maxY }, (_, y) => y * gapY)
108
+ const w = gapX * (maxX - 1)
109
+ const h = gapY * (maxY - 1)
110
+ const svgW = left + w + right
111
+ const svgH = top + h + bottom
112
+ const /** @type {import('./h.js').HArgs} */ graph = ['g', { transform: `translate(${left} ${top})` },
113
+ ...yi.map(y => ['line', { x1: 0, x2: w, y1: y, y2: y, stroke: '#8888' }]),
114
+ ...xi.map(x => ['line', { x1: x, x2: x, y1: 0, y2: h, stroke: '#8888' }])]
115
+ const /** @type {import('./h.js').HArgs} */ lColors = ['g', { class: 'chartable-z-colors', transform: 'translate(-80 0)' }]
116
+ const /** @type {import('./h.js').HArgs} */ lLabels = ['g', { class: 'chartable-z-labels', transform: 'translate(-95 0)' }]
117
+ const /** @type {import('./h.js').HArgs} */ rColors = ['g', { class: 'chartable-z-colors', transform: 'translate(80 0)' }]
118
+ const /** @type {import('./h.js').HArgs} */ rLabels = ['g', { class: 'chartable-z-labels', transform: 'translate(95 0)' }]
119
+ const yLabel = (/** @type {number} */ min, /** @type {number} */ max, /** @type {number} */ y) => (min + (max - min) * (maxY - 1 - y) / (maxY - 1)).toFixed(2).replace(/\.?0+$/, '')
120
+
197
121
  zxY.forEach((xa, z) => {
198
- const cls = `chartable-z-${z + 1}`;
199
- const fill = _COLORS[z % _COLORS.length];
200
- let [min, max] = ranges[z];
122
+ const cls = `chartable-z-${z + 1}`
123
+ const fill = _COLORS[z % _COLORS.length]
124
+ let [min, max] = ranges[z]
125
+
201
126
  if (min1 <= min && max <= max1) {
202
- min = min1;
203
- max = max1;
204
- lColors.push(["circle", { class: cls, cx: 0, cy: gapY * (lColors.length - 2), r: 5, fill }]);
205
- lLabels.push([
206
- "text",
207
- { x: 0, y: gapY * (lLabels.length - 2), "text-anchor": "end", "alignment-baseline": "middle" },
208
- zLabels[z]
209
- ]);
127
+ min = min1
128
+ max = max1
129
+ lColors.push(['circle', { class: cls, cx: 0, cy: gapY * (lColors.length - 2), r: 5, fill }])
130
+ lLabels.push(['text',
131
+ { x: 0, y: gapY * (lLabels.length - 2), 'text-anchor': 'end', 'alignment-baseline': 'middle' },
132
+ zLabels[z]])
210
133
  } else {
211
- min = min2;
212
- max = max2;
213
- rColors.push(["circle", { class: cls, cx: 0, cy: gapY * (rColors.length - 2), r: 5, fill }]);
214
- rLabels.push([
215
- "text",
216
- { x: 0, y: gapY * (rLabels.length - 2), "text-anchor": "start", "alignment-baseline": "middle" },
217
- zLabels[z]
218
- ]);
134
+ min = min2
135
+ max = max2
136
+ rColors.push(['circle', { class: cls, cx: 0, cy: gapY * (rColors.length - 2), r: 5, fill }])
137
+ rLabels.push(['text',
138
+ { x: 0, y: gapY * (rLabels.length - 2), 'text-anchor': 'start', 'alignment-baseline': 'middle' },
139
+ zLabels[z]])
219
140
  }
220
- const y = xa.map((x) => isNaN(x) ? x : h2 * (max - x) / (max - min));
141
+
142
+ const y = xa.map(x => isNaN(x) ? x : h * (max - x) / (max - min))
143
+
221
144
  xi.forEach((x, i) => {
222
145
  if (!isNaN(y[i])) {
223
- graph.push(["circle", { class: cls, cx: x, cy: y[i], r: 5, fill }]);
146
+ graph.push(['circle', { class: cls, cx: x, cy: y[i], r: 5, fill }])
147
+
224
148
  if (!isNaN(y[i - 1])) {
225
- graph.push(["line", { class: cls, x1: x, x2: xi[i - 1], y1: y[i], y2: y[i - 1], stroke: fill }]);
149
+ graph.push(['line', { class: cls, x1: x, x2: xi[i - 1], y1: y[i], y2: y[i - 1], stroke: fill }])
226
150
  }
227
151
  }
228
- });
229
- });
230
- return s(
231
- "svg",
232
- {
233
- viewBox: `0 0 ${svgW} ${svgH}`,
234
- width: `${svgW}px`,
235
- height: `${svgH}px`,
236
- class: "chartable"
237
- },
238
- id != null ? { id } : null,
239
- title != null ? [
240
- "text",
241
- { class: "chartable-title", x: svgW / 2, y: top / 2, "text-anchor": "middle", "alignment-baseline": "middle" },
242
- title
243
- ] : null,
244
- graph,
245
- min1 < Infinity ? [
246
- "g",
247
- { class: "chartable-left", transform: `translate(${left} ${top})` },
248
- [
249
- "g",
250
- { class: "chartable-y-labels", transform: "translate(-15 0)" },
251
- ...yi.map((y, i) => [
252
- "text",
253
- { x: 0, y, "text-anchor": "end", "alignment-baseline": "middle" },
254
- yLabel(min1, max1, i)
255
- ])
256
- ],
257
- lColors,
258
- lLabels
259
- ] : null,
260
- min2 < Infinity ? [
261
- "g",
262
- { class: "chartable-right", transform: `translate(${left + w} ${top})` },
263
- [
264
- "g",
265
- { class: "chartable-y-labels", transform: "translate(15 0)" },
266
- ...yi.map((y, i) => [
267
- "text",
268
- { x: 0, y, "text-anchor": "start", "alignment-baseline": "middle" },
269
- yLabel(min2, max2, i)
270
- ])
271
- ],
272
- rColors,
273
- rLabels
274
- ] : null,
275
- xLabels.length > 0 ? [
276
- "g",
277
- { transform: `translate(${left} ${top + h2})` },
278
- [
279
- "g",
280
- { class: "chartable-x-labels", transform: "translate(0 15)" },
281
- ...xi.map((x, i) => [
282
- "text",
283
- { x, y: 0, "text-anchor": "middle", "alignment-baseline": "hanging" },
284
- xLabels[i]
285
- ])
286
- ]
287
- ] : null
288
- );
289
- };
290
-
291
- // src/escape.js
292
- var escapeValues = (escapeMap, values) => values.map((value) => (escapeMap.get(value?.constructor) ?? escapeMap.get(void 0))?.(value) ?? "");
293
- var escape = (escapeMap, template, ...values) => String.raw(template, ...escapeValues(escapeMap, values));
294
-
295
- // src/has.js
296
- var has = (key, ref) => (is(String, key) || is(Number, key) || is(Symbol, key)) && Object.hasOwnProperty.call(ref ?? Object, key);
297
-
298
- // src/fixTypography.js
299
- var _TAGS_TO_SKIP = { IFRAME: 1, NOSCRIPT: 1, PRE: 1, SCRIPT: 1, STYLE: 1, TEXTAREA: 1 };
300
- var fixTypography = (node) => {
301
- const queue = [node];
152
+ })
153
+ })
154
+
155
+ return s('svg', {
156
+ viewBox: `0 0 ${svgW} ${svgH}`,
157
+ width: `${svgW}px`,
158
+ height: `${svgH}px`,
159
+ class: 'chartable'
160
+ }, id != null ? { id } : null, title != null
161
+ ? ['text',
162
+ { class: 'chartable-title', x: svgW / 2, y: top / 2, 'text-anchor': 'middle', 'alignment-baseline': 'middle' },
163
+ title]
164
+ : null,
165
+ graph,
166
+ min1 < Infinity
167
+ ? ['g', { class: 'chartable-left', transform: `translate(${left} ${top})` },
168
+ ['g', { class: 'chartable-y-labels', transform: 'translate(-15 0)' },
169
+ ...yi.map((y, i) => ['text',
170
+ { x: 0, y, 'text-anchor': 'end', 'alignment-baseline': 'middle' },
171
+ yLabel(min1, max1, i)])],
172
+ lColors, lLabels]
173
+ : null,
174
+ min2 < Infinity
175
+ ? ['g', { class: 'chartable-right', transform: `translate(${left + w} ${top})` },
176
+ ['g', { class: 'chartable-y-labels', transform: 'translate(15 0)' },
177
+ ...yi.map((y, i) => ['text',
178
+ { x: 0, y, 'text-anchor': 'start', 'alignment-baseline': 'middle' },
179
+ yLabel(min2, max2, i)])],
180
+ rColors, rLabels]
181
+ : null,
182
+ xLabels.length > 0
183
+ ? ['g', { transform: `translate(${left} ${top + h})` },
184
+ ['g', { class: 'chartable-x-labels', transform: 'translate(0 15)' },
185
+ ...xi.map((x, i) => ['text',
186
+ { x, y: 0, 'text-anchor': 'middle', 'alignment-baseline': 'hanging' },
187
+ xLabels[i]])]]
188
+ : null
189
+ )
190
+ }
191
+
192
+ export const eq = /** @return {boolean} */ (/** @type {any} */ x, /** @type {any} */ y) => {
193
+ if (x === y) {
194
+ return true
195
+ }
196
+
197
+ const xConstructor = x?.constructor
198
+
199
+ if (xConstructor === y?.constructor) {
200
+ if (xConstructor === Number) {
201
+ return (isNaN(x) && isNaN(y)) || +x === +y
202
+ }
203
+
204
+ if (xConstructor === Date) {
205
+ return +x === +y
206
+ }
207
+
208
+ if (xConstructor === String || xConstructor === RegExp) {
209
+ return '' + x === '' + y
210
+ }
211
+
212
+ if (xConstructor === Array) {
213
+ return x.length === y.length && x.every((/** @type {any} */ item, /** @type {number} */ index) => eq(item, y[index]))
214
+ }
215
+
216
+ if (xConstructor === Object) {
217
+ const keysOfX = Object.keys(x)
218
+ return keysOfX.length === Object.keys(y).length && keysOfX.every(key => eq(x[key], y[key]))
219
+ }
220
+
221
+ if (xConstructor === Set || xConstructor === Map) {
222
+ if (x.size !== y.size) {
223
+ return false
224
+ }
225
+ const xa = [...x]
226
+ const ya = [...y]
227
+ return xa.every(xv => ya.find(yv => eq(xv, yv)))
228
+ }
229
+ }
230
+
231
+ return false
232
+ }
233
+
234
+ /**
235
+ * @typedef {Map<any, (value?: any) => string>} EscapeMap
236
+ */
237
+
238
+ export const escapeValues = (
239
+ /** @type {EscapeMap} */ escapeMap,
240
+ /** @type {any[]} */ values
241
+ ) => values.map(value => (escapeMap.get(value?.constructor) ?? escapeMap.get(undefined))?.(value) ?? '')
242
+
243
+ export const escape = (
244
+ /** @type {EscapeMap} */ escapeMap,
245
+ /** @type {TemplateStringsArray} */ template,
246
+ /** @type {any[]} */ ...values
247
+ ) => String.raw(template, ...escapeValues(escapeMap, values))
248
+
249
+ const _TAGS_TO_SKIP = { IFRAME: 1, NOSCRIPT: 1, PRE: 1, SCRIPT: 1, STYLE: 1, TEXTAREA: 1 }
250
+
251
+ export const fixTypography = (/** @type {Node} */ node) => {
252
+ const /** @type {Node[]} */ queue = [node]
253
+
302
254
  while (queue.length > 0) {
303
- const node0 = queue.shift();
255
+ const node0 = queue.shift()
256
+
304
257
  if (node0 instanceof Element) {
305
258
  for (let i = 0; i < node0.childNodes.length; ++i) {
306
- const childNode = node0.childNodes[i];
259
+ const childNode = node0.childNodes[i]
260
+
307
261
  if (childNode instanceof Text) {
308
- queue.push(childNode);
262
+ queue.push(childNode)
309
263
  } else if (childNode instanceof Element && !has(childNode.tagName, _TAGS_TO_SKIP)) {
310
- queue.push(childNode);
264
+ queue.push(childNode)
311
265
  }
312
266
  }
313
- } else if (node0 instanceof Text && node0.nodeValue != null && node0.nodeValue.trim() !== "") {
314
- let previousNode = node0;
267
+ } else if (node0 instanceof Text && node0.nodeValue != null && node0.nodeValue.trim() !== '') {
268
+ let /** @type {Node} */ previousNode = node0
269
+
315
270
  node0.nodeValue.split(/(\s|\(|„)([aiouwz—]\s)/gi).forEach((chunk, i) => {
316
- i %= 3;
317
- const currentNode = i === 2 ? h("span", { style: "white-space:nowrap" }, chunk) : i === 1 ? document.createTextNode(chunk) : document.createTextNode(chunk.replace(/(\/(?=[^/\s])|\.(?=[^\s]))/g, "$1\u200B"));
271
+ i %= 3
272
+
273
+ const currentNode = i === 2
274
+ ? h('span', { style: 'white-space:nowrap' }, chunk)
275
+ : i === 1
276
+ ? document.createTextNode(chunk)
277
+ : document.createTextNode(chunk.replace(/(\/(?=[^/\s])|\.(?=[^\s]))/g, '$1\u200B'))
278
+
318
279
  if (node0.parentNode != null) {
319
- node0.parentNode.insertBefore(currentNode, previousNode.nextSibling);
280
+ node0.parentNode.insertBefore(currentNode, previousNode.nextSibling)
320
281
  }
321
- previousNode = currentNode;
322
- });
323
- node0.parentNode?.removeChild(node0);
282
+
283
+ previousNode = currentNode
284
+ })
285
+
286
+ node0.parentNode?.removeChild(node0)
324
287
  }
325
288
  }
326
- };
289
+ }
290
+
291
+ /**
292
+ * @typedef {[
293
+ * string | Node,
294
+ * ...(Record<string, any> | null | undefined | Node | string | number | HArgs)[]
295
+ * ]} HArgs
296
+ */
297
+
298
+ const /** @type {Record<string, string>} */ _NS = {
299
+ xlink: 'http://www.w3.org/1999/xlink'
300
+ }
301
+
302
+ /**
303
+ * @type {{
304
+ * (namespaceURI?: null | undefined): {
305
+ * <T extends keyof HTMLElementTagNameMap>(tag: T, ...args: HArgs[1][]): HTMLElementTagNameMap[T];
306
+ * <N extends Node> (node: N, ...args: HArgs[1][]): N;
307
+ * (...args: HArgs): Node;
308
+ * };
309
+ * (namespaceURI: 'http://www.w3.org/2000/svg'): {
310
+ * <T extends keyof SVGElementTagNameMap> (tag: T, ...args: HArgs[1][]): SVGElementTagNameMap[T];
311
+ * <N extends Node> (node: N, ...args: HArgs[1][]): N;
312
+ * (...args: HArgs): Node;
313
+ * };
314
+ * }}
315
+ */
316
+ const _h = (/** @type {string?=} */ namespaceURI) => {
317
+ const createElement = namespaceURI == null
318
+ ? (/** @type {string } */ tag) => document.createElement(tag)
319
+ : (/** @type {string } */ tag) => document.createElementNS(namespaceURI, tag)
320
+
321
+ const h = (/** @type {HArgs[0]} */ tagOrNode, /** @type {HArgs[1][]} */ ...args) => {
322
+ const node = is(String, tagOrNode) ? createElement(tagOrNode) : tagOrNode
323
+
324
+ for (const arg of args) {
325
+ let child = null
326
+
327
+ if (arg instanceof Node) {
328
+ child = arg
329
+ } else if (is(String, arg) || is(Number, arg)) {
330
+ // @ts-expect-error
331
+ child = new Text(arg)
332
+ } else if (is(Array, arg)) {
333
+ // @ts-expect-error
334
+ child = h(...arg)
335
+ } else if (arg != null) {
336
+ for (const name in arg) {
337
+ const value = arg[name]
338
+
339
+ if (name[0] === '$') {
340
+ const name1 = name.slice(1)
341
+
342
+ if (is(Object, value)) {
343
+ // @ts-expect-error
344
+ node[name1] = node[name1] ?? {}
345
+ // @ts-expect-error
346
+ Object.assign(node[name1], value)
347
+ } else {
348
+ // @ts-expect-error
349
+ node[name1] = value
350
+ }
351
+ } else if (node instanceof Element) {
352
+ const indexOfColon = name.indexOf(':')
353
+
354
+ if (indexOfColon >= 0) {
355
+ const /** @type {string=} */ ns = _NS[name.slice(0, indexOfColon)]
356
+
357
+ if (ns != null) {
358
+ const basename = name.slice(indexOfColon + 1)
359
+
360
+ if (value === true) {
361
+ node.setAttributeNS(ns, basename, '')
362
+ } else if (value === false) {
363
+ node.removeAttributeNS(ns, basename)
364
+ } else {
365
+ node.setAttributeNS(ns, basename, is(String, value) ? value : '' + value)
366
+ }
367
+ }
368
+ } else {
369
+ if (value === true) {
370
+ node.setAttribute(name, '')
371
+ } else if (value === false) {
372
+ node.removeAttribute(name)
373
+ } else {
374
+ node.setAttribute(name, is(String, value) ? value : '' + value)
375
+ }
376
+ }
377
+ }
378
+ }
379
+ }
380
+
381
+ if (child != null) {
382
+ node.appendChild(child)
383
+ }
384
+ }
385
+
386
+ return node
387
+ }
388
+
389
+ return h
390
+ }
391
+
392
+ export const h = _h()
393
+
394
+ export const s = _h('http://www.w3.org/2000/svg')
395
+
396
+ export const has = (/** @type {any} */ key, /** @type {any} */ ref) => (is(String, key) || is(Number, key) || is(Symbol, key)) && Object.hasOwnProperty.call(ref ?? Object, key)
397
+
398
+ /**
399
+ * @template {abstract new (...args: any[]) => any} T
400
+ *
401
+ * @type {{
402
+ * (type: BigIntConstructor, arg: any): arg is bigint;
403
+ * (type: BooleanConstructor, arg: any): arg is boolean;
404
+ * (type: NumberConstructor, arg: any): arg is number;
405
+ * (type: StringConstructor, arg: any): arg is string;
406
+ * (type: SymbolConstructor, arg: any): arg is symbol;
407
+ * (type: undefined, arg: any): arg is undefined | null;
408
+ * <T extends abstract new (...args: any[]) => any>(type: T, arg: any): arg is InstanceType<T>;
409
+ * }}
410
+ *
411
+ * @return {arg is bigint | boolean | number | string | symbol | undefined | null | InstanceType<T>}
412
+ */
413
+ export const is = (/** @type {T} */ type, /** @type {any} */ arg) => arg?.constructor === type
414
+
415
+ /**
416
+ * @typedef {{
417
+ * [attributeOrSelector: string]: string | number | JcssNode;
418
+ * }} JcssNode
419
+ */
420
+
421
+ /**
422
+ * @typedef {Record<string, JcssNode>} JcssRoot
423
+ */
424
+
425
+ const _jcss = (
426
+ /** @type {JcssNode} */ node,
427
+ /** @type {string} */ prefix,
428
+ /** @type {string[]} */ result,
429
+ /** @type {(text: string) => string} */ split
430
+ ) => {
431
+ const /** @type {[JcssNode | string[], string][]} */ queue = [[node, prefix]]
327
432
 
328
- // src/jcss.js
329
- var _jcss = (node, prefix, result, split) => {
330
- const queue = [[node, prefix]];
331
433
  while (queue.length) {
332
- const [style2, prefix2] = queue.shift() ?? [];
434
+ const [style2, prefix2] = queue.shift() ?? []
435
+
333
436
  if (style2 == null || prefix2 == null) {
334
- continue;
437
+ continue
335
438
  }
439
+
336
440
  if (is(Array, style2)) {
337
- result.push(prefix2, prefix2 !== "" ? "{" : "", style2.join(";"), prefix2 !== "" ? "}" : "");
441
+ result.push(prefix2, prefix2 !== '' ? '{' : '', style2.join(';'), prefix2 !== '' ? '}' : '')
338
442
  } else {
339
- const todo = [];
340
- let attributes = [];
341
- let attributesPushed = false;
443
+ const /** @type {[JcssNode | string[], string][]} */ todo = []
444
+ let /** @type {string[]} */ attributes = []
445
+ let attributesPushed = false
446
+
342
447
  for (const key in style2) {
343
- const value = style2[key];
448
+ const value = style2[key]
449
+
344
450
  if (is(String, value) || is(Number, value)) {
345
451
  if (!attributesPushed) {
346
- attributesPushed = true;
347
- attributes = [];
348
- todo.push([attributes, prefix2]);
452
+ attributesPushed = true
453
+ attributes = []
454
+ todo.push([attributes, prefix2])
349
455
  }
350
- attributes.push(`${split(key).replace(/([A-Z])/g, (_, letter) => "-" + letter.toLowerCase())}:${value}`);
456
+
457
+ attributes.push(`${split(key).replace(/([A-Z])/g, (_, letter) => '-' + letter.toLowerCase())}:${value}`)
351
458
  } else {
352
- attributesPushed = false;
353
- const newPrefix = [];
354
- const keySplitted = key.split(",");
355
- for (const prefixItem of prefix2.split(",")) {
459
+ attributesPushed = false
460
+
461
+ const /** @type {string[]} */ newPrefix = []
462
+ const keySplitted = key.split(',')
463
+
464
+ for (const prefixItem of prefix2.split(',')) {
356
465
  for (const keyItem of keySplitted) {
357
- newPrefix.push(prefixItem + keyItem);
466
+ newPrefix.push(prefixItem + keyItem)
358
467
  }
359
468
  }
360
- todo.push([value, newPrefix.join(",")]);
469
+
470
+ todo.push([value, newPrefix.join(',')])
361
471
  }
362
472
  }
363
- queue.unshift(...todo);
473
+
474
+ queue.unshift(...todo)
364
475
  }
365
476
  }
366
- };
367
- var jcss = (root, splitter = "$$") => {
368
- const split = (text) => text.split(splitter)[0];
369
- const result = [];
477
+ }
478
+
479
+ export const jcss = (/** @type {JcssRoot} */ root, splitter = '$$') => {
480
+ const split = (/** @type {string} */ text) => text.split(splitter)[0]
481
+ const /** @type {string[]} */ result = []
482
+
370
483
  for (const key in root) {
371
- const value = root[key];
372
- if (key[0] === "@") {
373
- result.push(split(key) + "{");
374
- _jcss(value, "", result, split);
375
- result.push("}");
484
+ const value = root[key]
485
+
486
+ if (key[0] === '@') {
487
+ result.push(split(key) + '{')
488
+ _jcss(value, '', result, split)
489
+ result.push('}')
376
490
  } else {
377
- _jcss(value, split(key), result, split);
491
+ _jcss(value, split(key), result, split)
378
492
  }
379
493
  }
380
- return result.join("");
381
- };
382
494
 
383
- // src/jsOnParse.js
384
- var jsOnParse = (handlers, text) => JSON.parse(text, (key, value) => {
495
+ return result.join('')
496
+ }
497
+
498
+ export const jsOnParse = (
499
+ /** @type {Record<string, Function>} */ handlers,
500
+ /** @type {string} */ text
501
+ ) => JSON.parse(text, (key, value) => {
385
502
  if (is(Object, value)) {
386
- let isSecondKey = false;
503
+ let isSecondKey = false
504
+
387
505
  for (key in value) {
388
506
  if (isSecondKey) {
389
- return value;
507
+ return value
390
508
  }
391
- isSecondKey = true;
509
+ isSecondKey = true
392
510
  }
511
+
393
512
  if (has(key, handlers) && is(Array, value[key])) {
394
- return handlers[key](...value[key]);
513
+ return handlers[key](...value[key])
395
514
  }
396
515
  }
397
- return value;
398
- });
399
516
 
400
- // src/locale.js
401
- var _locale = (locales, language, text, version) => {
402
- const v = locales?.[language]?.[version]?.[text];
517
+ return value
518
+ })
519
+
520
+ const _locale = (
521
+ /** @type {Record<string, Record<string, string | Record<string, string>>>} */ locales,
522
+ /** @type {string} */ language,
523
+ /** @type {string} */ text,
524
+ /** @type {string} */ version
525
+ ) => {
526
+ // @ts-expect-error
527
+ const v = locales?.[language]?.[version]?.[text]
528
+
403
529
  if (is(String, v)) {
404
- return v;
530
+ return v
405
531
  }
406
- const t = locales?.[language]?.[text];
407
- return is(String, t) ? t : text;
408
- };
409
- var locale = (locales, defaultLanguage, languages = navigator.languages) => {
532
+
533
+ const t = locales?.[language]?.[text]
534
+
535
+ return is(String, t) ? t : text
536
+ }
537
+
538
+ export const locale = (
539
+ /** @type {Record<string, Record<string, string | Record<string, string>>>} */ locales,
540
+ /** @type {string} */ defaultLanguage,
541
+ languages = navigator.languages
542
+ ) => {
410
543
  for (const language of languages) {
411
544
  if (has(language, locales)) {
412
- return _locale.bind(0, locales, language);
545
+ // @ts-expect-error
546
+ return _locale.bind(0, locales, language)
413
547
  }
414
548
  }
415
- return _locale.bind(0, locales, defaultLanguage);
416
- };
417
549
 
418
- // src/nanolight.js
419
- var nanolight = (pattern, highlighters, code) => {
420
- const result = [];
550
+ // @ts-expect-error
551
+ return _locale.bind(0, locales, defaultLanguage)
552
+ }
553
+
554
+ export const nanolight = (
555
+ /** @type {RegExp} */ pattern,
556
+ /** @type {((chunk: string, index: number) => import('./h.js').HArgs[1])[]} */ highlighters,
557
+ /** @type {string} */ code
558
+ ) => {
559
+ const /** @type {import('./h.js').HArgs[1][]} */ result = []
560
+
421
561
  code.split(pattern).forEach((chunk, index) => {
422
- index %= highlighters.length;
562
+ index %= highlighters.length
423
563
  if (chunk != null) {
424
- result.push(highlighters[index](chunk, index));
564
+ result.push(highlighters[index](chunk, index))
425
565
  }
426
- });
427
- return result;
428
- };
566
+ })
567
+
568
+ return result
569
+ }
429
570
 
430
- // src/nanolightJs.js
431
- var nanolightJs = nanolight.bind(
432
- 0,
571
+ // @ts-expect-error
572
+ export const nanolightJs = nanolight.bind(0,
433
573
  /('.*?'|".*?"|`[\s\S]*?`)|(\/\/.*?\n|\/\*[\s\S]*?\*\/)|(break|case|catch|const|continue|debugger|default|delete|do|else|eval|export\s+type|export|extends|false|finally|for|from|function|goto|if|import|in|instanceof|is|keyof|let|NaN|new|null|package|return|super|switch|this|throw|true|try|typeof|undefined|var|void|while|with|yield)(?!\w)|([<>=.?:&|!~*/%+-])|(0x[\dabcdef]+|0o[01234567]+|0b[01]+|\d+(?:\.[\d_]+)?(?:e[+-]?[\d_]+)?)|([$\w]+)(?=\()|([$\wąćęłńóśżźĄĆĘŁŃÓŚŻŹ]+)/,
434
574
  [
435
- (chunk) => chunk,
436
- // no match
437
- (chunk) => ["u", chunk],
438
- // string literals
439
- (chunk) => ["em", chunk],
440
- // comments
441
- (chunk) => ["b", chunk],
442
- // keywords
443
- (chunk) => ["b", chunk],
444
- // operators
445
- (chunk) => ["u", chunk],
446
- // number literals
447
- (chunk) => ["ins", chunk],
448
- // function calls
449
- (chunk) => ["i", chunk]
450
- // literals
575
+ chunk => chunk, // no match
576
+ chunk => ['u', chunk], // string literals
577
+ chunk => ['em', chunk], // comments
578
+ chunk => ['b', chunk], // keywords
579
+ chunk => ['b', chunk], // operators
580
+ chunk => ['u', chunk], // number literals
581
+ chunk => ['ins', chunk], // function calls
582
+ chunk => ['i', chunk] // literals
451
583
  ]
452
- );
453
-
454
- // src/plUral.js
455
- var plUral = (singular, plural2, plural5, value) => {
456
- const absValue = Math.abs(value);
457
- const absValueMod10 = absValue % 10;
458
- return value === 1 ? singular : absValue === 12 || absValue === 13 || absValue === 14 ? plural5 : absValueMod10 === 2 || absValueMod10 === 3 || absValueMod10 === 4 ? plural2 : plural5;
459
- };
460
-
461
- // src/pro.js
462
- var pro = (ref) => new Proxy(ref, {
463
- get(target, key) {
464
- return pro(target[key] = target[key] ?? {});
584
+ )
585
+
586
+ export const plUral = (
587
+ /** @type {string} */ singular,
588
+ /** @type {string} */ plural2,
589
+ /** @type {string} */ plural5,
590
+ /** @type {number} */ value
591
+ ) => {
592
+ const absValue = Math.abs(value)
593
+ const absValueMod10 = absValue % 10
594
+
595
+ return value === 1
596
+ ? singular
597
+ : absValue === 12 || absValue === 13 || absValue === 14
598
+ ? plural5
599
+ : absValueMod10 === 2 || absValueMod10 === 3 || absValueMod10 === 4
600
+ ? plural2
601
+ : plural5
602
+ }
603
+
604
+ // @ts-expect-error
605
+ export const pro = (/** @type {any} */ ref) => new Proxy(ref, {
606
+ get (target, key) {
607
+ return pro(target[key] = target[key] ?? {})
465
608
  }
466
- });
467
-
468
- // src/refsInfo.js
469
- var refsInfo = (...refs) => {
470
- const fns = /* @__PURE__ */ new Set();
471
- refs.forEach((ref) => {
472
- while (is(Function, ref) && !fns.has(ref) && ref.toString?.()?.includes?.("[native code]")) {
473
- fns.add(ref);
474
- ref = Object.getPrototypeOf(ref);
609
+ })
610
+
611
+ export const refsInfo = (/** @type {any[]} */ ...refs) => {
612
+ const /** @type {Set<Function>} */ fns = new Set()
613
+
614
+ refs.forEach(ref => {
615
+ while (is(Function, ref) && !fns.has(ref) && ref.toString?.()?.includes?.('[native code]')) {
616
+ fns.add(ref)
617
+ ref = Object.getPrototypeOf(ref)
475
618
  }
476
- });
477
- return Array.from(fns.values()).map(
478
- /** @return {[string, string, string[]]} */
479
- (fn) => [
480
- fn.name,
481
- Object.getPrototypeOf(fn)?.name ?? "",
482
- Object.getOwnPropertyNames(fn.prototype ?? /* @__PURE__ */ Object.create(null)).sort()
483
- ]
484
- ).sort((a, b) => -(a[0] < b[0]));
485
- };
486
-
487
- // src/uuid1.js
488
- var ZEROS = "0".repeat(16);
489
- var counter = 0;
490
- var uuid1 = ({
491
- date = /* @__PURE__ */ new Date(),
619
+ })
620
+
621
+ return Array.from(fns.values()).map(/** @return {[string, string, string[]]} */ fn => [
622
+ fn.name,
623
+ Object.getPrototypeOf(fn)?.name ?? '',
624
+ Object.getOwnPropertyNames(fn.prototype ?? Object.create(null)).sort()
625
+ ]).sort((a, b) => -(a[0] < b[0]))
626
+ }
627
+
628
+ const ZEROS = '0'.repeat(16)
629
+ let counter = 0
630
+
631
+ export const uuid1 = ({
632
+ date = new Date(),
492
633
  node = Math.random().toString(16).slice(2)
493
634
  } = {}) => {
494
- const time = ZEROS + (1e4 * (+date + 122192928e5)).toString(16);
495
- counter = counter + 1 & 16383;
635
+ const time = ZEROS + (10000 * (+date + 12219292800000)).toString(16)
636
+
637
+ counter = (counter + 1) & 16383
638
+
496
639
  return time.slice(-8).concat(
497
- "-",
640
+ '-',
498
641
  time.slice(-12, -8),
499
642
  // @ts-expect-error
500
643
  -1,
501
644
  time.slice(-15, -12),
502
- "-",
503
- (8 | counter >> 12).toString(16),
645
+ '-',
646
+ (8 | (counter >> 12)).toString(16),
504
647
  (ZEROS + (counter & 4095).toString(16)).slice(-3),
505
- "-",
506
- (ZEROS + node).slice(-12)
507
- );
508
- };
509
- export {
510
- chartable,
511
- eq,
512
- escape,
513
- escapeValues,
514
- fixTypography,
515
- h,
516
- has,
517
- is,
518
- jcss,
519
- jsOnParse,
520
- locale,
521
- nanolight,
522
- nanolightJs,
523
- plUral,
524
- pro,
525
- refsInfo,
526
- s,
527
- uuid1
528
- };
648
+ '-',
649
+ (ZEROS + node).slice(-12))
650
+ }
package/package.json CHANGED
@@ -40,5 +40,5 @@
40
40
  "types": "nnn.d.ts",
41
41
  "name": "@jackens/nnn",
42
42
  "type": "module",
43
- "version": "2023.11.1"
43
+ "version": "2023.11.4"
44
44
  }