@jackens/nnn 2026.9.9 → 2026.9.28

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 (5) hide show
  1. package/README.md +1099 -0
  2. package/nnn.d.ts +175 -204
  3. package/nnn.js +81 -92
  4. package/package.json +2 -13
  5. package/readme.md +0 -1370
package/nnn.d.ts CHANGED
@@ -1,244 +1,215 @@
1
- /**
2
- * Represents a CSS rule node for the {@link c} helper. Keys
3
- * are CSS properties or nested selectors.
4
- */
1
+ /** Represents a CSS rule node for the {@link c} helper. Keys are CSS properties or nested selectors. */
5
2
  export type CNode = {
6
- [attributeOrSelector: string]: string | number | CNode | undefined;
7
- };
3
+ [attributeOrSelector: string]: string | number | CNode | undefined
4
+ }
8
5
  /**
9
- * A minimal CSS-in-JS helper that converts a JavaScript
10
- * object hierarchy into a CSS string.
11
- *
12
- * @param node An object describing CSS rules. Keys are
13
- * selectors or at-rules; values are either CSS property
14
- * values or nested rule objects. A selector key may
15
- * contain comma-separated alternatives (e.g. `'.b,.c'`);
16
- * when nested, each alternative is combined with each
17
- * parent alternative (cartesian product), producing a
18
- * comma-joined selector list (e.g. `'a.b,a.c'`).
19
- * @param splitter A delimiter used to create unique keys
20
- * (default: `'$$'`). The substring from `splitter` to the
21
- * end of a key is ignored (e.g., `src$$1` → `src`).
22
- *
23
- * @returns A CSS string representing the compiled rules.
6
+ * A minimal CSS-in-JS helper that converts a JavaScript object hierarchy into a CSS string.
7
+ *
8
+ * @param node
9
+ *
10
+ * An object describing CSS rules.
11
+ * Keys are selectors or at-rules; values are either CSS property values or nested rule objects.
12
+ * A selector key may contain comma-separated alternatives (e.g. `'.b,.c'`); when nested, each alternative is combined with each parent alternative (cartesian product), producing a comma-joined selector list (e.g. `'a.b,a.c'`).
13
+ *
14
+ * @param splitter
15
+ *
16
+ * A delimiter used to create unique keys (default: `'$$'`).
17
+ * The substring from `splitter` to the end of a key is ignored (e.g., `src$$1` → `src`).
18
+ *
19
+ * @returns
20
+ *
21
+ * A CSS string representing the compiled rules.
24
22
  */
25
- export declare const c: (node: CNode, splitter?: string) => string;
23
+ export declare const c: (node: CNode, splitter?: string) => string
26
24
  /**
27
- * Creates a tag function for escaping interpolated values
28
- * in template literals.
25
+ * Options of a {@link createTokenizer} spec controlling the tokenizer state stack.
26
+ *
27
+ * @property in
28
+ *
29
+ * State(s) in which the spec is active (default: `'root'`).
30
+ *
31
+ * @property pop
29
32
  *
30
- * @param escapeFn A function that takes a value and returns
31
- * its escaped string representation.
33
+ * Whether to pop the current state off the stack after a match (the `'root'` state at the bottom is never popped).
32
34
  *
33
- * @returns A tag function that escapes interpolated values
34
- * using the provided escape function.
35
+ * @property push
36
+ *
37
+ * State to push onto the stack after a match (applied after `pop`).
35
38
  */
36
- export declare const createEscape: (escapeFn: (value: any) => string) => (template: TemplateStringsArray, ...values: unknown[]) => string;
39
+ export type TokenizerSpecOptions = {
40
+ in?: string | string[]
41
+ pop?: boolean
42
+ push?: string
43
+ }
44
+ /** A {@link createTokenizer} spec: a `[metadata, pattern, options?]` tuple. */
45
+ export type TokenizerSpec<M> = [metadata: M, pattern: string | RegExp, options?: TokenizerSpecOptions]
37
46
  /**
38
- * A helper for building simple tokenizers (see also
39
- * {@link nanolightTs}).
47
+ * A helper for building simple stateful tokenizers (see also {@link nanolightTs}).
40
48
  *
41
49
  * @remarks
42
50
  *
43
- * 1. Matches starting at an earlier position take
44
- * precedence.
45
- * 2. Among matches at the same position, the longer one
46
- * wins.
47
- * 3. Among matches of the same position and length, the one
48
- * defined earlier wins.
49
- *
50
- * @param decorator A function that wraps each matched
51
- * chunk. It receives the matched text (`chunk`) and
52
- * optionally the `metadata` associated with the pattern
53
- * that produced the match. For unmatched text between
54
- * patterns, `metadata` is `undefined`.
55
- * @param specs An array of tuples `[metadata, pattern]`
56
- * where:
57
- *
58
- * - `metadata`: arbitrary data (e.g., a CSS class name)
59
- * passed to `decorator` when the pattern matches.
60
- * - `pattern`: a `string` or `RegExp` to match against the
61
- * input.
62
- *
63
- * @returns A tokenizer function that accepts a code string
64
- * and returns an array of decorated tokens.
65
- */
66
- export declare const createTokenizer: <M, T>(decorator: (chunk: string, metadata?: M) => T, ...specs: [M, string | RegExp][]) => (code: string) => T[];
67
- /**
68
- * Parses a CSV string into a two-dimensional array of
69
- * strings.
51
+ * 1. Matches starting at an earlier position take precedence.
52
+ * 2. Among matches at the same position, the longer one wins.
53
+ * 3. Among matches of the same position and length, the one defined earlier wins.
54
+ * 4. Only specs active in the current state (the top of the state stack, initially `'root'`) are considered.
55
+ * 5. Patterns are matched against the whole input, so `^`, `$`, `\b` and lookbehinds see the text around the current position; a sticky (`y`) `RegExp` matches only at the current position.
56
+ * 6. Empty matches are ignored.
70
57
  *
71
- * Supports quoted fields with escaped double quotes (`""`).
72
- * Carriage returns are normalized.
58
+ * @param decorator
73
59
  *
74
- * @param csv The CSV string to parse.
75
- * @param separator The field delimiter (default: `','`).
60
+ * A function that wraps each matched chunk.
61
+ * It receives the matched text (`chunk`) and optionally the `metadata` associated with the pattern that produced the match.
62
+ * For unmatched text between patterns, `metadata` is `undefined`.
76
63
  *
77
- * @returns A 2D array where each inner array represents a
78
- * row of fields.
79
- */
80
- export declare const csvParse: (csv: string, separator?: string) => string[][];
81
- /**
82
- * Applies Polish-specific typographic corrections to a DOM
83
- * subtree.
84
- *
85
- * This function prevents orphaned conjunctions
86
- * (single-letter words like “a”, “i”, “o”, “u”, “w”, “z”)
87
- * and the em dash (“—”) from appearing at the end of a
88
- * line. It wraps each such character together with the
89
- * whitespace that follows it in a `white-space:nowrap`
90
- * span, removing the only line-break opportunity between it
91
- * and the next word so the two stay glued together. It also
92
- * inserts zero-width spaces after slashes and dots to allow
93
- * line breaks.
94
- *
95
- * @param node The root DOM node to process. All descendant
96
- * text nodes are corrected recursively, except those
97
- * inside `IFRAME`, `NOSCRIPT`, `PRE`, `SCRIPT`, `STYLE`,
98
- * or `TEXTAREA` elements.
99
- */
100
- export declare const fixPlTypography: (node: Node) => void;
101
- /**
102
- * Single argument type for the {@link h} and {@link s}
103
- * helpers.
104
- */
105
- export type HArgs1 = Record<PropertyKey, unknown> | null | undefined | Node | string | number | HArgs;
106
- /**
107
- * Tuple argument type for the {@link h} and {@link s}
108
- * helpers.
64
+ * @param specs
65
+ *
66
+ * An array of tuples `[metadata, pattern, options?]` where:
67
+ *
68
+ * - `metadata`: arbitrary data (e.g., a CSS class name) passed to `decorator` when the pattern matches.
69
+ * - `pattern`: a `string` or `RegExp` to match against the input.
70
+ * - `options`: optional {@link TokenizerSpecOptions} (states in which the spec is active and state transitions).
71
+ *
72
+ * @returns
73
+ *
74
+ * A tokenizer function that accepts a code string and returns an array of decorated tokens.
109
75
  */
110
- export type HArgs = [string | Node, ...HArgs1[]];
76
+ export declare const createTokenizer: <M, T>(
77
+ decorator: (chunk: string, metadata?: M) => T,
78
+ ...specs: TokenizerSpec<M>[]
79
+ ) => (code: string) => T[]
80
+ /** Single argument type for the {@link h} and {@link s} helpers. */
81
+ export type HArgs1 = Record<PropertyKey, unknown> | null | undefined | Node | string | number | HArgs
82
+ /** Tuple argument type for the {@link h} and {@link s} helpers. */
83
+ export type HArgs = [string | Node, ...HArgs1[]]
111
84
  /**
112
- * A lightweight _HyperScript_-style helper for creating and
113
- * modifying `HTMLElement`s (see also {@link s}).
114
- *
115
- * @param tagOrNode If a `string`, it is treated as the tag
116
- * name for a new element. If a `Node`, that node is
117
- * modified in place.
118
- * @param args Additional arguments processed as follows:
119
- *
120
- * - `Object`: maps attributes/properties. Keys starting
121
- * with `$` set element properties (without the `$`
122
- * prefix); if the value is a plain object, it is
123
- * shallow-merged into the existing property instead of
124
- * replacing it (useful e.g. for `$style`). Other keys
125
- * set attributes: a key prefixed with `xlink:` sets the
126
- * attribute via `setAttributeNS` in the XLink
127
- * namespace; any other key (without a colon) sets it
128
- * via `setAttribute`. A value of `false` removes the
129
- * attribute.
130
- * - `null`/`undefined`: ignored.
131
- * - `Node`: appended as a child.
132
- * - `string`/`number`: converted to a `Text` node and
133
- * appended.
134
- * - {@link HArgs} array: processed recursively.
135
- *
136
- * @returns The created or modified `HTMLElement`.
85
+ * A lightweight _HyperScript_-style helper for creating and modifying `HTMLElement`s (see also {@link s}).
86
+ *
87
+ * @param tagOrNode
88
+ *
89
+ * If a `string`, it is treated as the tag name for a new element.
90
+ * If a `Node`, that node is modified in place.
91
+ *
92
+ * @param args
93
+ *
94
+ * Additional arguments processed as follows:
95
+ *
96
+ * - `Object`: maps attributes/properties.
97
+ * Keys starting with `$` set element properties (without the `$` prefix); if the value is a plain object, it is shallow-merged into the existing property instead of replacing it (useful e.g. for `$style`).
98
+ * Other keys set attributes: a key prefixed with `xlink:` sets the attribute via `setAttributeNS` in the XLink namespace; any other key (without a colon) sets it via `setAttribute`.
99
+ * A value of `false` removes the attribute.
100
+ * - `null`/`undefined`: ignored.
101
+ * - `Node`: appended as a child.
102
+ * - `string`/`number`: converted to a `Text` node and appended.
103
+ * - {@link HArgs} array: processed recursively.
104
+ *
105
+ * @returns
106
+ *
107
+ * The created or modified `HTMLElement`.
137
108
  */
138
109
  export declare const h: {
139
- <T extends keyof HTMLElementTagNameMap>(tag: T, ...args1: HArgs1[]): HTMLElementTagNameMap[T];
140
- <N extends Node>(node: N, ...args1: HArgs1[]): N;
141
- (tagOrNode: string | Node, ...args1: HArgs1[]): Node;
142
- };
110
+ <T extends keyof HTMLElementTagNameMap>(tag: T, ...args1: HArgs1[]): HTMLElementTagNameMap[T]
111
+ <N extends Node>(node: N, ...args1: HArgs1[]): N
112
+ (tagOrNode: string | Node, ...args1: HArgs1[]): Node
113
+ }
143
114
  /**
144
- * A lightweight _HyperScript_-style helper for creating and
145
- * modifying `SVGElement`s (see also {@link h}).
146
- *
147
- * @param tagOrNode If a `string`, it is treated as the tag
148
- * name for a new element. If a `Node`, that node is
149
- * modified in place.
150
- * @param args Additional arguments processed as follows:
151
- *
152
- * - `Object`: maps attributes/properties. Keys starting
153
- * with `$` set element properties (without the `$`
154
- * prefix); if the value is a plain object, it is
155
- * shallow-merged into the existing property instead of
156
- * replacing it. Other keys set attributes: a key
157
- * prefixed with `xlink:` sets the attribute via
158
- * `setAttributeNS` in the XLink namespace; any other
159
- * key (without a colon) sets it via `setAttribute`. A
160
- * value of `false` removes the attribute.
161
- * - `null`/`undefined`: ignored.
162
- * - `Node`: appended as a child.
163
- * - `string`/`number`: converted to a `Text` node and
164
- * appended.
165
- * - {@link HArgs} array: processed recursively.
166
- *
167
- * @returns The created or modified `SVGElement`.
115
+ * A lightweight _HyperScript_-style helper for creating and modifying `SVGElement`s (see also {@link h}).
116
+ *
117
+ * @param tagOrNode
118
+ *
119
+ * If a `string`, it is treated as the tag name for a new element.
120
+ * If a `Node`, that node is modified in place.
121
+ *
122
+ * @param args
123
+ *
124
+ * Additional arguments processed as follows:
125
+ *
126
+ * - `Object`: maps attributes/properties.
127
+ * Keys starting with `$` set element properties (without the `$` prefix); if the value is a plain object, it is shallow-merged into the existing property instead of replacing it.
128
+ * Other keys set attributes: a key prefixed with `xlink:` sets the attribute via `setAttributeNS` in the XLink namespace; any other key (without a colon) sets it via `setAttribute`.
129
+ * A value of `false` removes the attribute.
130
+ * - `null`/`undefined`: ignored.
131
+ * - `Node`: appended as a child.
132
+ * - `string`/`number`: converted to a `Text` node and appended.
133
+ * - {@link HArgs} array: processed recursively.
134
+ *
135
+ * @returns
136
+ *
137
+ * The created or modified `SVGElement`.
168
138
  */
169
139
  export declare const s: {
170
- <T extends keyof SVGElementTagNameMap>(tag: T, ...args1: HArgs1[]): SVGElementTagNameMap[T];
171
- <N extends Node>(node: N, ...args1: HArgs1[]): N;
172
- (tagOrNode: string | Node, ...args1: HArgs1[]): Node;
173
- };
140
+ <T extends keyof SVGElementTagNameMap>(tag: T, ...args1: HArgs1[]): SVGElementTagNameMap[T]
141
+ <N extends Node>(node: N, ...args1: HArgs1[]): N
142
+ (tagOrNode: string | Node, ...args1: HArgs1[]): Node
143
+ }
174
144
  /**
175
- * Shorthand for creating an SVG element with a `<use>`
176
- * child referencing an icon by ID.
145
+ * Shorthand for creating an SVG element with a `<use>` child referencing an icon by ID.
177
146
  *
178
147
  * Equivalent to:
179
148
  *
180
149
  * ```ts
181
- * s(
182
- * 'svg',
183
- * ['use', { 'xlink:href': '#' + id }],
184
- * ...args
185
- * )
150
+ * s('svg', ['use', { 'xlink:href': '#' + id }], ...args)
186
151
  * ```
187
152
  *
188
- * @param id The ID of the symbol to reference (without the
189
- * `#` prefix).
190
- * @param args Additional arguments passed to the outer
191
- * `<svg>` element.
153
+ * @param id
154
+ *
155
+ * The ID of the symbol to reference (without the `#` prefix).
156
+ *
157
+ * @param args
158
+ *
159
+ * Additional arguments passed to the outer `<svg>` element.
160
+ *
161
+ * @returns
192
162
  *
193
- * @returns An `SVGSVGElement` containing a `<use>` element.
163
+ * An `SVGSVGElement` containing a `<use>` element.
194
164
  */
195
- export declare const svgUse: (id: string, ...args: HArgs1[]) => SVGSVGElement;
165
+ export declare const svgUse: (id: string, ...args: HArgs1[]) => SVGSVGElement
196
166
  /**
197
- * A Monokai-inspired color scheme for use with the {@link c}
198
- * helper and {@link nanolightTs} tokenizer.
167
+ * A Monokai-inspired color scheme for use with the {@link c} helper and {@link nanolightTs} tokenizer.
199
168
  */
200
- export declare const monokai: CNode;
169
+ export declare const monokai: CNode
201
170
  /**
202
- * A TypeScript/JavaScript syntax highlighting tokenizer
203
- * built using {@link createTokenizer}.
171
+ * A TypeScript/JavaScript syntax highlighting tokenizer built using {@link createTokenizer}.
204
172
  *
205
- * @param code The source code string to tokenize.
173
+ * @param code
206
174
  *
207
- * @returns An array of {@link HArgs1} elements suitable for
208
- * rendering with {@link h}.
209
- */
210
- export declare const nanolightTs: (code: string) => HArgs1[];
211
- /**
212
- * A responsive web design helper that generates CSS rules
213
- * for a grid-like layout.
214
- *
215
- * @param root The CSS root object to populate (see
216
- * {@link c}).
217
- * @param selector The CSS selector for the grid item.
218
- * @param cellWidthPx The base cell width in pixels.
219
- * @param cellHeightPx The base cell height in pixels.
220
- * @param specs An array of breakpoint specifications, each
221
- * a tuple of:
222
- *
223
- * - `maxWidth`: maximum number of cells per row (defines
224
- * the viewport breakpoint).
225
- * - `width` (optional, default `1`): number of horizontal
226
- * cells the element spans.
227
- * - `height` (optional, default `1`): number of vertical
228
- * cells the element spans.
175
+ * The source code string to tokenize.
176
+ *
177
+ * @returns
178
+ *
179
+ * An array of {@link HArgs1} elements suitable for rendering with {@link h}.
229
180
  */
230
- export declare const rwd: (root: CNode, selector: string, cellWidthPx: number, cellHeightPx: number, ...specs: [number, number?, number?][]) => void;
181
+ export declare const nanolightTs: (code: string) => HArgs1[]
231
182
  /**
232
- * Generates a UUID v1 (time-based) identifier.
183
+ * A responsive web design helper that generates CSS rules for a grid-like layout.
184
+ *
185
+ * @param root
186
+ *
187
+ * The CSS root object to populate (see {@link c}).
188
+ *
189
+ * @param selector
190
+ *
191
+ * The CSS selector for the grid item.
192
+ *
193
+ * @param cellWidthPx
194
+ *
195
+ * The base cell width in pixels.
196
+ *
197
+ * @param cellHeightPx
198
+ *
199
+ * The base cell height in pixels.
200
+ *
201
+ * @param specs
233
202
  *
234
- * @param date The date to use for the timestamp portion
235
- * (default: current date/time).
236
- * @param node A hexadecimal `string` for the node portion
237
- * (default: random). Must match `/^[0-9a-f]*$/`; it is
238
- * trimmed to the last 12 characters and left-padded with
239
- * zeros if shorter.
203
+ * An array of breakpoint specifications, each a tuple of:
240
204
  *
241
- * @returns A UUID v1 `string` in the standard format
242
- * `xxxxxxxx-xxxx-1xxx-xxxx-xxxxxxxxxxxx`.
205
+ * - `maxWidth`: maximum number of cells per row (defines the viewport breakpoint).
206
+ * - `width` (optional, default `1`): number of horizontal cells the element spans.
207
+ * - `height` (optional, default `1`): number of vertical cells the element spans.
243
208
  */
244
- export declare const uuidV1: (date?: Date, node?: string) => string;
209
+ export declare const rwd: (
210
+ root: CNode,
211
+ selector: string,
212
+ cellWidthPx: number,
213
+ cellHeightPx: number,
214
+ ...specs: [number, number?, number?][]
215
+ ) => void
package/nnn.js CHANGED
@@ -50,51 +50,78 @@ var _c = (node, splitter = DEFAULT_SPLITTER, prefix = "", flatten = false) => {
50
50
  return out.join(flatten ? ";" : "");
51
51
  };
52
52
  var c = (node, splitter = DEFAULT_SPLITTER) => _c(node, splitter);
53
- // src/nnn/createEscape.ts
54
- var createEscape = (escapeFn) => (template, ...values) => String.raw(template, ...values.map(escapeFn));
55
53
  // src/nnn/createTokenizer.ts
56
- var createTokenizer = (decorator, ...specs) => (code) => {
57
- const result = [];
58
- while (code.length > 0) {
59
- let bestMetadata;
60
- let bestIndex = Infinity;
61
- let bestChunk = "";
62
- for (const [metadata, pattern] of specs) {
63
- let index = -1;
64
- let chunk = "";
65
- if (typeof pattern === "string" && pattern.length > 0) {
66
- index = code.indexOf(pattern);
67
- chunk = code.slice(index, index + pattern.length);
68
- }
69
- if (pattern instanceof RegExp) {
70
- const match = code.match(pattern);
71
- index = match?.index ?? -1;
72
- chunk = match?.[0] ?? "";
54
+ var ROOT = "root";
55
+ var createTokenizer = (decorator, ...specs) => {
56
+ const compiled = specs.map(([metadata, pattern, options]) => ({
57
+ metadata,
58
+ pattern: pattern instanceof RegExp ? new RegExp(pattern.source, pattern.sticky ? pattern.flags : pattern.flags.replace("g", "") + "g") : pattern,
59
+ states: [options?.in ?? ROOT].flat(),
60
+ pop: options?.pop ?? false,
61
+ push: options?.push
62
+ }));
63
+ const find = (pattern, code, position) => {
64
+ if (typeof pattern === "string") {
65
+ const index = pattern.length > 0 ? code.indexOf(pattern, position) : -1;
66
+ return [index, pattern];
67
+ }
68
+ pattern.lastIndex = position;
69
+ for (let match = pattern.exec(code);match != null; match = pattern.exec(code)) {
70
+ if (match[0].length > 0) {
71
+ return [match.index, match[0]];
73
72
  }
74
- if (index >= 0 && chunk.length > 0 && (index < bestIndex || index === bestIndex && chunk.length > bestChunk.length)) {
75
- bestMetadata = metadata;
76
- bestIndex = index;
77
- bestChunk = chunk;
73
+ if (pattern.sticky) {
74
+ break;
78
75
  }
76
+ pattern.lastIndex = match.index + 1;
79
77
  }
80
- if (bestMetadata != null) {
81
- if (bestIndex > 0) {
82
- result.push(decorator(code.slice(0, bestIndex)));
78
+ return [-1, ""];
79
+ };
80
+ return (code) => {
81
+ const result = [];
82
+ const stack = [ROOT];
83
+ const cache = compiled.map(() => ({ from: -1, index: -1, chunk: "" }));
84
+ let position = 0;
85
+ while (position < code.length) {
86
+ const state = stack.at(-1);
87
+ let best = -1;
88
+ let bestIndex = Infinity;
89
+ let bestChunk = "";
90
+ compiled.forEach(({ pattern, states }, i) => {
91
+ if (!states.includes(state)) {
92
+ return;
93
+ }
94
+ const cached = cache[i];
95
+ const isValid = cached.from >= 0 && (pattern instanceof RegExp && pattern.sticky ? cached.from === position : cached.from <= position && (cached.index < 0 || cached.index >= position));
96
+ if (!isValid) {
97
+ [cached.index, cached.chunk] = find(pattern, code, position);
98
+ cached.from = position;
99
+ }
100
+ if (cached.index >= 0 && (cached.index < bestIndex || cached.index === bestIndex && cached.chunk.length > bestChunk.length)) {
101
+ best = i;
102
+ bestIndex = cached.index;
103
+ bestChunk = cached.chunk;
104
+ }
105
+ });
106
+ if (best < 0) {
107
+ result.push(decorator(code.slice(position)));
108
+ break;
109
+ }
110
+ const { metadata, pop, push } = compiled[best];
111
+ if (bestIndex > position) {
112
+ result.push(decorator(code.slice(position, bestIndex)));
113
+ }
114
+ result.push(decorator(bestChunk, metadata));
115
+ position = bestIndex + bestChunk.length;
116
+ if (pop && stack.length > 1) {
117
+ stack.pop();
118
+ }
119
+ if (push != null) {
120
+ stack.push(push);
83
121
  }
84
- result.push(decorator(bestChunk, bestMetadata));
85
- code = code.slice(bestIndex + bestChunk.length);
86
- } else {
87
- result.push(decorator(code));
88
- break;
89
122
  }
90
- }
91
- return result;
92
- };
93
- // src/nnn/csvParse.ts
94
- var MAIN_PATTERN = /\n|(?<!")("(?:[^"]|"")*")(?!")/g;
95
- var csvParse = (csv, separator = ",") => {
96
- const linePattern = new RegExp(`${separator}|(?<!")\\s*"((?:[^"]|"")*)"\\s*(?!")`, "g");
97
- return csv.replace(/\r/g, "").replace(/\n+$/, "").replace(MAIN_PATTERN, (_, chunk) => chunk ?? "\r").split("\r").map((line) => line.replace(linePattern, (_, chunk) => chunk == null ? "\r" : chunk.replace(/""/g, '"')).split("\r"));
123
+ return result;
124
+ };
98
125
  };
99
126
  // src/nnn/h.ts
100
127
  var XLINK_NS = "http://www.w3.org/1999/xlink";
@@ -153,45 +180,6 @@ var _h = (createElement, tagOrNode, ...args) => {
153
180
  var h = _h.bind(null, (tag) => document.createElement(tag));
154
181
  var s = _h.bind(null, (tag) => document.createElementNS("http://www.w3.org/2000/svg", tag));
155
182
  var svgUse = (id, ...args) => s("svg", ["use", { "xlink:href": "#" + id }], ...args);
156
-
157
- // src/nnn/fixPlTypography.ts
158
- var TAGS_TO_SKIP = [
159
- "IFRAME",
160
- "NOSCRIPT",
161
- "PRE",
162
- "SCRIPT",
163
- "STYLE",
164
- "TEXTAREA"
165
- ];
166
- var fixPlTypography = (node) => {
167
- const queue = [node];
168
- while (queue.length > 0) {
169
- const node0 = queue.shift();
170
- if (node0 instanceof Element) {
171
- node0.childNodes.forEach((childNode) => {
172
- if (childNode instanceof Text) {
173
- queue.push(childNode);
174
- } else if (childNode instanceof Element && !TAGS_TO_SKIP.includes(childNode.tagName)) {
175
- queue.push(childNode);
176
- }
177
- });
178
- } else if (node0 instanceof Text) {
179
- const nodeValue = node0.nodeValue?.trim?.();
180
- if (nodeValue != null) {
181
- let previousNode = node0;
182
- nodeValue.split(/(\s|\(|„)([aiouwz—]\s)/gi).forEach((chunk, i) => {
183
- i %= 3;
184
- const currentNode = i === 2 ? h("span", { style: "white-space:nowrap" }, chunk) : document.createTextNode(i === 1 ? chunk : chunk.replace(/(\/(?=[^/\s])|\.(?=[^\s]))/g, "$1​"));
185
- if (node0.parentNode != null) {
186
- node0.parentNode.insertBefore(currentNode, previousNode.nextSibling);
187
- }
188
- previousNode = currentNode;
189
- });
190
- node0.parentNode?.removeChild(node0);
191
- }
192
- }
193
- }
194
- };
195
183
  // src/nnn/monokai.ts
196
184
  var monokai = {
197
185
  ":root$$monokai": {
@@ -270,6 +258,14 @@ var monokai = {
270
258
  string: "#ffd866"
271
259
  }
272
260
  }
261
+ },
262
+ "@media print$$monokai": {
263
+ pre: {
264
+ "background-color": "white"
265
+ },
266
+ ":root": {
267
+ "--bg": "white"
268
+ }
273
269
  }
274
270
  };
275
271
  // src/nnn/nanolightTs.ts
@@ -285,7 +281,12 @@ var NUMBER = "number";
285
281
  var OPERATOR = "operator";
286
282
  var PUNCTUATION = "punctuation";
287
283
  var STRING = "string";
288
- var nanolightTs = /* @__PURE__ */ createTokenizer((chunk, name) => name != null ? ["span", { class: name }, chunk] : chunk, [COMMENT, /\/\*.*?\*\//s], [COMMENT, /(?<!\\)\/\/.*?(?=\n)/], [STRING, /".*?"/], [STRING, /'.*?'/], [STRING, /`.*?`/s], [STRING, /\/[^\s]*[^\\]\/[dgimsuvy]*/], [NUMBER, /0b[01_]+/], [NUMBER, /0o[01234567_]+/], [NUMBER, /0x[\dabcdef_]+/], [NUMBER, /\d[\d_]*(\.[\d_]+)?(e[+-]?[\d_]+)?/], [OPERATOR, "!"], [OPERATOR, "!="], [OPERATOR, "!=="], [OPERATOR, "%"], [OPERATOR, "%="], [OPERATOR, "&&"], [OPERATOR, "&&="], [OPERATOR, "&"], [OPERATOR, "&="], [OPERATOR, "*"], [OPERATOR, "**"], [OPERATOR, "**="], [OPERATOR, "*="], [OPERATOR, "+"], [OPERATOR, "++"], [OPERATOR, "+="], [OPERATOR, "-"], [OPERATOR, "--"], [OPERATOR, "-="], [OPERATOR, "..."], [OPERATOR, "/"], [OPERATOR, "/="], [OPERATOR, ":"], [OPERATOR, "<"], [OPERATOR, "<<"], [OPERATOR, "<<="], [OPERATOR, "<="], [OPERATOR, "="], [OPERATOR, "=="], [OPERATOR, "==="], [OPERATOR, "=>"], [OPERATOR, ">"], [OPERATOR, ">="], [OPERATOR, ">>"], [OPERATOR, ">>="], [OPERATOR, ">>>"], [OPERATOR, ">>>="], [OPERATOR, "?"], [OPERATOR, "?"], [OPERATOR, "??"], [OPERATOR, "??="], [OPERATOR, "^"], [OPERATOR, "^="], [OPERATOR, "|"], [OPERATOR, "|="], [OPERATOR, "||"], [OPERATOR, "||="], [OPERATOR, "~"], [OPERATOR, "~="], [OPERATOR, /(?<=\s):/], [PUNCTUATION, "("], [PUNCTUATION, ")"], [PUNCTUATION, ","], [PUNCTUATION, "."], [PUNCTUATION, ":"], [PUNCTUATION, ";"], [PUNCTUATION, "?."], [PUNCTUATION, "["], [PUNCTUATION, "]"], [PUNCTUATION, "{"], [PUNCTUATION, "}"], [KEYWORD1, "as"], [KEYWORD1, "async"], [KEYWORD1, "await"], [KEYWORD1, "break"], [KEYWORD1, "case"], [KEYWORD1, "catch"], [KEYWORD1, "class"], [KEYWORD1, "const"], [KEYWORD1, "continue"], [KEYWORD1, "debugger"], [KEYWORD1, "default"], [KEYWORD1, "delete"], [KEYWORD1, "do"], [KEYWORD1, "else"], [KEYWORD1, "export"], [KEYWORD1, "extends"], [KEYWORD1, "finally"], [KEYWORD1, "for"], [KEYWORD1, "from"], [KEYWORD1, "function"], [KEYWORD1, "function*"], [KEYWORD1, "goto"], [KEYWORD1, "if"], [KEYWORD1, "import"], [KEYWORD1, "in"], [KEYWORD1, "instanceof"], [KEYWORD1, "is"], [KEYWORD1, "keyof"], [KEYWORD1, "let"], [KEYWORD1, "new"], [KEYWORD1, "of"], [KEYWORD1, "package"], [KEYWORD1, "return"], [KEYWORD1, "super"], [KEYWORD1, "switch"], [KEYWORD1, "this"], [KEYWORD1, "throw"], [KEYWORD1, "try"], [KEYWORD1, "type"], [KEYWORD1, "typeof"], [KEYWORD1, "var"], [KEYWORD1, "void"], [KEYWORD1, "while"], [KEYWORD1, "with"], [KEYWORD1, "yield"], [KEYWORD1, "yield*"], [KEYWORD2, "false"], [KEYWORD2, "Infinity"], [KEYWORD2, "NaN"], [KEYWORD2, "null"], [KEYWORD2, "true"], [KEYWORD2, "undefined"], [KEYWORD3, "any"], [KEYWORD3, "bigint"], [KEYWORD3, "boolean"], [KEYWORD3, "eval"], [KEYWORD3, "number"], [KEYWORD3, "string"], [KEYWORD3, "symbol"], [KEYWORD3, "unknown"], [IDENTIFIER1, /[\p{Lu}_$][\p{Lu}\d_$]*/u], [IDENTIFIER2, /[\p{L}_$][\p{L}\d_$]*(?=[(`])/u], [IDENTIFIER3, /\p{Lu}[\p{L}\d_$]*/u], [IDENTIFIER4, /[\p{L}_$][\p{L}\d_$]*/u]);
284
+ var ROOT2 = "root";
285
+ var TEMPLATE = "template";
286
+ var nanolightTs = /* @__PURE__ */ createTokenizer((chunk, name) => name != null ? ["span", { class: name }, chunk] : chunk, [COMMENT, /\/\*[\s\S]*?(?:\*\/|$)/], [COMMENT, /\/\/.*/], [STRING, /"(?:[^"\\\n]|\\[\s\S])*"?/], [STRING, /'(?:[^'\\\n]|\\[\s\S])*'?/], [STRING, /`(?:[^`\\$]|\\[\s\S]|\$(?!\{))*(?:`|$)/], [STRING, /`(?:[^`\\$]|\\[\s\S]|\$(?!\{))*(?=\$\{)/, { push: TEMPLATE }], [STRING, /(?:[^`\\$]|\\[\s\S]|\$(?!\{))*(?:`|$)/y, { in: TEMPLATE, pop: true }], [STRING, /(?:[^`\\$]|\\[\s\S]|\$(?!\{))+(?=\$\{)/y, { in: TEMPLATE }], [PUNCTUATION, "${", { in: TEMPLATE, push: ROOT2 }], [
287
+ STRING,
288
+ /(?<=(?:^|[!%&(*+,\-:;<=>?[^{|}~]|\b(?:await|case|delete|do|else|in|instanceof|new|of|return|throw|typeof|void|yield))\s*)\/(?![*/])(?:[^\\/[\n]|\\.|\[(?:[^\\\]\n]|\\.)*\]?)+\/[dgimsuvy]*/
289
+ ], [NUMBER, /0b[01_]+/], [NUMBER, /0o[01234567_]+/], [NUMBER, /0x[\dabcdef_]+/], [NUMBER, /\d[\d_]*(\.[\d_]+)?(e[+-]?[\d_]+)?/], [OPERATOR, "!"], [OPERATOR, "!="], [OPERATOR, "!=="], [OPERATOR, "%"], [OPERATOR, "%="], [OPERATOR, "&&"], [OPERATOR, "&&="], [OPERATOR, "&"], [OPERATOR, "&="], [OPERATOR, "*"], [OPERATOR, "**"], [OPERATOR, "**="], [OPERATOR, "*="], [OPERATOR, "+"], [OPERATOR, "++"], [OPERATOR, "+="], [OPERATOR, "-"], [OPERATOR, "--"], [OPERATOR, "-="], [OPERATOR, "..."], [OPERATOR, "/"], [OPERATOR, "/="], [OPERATOR, ":"], [OPERATOR, "<"], [OPERATOR, "<<"], [OPERATOR, "<<="], [OPERATOR, "<="], [OPERATOR, "="], [OPERATOR, "=="], [OPERATOR, "==="], [OPERATOR, "=>"], [OPERATOR, ">"], [OPERATOR, ">="], [OPERATOR, ">>"], [OPERATOR, ">>="], [OPERATOR, ">>>"], [OPERATOR, ">>>="], [OPERATOR, "?"], [OPERATOR, "??"], [OPERATOR, "??="], [OPERATOR, "^"], [OPERATOR, "^="], [OPERATOR, "|"], [OPERATOR, "|="], [OPERATOR, "||"], [OPERATOR, "||="], [OPERATOR, "~"], [OPERATOR, "~="], [OPERATOR, /(?<=\s):/], [PUNCTUATION, "("], [PUNCTUATION, ")"], [PUNCTUATION, ","], [PUNCTUATION, "."], [PUNCTUATION, ":"], [PUNCTUATION, ";"], [PUNCTUATION, "?."], [PUNCTUATION, "["], [PUNCTUATION, "]"], [PUNCTUATION, "{", { push: ROOT2 }], [PUNCTUATION, "}", { pop: true }], [KEYWORD1, "as"], [KEYWORD1, "async"], [KEYWORD1, "await"], [KEYWORD1, "break"], [KEYWORD1, "case"], [KEYWORD1, "catch"], [KEYWORD1, "class"], [KEYWORD1, "const"], [KEYWORD1, "continue"], [KEYWORD1, "debugger"], [KEYWORD1, "default"], [KEYWORD1, "delete"], [KEYWORD1, "do"], [KEYWORD1, "else"], [KEYWORD1, "export"], [KEYWORD1, "extends"], [KEYWORD1, "finally"], [KEYWORD1, "for"], [KEYWORD1, "from"], [KEYWORD1, "function"], [KEYWORD1, "function*"], [KEYWORD1, "goto"], [KEYWORD1, "if"], [KEYWORD1, "import"], [KEYWORD1, "in"], [KEYWORD1, "instanceof"], [KEYWORD1, "is"], [KEYWORD1, "keyof"], [KEYWORD1, "let"], [KEYWORD1, "new"], [KEYWORD1, "of"], [KEYWORD1, "package"], [KEYWORD1, "return"], [KEYWORD1, "super"], [KEYWORD1, "switch"], [KEYWORD1, "this"], [KEYWORD1, "throw"], [KEYWORD1, "try"], [KEYWORD1, "type"], [KEYWORD1, "typeof"], [KEYWORD1, "var"], [KEYWORD1, "void"], [KEYWORD1, "while"], [KEYWORD1, "with"], [KEYWORD1, "yield"], [KEYWORD1, "yield*"], [KEYWORD2, "false"], [KEYWORD2, "Infinity"], [KEYWORD2, "NaN"], [KEYWORD2, "null"], [KEYWORD2, "true"], [KEYWORD2, "undefined"], [KEYWORD3, "any"], [KEYWORD3, "bigint"], [KEYWORD3, "boolean"], [KEYWORD3, "eval"], [KEYWORD3, "number"], [KEYWORD3, "string"], [KEYWORD3, "symbol"], [KEYWORD3, "unknown"], [IDENTIFIER1, /[\p{Lu}_$][\p{Lu}\d_$]*/u], [IDENTIFIER2, /[\p{L}_$][\p{L}\d_$]*(?=[(`])/u], [IDENTIFIER3, /\p{Lu}[\p{L}\d_$]*/u], [IDENTIFIER4, /[\p{L}_$][\p{L}\d_$]*/u]);
289
290
  // src/nnn/rwd.ts
290
291
  var rwd = (root, selector, cellWidthPx, cellHeightPx, ...specs) => {
291
292
  const main = root[selector] ??= {};
@@ -310,25 +311,13 @@ var rwd = (root, selector, cellWidthPx, cellHeightPx, ...specs) => {
310
311
  node.height = `${cellHeightPx * height}px`;
311
312
  }
312
313
  };
313
- // src/nnn/uuidV1.ts
314
- var ZEROS = /* @__PURE__ */ "0".repeat(16);
315
- var counter = 0;
316
- var uuidV1 = (date = new Date, node = Math.random().toString(16).slice(2)) => {
317
- const time = ZEROS + (1e4 * (+date + 12219292800000)).toString(16);
318
- counter = counter + 1 & 16383;
319
- return time.slice(-8).concat("-", time.slice(-12, -8), -1, time.slice(-15, -12), "-", (8 | counter >> 12).toString(16), (ZEROS + (counter & 4095).toString(16)).slice(-3), "-", (ZEROS + node).slice(-12));
320
- };
321
314
  export {
322
315
  c,
323
- createEscape,
324
316
  createTokenizer,
325
- csvParse,
326
- fixPlTypography,
327
317
  h,
328
318
  monokai,
329
319
  nanolightTs,
330
320
  rwd,
331
321
  s,
332
- svgUse,
333
- uuidV1
322
+ svgUse
334
323
  };