@jackens/nnn 2024.7.14 → 2024.8.6
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/nnn.d.ts +16 -33
- package/nnn.js +7 -4
- package/package.json +1 -1
- package/readme.md +29 -40
package/nnn.d.ts
CHANGED
|
@@ -15,14 +15,10 @@ export type CRoot = Partial<Record<PropertyKey, CNode>>;
|
|
|
15
15
|
*
|
|
16
16
|
* The `root` parameter provides a hierarchical description of CSS rules.
|
|
17
17
|
*
|
|
18
|
-
* - Keys of sub-objects whose values are NOT objects are treated as CSS attribute, and values are treated as values of
|
|
19
|
-
*
|
|
20
|
-
* -
|
|
21
|
-
*
|
|
22
|
-
* - In keys specifying CSS attribute, all uppercase letters are replaced by lowercase letters with an additional `-`
|
|
23
|
-
* character preceding them (e.g. `fontFamily` → `font-family`).
|
|
24
|
-
* - Commas in keys that makes a CSS rule cause it to “split” and create separate rules for each part (e.g.
|
|
25
|
-
* `{div:{margin:1,'.a,.b,.c':{margin:2}}}` → `div{margin:1}div.a,div.b,div.c{margin:2}`).
|
|
18
|
+
* - Keys of sub-objects whose values are NOT objects are treated as CSS attribute, and values are treated as values of those CSS attributes; the concatenation of keys of all parent objects is a CSS rule.
|
|
19
|
+
* - All keys ignore the part starting with a splitter (default: `$$`) sign until the end of the key (e.g. `src$$1` → `src`, `@font-face$$1` → `@font-face`).
|
|
20
|
+
* - In keys specifying CSS attribute, all uppercase letters are replaced by lowercase letters with an additional `-` character preceding them (e.g. `fontFamily` → `font-family`).
|
|
21
|
+
* - Commas in keys that makes a CSS rule cause it to “split” and create separate rules for each part (e.g. `{div:{margin:1,'.a,.b,.c':{margin:2}}}` → `div{margin:1}div.a,div.b,div.c{margin:2}`).
|
|
26
22
|
* - Top-level keys that begin with `@` are not concatenated with sub-object keys.
|
|
27
23
|
*/
|
|
28
24
|
export declare const c: (root: CRoot, splitter?: string) => string;
|
|
@@ -70,21 +66,15 @@ export type HArgs1 = Partial<Record<PropertyKey, unknown>> | null | undefined |
|
|
|
70
66
|
export type HArgs = [string | Node, ...HArgs1[]];
|
|
71
67
|
|
|
72
68
|
/**
|
|
73
|
-
* A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying
|
|
74
|
-
* `HTMLElement`s (see also `s`).
|
|
69
|
+
* A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `HTMLElement`s (see also `s`).
|
|
75
70
|
*
|
|
76
71
|
* - The first argument of type `string` specifies the tag of the element to be created.
|
|
77
72
|
* - The first argument of type `Node` specifies the element to be modified.
|
|
78
|
-
* - All other arguments of type `Partial<Record<PropertyKey, unknown>>` are mappings of attributes and properties.
|
|
79
|
-
* Keys starting with `$` specify *properties* (without the leading `$`) to be set on the element being created or
|
|
80
|
-
* modified. (Note that `$` is not a valid attribute name character.) All other keys specify *attributes* to be set by
|
|
81
|
-
* `setAttribute`. An attribute equal to `false` causes the attribute to be removed by `removeAttribute`.
|
|
73
|
+
* - All other arguments of type `Partial<Record<PropertyKey, unknown>>` are mappings of attributes and properties. Keys starting with `$` specify *properties* (without the leading `$`) to be set on the element being created or modified. (Note that `$` is not a valid attribute name character.) All other keys specify *attributes* to be set by `setAttribute`. An attribute equal to `false` causes the attribute to be removed by `removeAttribute`.
|
|
82
74
|
* - All other arguments of type `null` or `undefined` are simply ignored.
|
|
83
75
|
* - All other arguments of type `Node` are appended to the element being created or modified.
|
|
84
|
-
* - All other arguments of type `string`/`number` are converted to `Text` nodes and appended to the element being
|
|
85
|
-
*
|
|
86
|
-
* - All other arguments of type `HArgs` are passed to `h` and the results are appended to the element being created or
|
|
87
|
-
* modified.
|
|
76
|
+
* - All other arguments of type `string`/`number` are converted to `Text` nodes and appended to the element being created or modified.
|
|
77
|
+
* - All other arguments of type `HArgs` are passed to `h` and the results are appended to the element being created or modified.
|
|
88
78
|
*/
|
|
89
79
|
export declare const h: {
|
|
90
80
|
<T extends keyof HTMLElementTagNameMap>(tag: T, ...args1: Partial<Array<HArgs1>>): HTMLElementTagNameMap[T];
|
|
@@ -93,21 +83,15 @@ export declare const h: {
|
|
|
93
83
|
};
|
|
94
84
|
|
|
95
85
|
/**
|
|
96
|
-
* A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying
|
|
97
|
-
* `SVGElement`s (see also `h`).
|
|
86
|
+
* A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `SVGElement`s (see also `h`).
|
|
98
87
|
*
|
|
99
88
|
* - The first argument of type `string` specifies the tag of the element to be created.
|
|
100
89
|
* - The first argument of type `Node` specifies the element to be modified.
|
|
101
|
-
* - All other arguments of type `Partial<Record<PropertyKey, unknown>>` are mappings of attributes and properties.
|
|
102
|
-
* Keys starting with `$` specify *properties* (without the leading `$`) to be set on the element being created or
|
|
103
|
-
* modified. (Note that `$` is not a valid attribute name character.) All other keys specify *attributes* to be set by
|
|
104
|
-
* `setAttributeNS`. An attribute equal to `false` causes the attribute to be removed by `removeAttributeNS`.
|
|
90
|
+
* - All other arguments of type `Partial<Record<PropertyKey, unknown>>` are mappings of attributes and properties. Keys starting with `$` specify *properties* (without the leading `$`) to be set on the element being created or modified. (Note that `$` is not a valid attribute name character.) All other keys specify *attributes* to be set by `setAttributeNS`. An attribute equal to `false` causes the attribute to be removed by `removeAttributeNS`.
|
|
105
91
|
* - All other arguments of type `null` or `undefined` are simply ignored.
|
|
106
92
|
* - All other arguments of type `Node` are appended to the element being created or modified.
|
|
107
|
-
* - All other arguments of type `string`/`number` are converted to `Text` nodes and appended to the element being
|
|
108
|
-
*
|
|
109
|
-
* - All other arguments of type `HArgs` are passed to `s` and the results are appended to the element being created or
|
|
110
|
-
* modified.
|
|
93
|
+
* - All other arguments of type `string`/`number` are converted to `Text` nodes and appended to the element being created or modified.
|
|
94
|
+
* - All other arguments of type `HArgs` are passed to `s` and the results are appended to the element being created or modified.
|
|
111
95
|
*/
|
|
112
96
|
export declare const s: {
|
|
113
97
|
<T extends keyof SVGElementTagNameMap>(tag: T, ...args1: Partial<Array<HArgs1>>): SVGElementTagNameMap[T];
|
|
@@ -168,17 +152,17 @@ export declare const locale: (map: Partial<Record<PropertyKey, Partial<Record<Pr
|
|
|
168
152
|
export declare const nanolight: (pattern: RegExp, highlighters: Partial<Array<(chunk: string, index: number) => HArgs1>>, code: string) => HArgs1[];
|
|
169
153
|
|
|
170
154
|
/**
|
|
171
|
-
* A helper for highlighting JavaScript.
|
|
155
|
+
* A helper for highlighting JavaScript (see also `nanolight`).
|
|
172
156
|
*/
|
|
173
157
|
export declare const nanolightJs: (code: string) => HArgs1[];
|
|
174
158
|
|
|
175
159
|
/**
|
|
176
|
-
* A helper that implements TypeScript’s `Pick` utility type.
|
|
160
|
+
* A helper that implements TypeScript’s `Pick` utility type (see also `omit`).
|
|
177
161
|
*/
|
|
178
162
|
export declare const pick: <T extends Partial<Record<PropertyKey, unknown>>, K extends Array<keyof T>>(obj: Partial<Record<PropertyKey, unknown>>, keys: Partial<Array<unknown>>) => Pick<T, K[number]>;
|
|
179
163
|
|
|
180
164
|
/**
|
|
181
|
-
* A helper that implements TypeScript’s `Omit` utility type.
|
|
165
|
+
* A helper that implements TypeScript’s `Omit` utility type (see also `pick`).
|
|
182
166
|
*/
|
|
183
167
|
export declare const omit: <T extends Partial<Record<PropertyKey, unknown>>, K extends Array<keyof T>>(obj: Partial<Record<PropertyKey, unknown>>, keys: Partial<Array<unknown>>) => Omit<T, K[number]>;
|
|
184
168
|
|
|
@@ -203,8 +187,7 @@ export declare const refsInfo: (...refs: Partial<Array<unknown>>) => Partial<Arr
|
|
|
203
187
|
/**
|
|
204
188
|
* A helper that generates a UUID v1 identifier (with a creation timestamp).
|
|
205
189
|
*
|
|
206
|
-
* - The optional `node` parameter should have the format `/^[0123456789abcdef]+$/`.
|
|
207
|
-
* Its value will be trimmed to last 12 characters and left padded with zeros.
|
|
190
|
+
* - The optional `node` parameter should have the format `/^[0123456789abcdef]+$/`. Its value will be trimmed to last 12 characters and left padded with zeros.
|
|
208
191
|
*/
|
|
209
192
|
export declare const uuid1: ({ date, node }?: {
|
|
210
193
|
date?: Date | undefined;
|
package/nnn.js
CHANGED
|
@@ -184,7 +184,7 @@ var jsOnParse = (handlers, text) => JSON.parse(text, (key, value) => {
|
|
|
184
184
|
}
|
|
185
185
|
const handler = handlers[key];
|
|
186
186
|
const params = value[key];
|
|
187
|
-
if (
|
|
187
|
+
if (handler instanceof Function && is(Array, params)) {
|
|
188
188
|
return handler(...params);
|
|
189
189
|
}
|
|
190
190
|
}
|
|
@@ -244,9 +244,12 @@ var pro = (ref) => new Proxy(ref, {
|
|
|
244
244
|
var refsInfo = (...refs) => {
|
|
245
245
|
const fns = new Set;
|
|
246
246
|
refs.forEach((ref) => {
|
|
247
|
-
|
|
248
|
-
fns.
|
|
249
|
-
|
|
247
|
+
try {
|
|
248
|
+
while (ref instanceof Function && !fns.has(ref) && `${ref}`.match(/function\s+\w+[\s\S]+\[native code\]/)) {
|
|
249
|
+
fns.add(ref);
|
|
250
|
+
ref = Object.getPrototypeOf(ref);
|
|
251
|
+
}
|
|
252
|
+
} catch {
|
|
250
253
|
}
|
|
251
254
|
});
|
|
252
255
|
return Array.from(fns.values()).map((fn) => [
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -2,7 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
Jackens’ JavaScript helpers.
|
|
4
4
|
|
|
5
|
-
<sub>Version: <code class="version">2024.
|
|
5
|
+
<sub>Version: <code class="version">2024.8.6</code></sub>
|
|
6
|
+
|
|
7
|
+
* [Documentation](https://jackens.github.io/nnn/doc/)
|
|
8
|
+
* [Tests](https://jackens.github.io/nnn/test/)
|
|
9
|
+
* [Chessboard Demo](https://jackens.github.io/nnn/chessboard/)
|
|
10
|
+
* [Gantt Chart Demo](https://jackens.github.io/nnn/gantt/)
|
|
11
|
+
* [Responsive Web Design Demo](https://jackens.github.io/nnn/rwd/)
|
|
6
12
|
|
|
7
13
|
## Installation
|
|
8
14
|
|
|
@@ -31,7 +37,7 @@ import { «something» } from './node_modules/@jackens/nnn/nnn.js'
|
|
|
31
37
|
or:
|
|
32
38
|
|
|
33
39
|
```js
|
|
34
|
-
import { «something» } from 'https://unpkg.com/@jackens/nnn@2024.
|
|
40
|
+
import { «something» } from 'https://unpkg.com/@jackens/nnn@2024.8.6/nnn.js'
|
|
35
41
|
```
|
|
36
42
|
|
|
37
43
|
## Exports
|
|
@@ -46,19 +52,19 @@ import { «something» } from 'https://unpkg.com/@jackens/nnn@2024.7.14/nnn.js'
|
|
|
46
52
|
- `escape`: A generic helper for escaping `values` by given `escapeMap` (in *TemplateStrings* flavor).
|
|
47
53
|
- `escapeValues`: A generic helper for escaping `values` by given `escapeMap`.
|
|
48
54
|
- `fixTypography`: A helper that implements typographic corrections specific to Polish typography.
|
|
49
|
-
- `h`: A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying
|
|
55
|
+
- `h`: A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `HTMLElement`s (see also `s`).
|
|
50
56
|
- `has`: A replacement for the `in` operator (not to be confused with the `for-in` loop) that works properly.
|
|
51
57
|
- `is`: A helper that checks if the given argument is of a certain type.
|
|
52
58
|
- `jsOnParse`: `JSON.parse` with “JavaScript turned on”.
|
|
53
59
|
- `locale`: Language translations helper.
|
|
54
60
|
- `nanolight`: A generic helper for syntax highlighting (see also `nanolightJs`).
|
|
55
|
-
- `nanolightJs`: A helper for highlighting JavaScript.
|
|
56
|
-
- `omit`: A helper that implements TypeScript’s `Omit` utility type.
|
|
57
|
-
- `pick`: A helper that implements TypeScript’s `Pick` utility type.
|
|
61
|
+
- `nanolightJs`: A helper for highlighting JavaScript (see also `nanolight`).
|
|
62
|
+
- `omit`: A helper that implements TypeScript’s `Omit` utility type (see also `pick`).
|
|
63
|
+
- `pick`: A helper that implements TypeScript’s `Pick` utility type (see also `omit`).
|
|
58
64
|
- `plUral`: A helper for choosing the correct singular and plural.
|
|
59
65
|
- `pro`: A helper that protects calls to nested properties by a `Proxy` that initializes non-existent values with an empty
|
|
60
66
|
- `refsInfo`: A helper that provides information about the given `refs`.
|
|
61
|
-
- `s`: A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying
|
|
67
|
+
- `s`: A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `SVGElement`s (see also `h`).
|
|
62
68
|
- `svgUse`: A convenient shortcut for `s('svg', ['use', { 'xlink:href': '#' + id }], ...args)`.
|
|
63
69
|
- `uuid1`: A helper that generates a UUID v1 identifier (with a creation timestamp).
|
|
64
70
|
|
|
@@ -114,14 +120,10 @@ A simple JS-to-CSS (aka CSS-in-JS) helper.
|
|
|
114
120
|
|
|
115
121
|
The `root` parameter provides a hierarchical description of CSS rules.
|
|
116
122
|
|
|
117
|
-
- Keys of sub-objects whose values are NOT objects are treated as CSS attribute, and values are treated as values of
|
|
118
|
-
|
|
119
|
-
-
|
|
120
|
-
|
|
121
|
-
- In keys specifying CSS attribute, all uppercase letters are replaced by lowercase letters with an additional `-`
|
|
122
|
-
character preceding them (e.g. `fontFamily` → `font-family`).
|
|
123
|
-
- Commas in keys that makes a CSS rule cause it to “split” and create separate rules for each part (e.g.
|
|
124
|
-
`{div:{margin:1,'.a,.b,.c':{margin:2}}}` → `div{margin:1}div.a,div.b,div.c{margin:2}`).
|
|
123
|
+
- Keys of sub-objects whose values are NOT objects are treated as CSS attribute, and values are treated as values of those CSS attributes; the concatenation of keys of all parent objects is a CSS rule.
|
|
124
|
+
- All keys ignore the part starting with a splitter (default: `$$`) sign until the end of the key (e.g. `src$$1` → `src`, `@font-face$$1` → `@font-face`).
|
|
125
|
+
- In keys specifying CSS attribute, all uppercase letters are replaced by lowercase letters with an additional `-` character preceding them (e.g. `fontFamily` → `font-family`).
|
|
126
|
+
- Commas in keys that makes a CSS rule cause it to “split” and create separate rules for each part (e.g. `{div:{margin:1,'.a,.b,.c':{margin:2}}}` → `div{margin:1}div.a,div.b,div.c{margin:2}`).
|
|
125
127
|
- Top-level keys that begin with `@` are not concatenated with sub-object keys.
|
|
126
128
|
|
|
127
129
|
#### Usage Examples
|
|
@@ -436,21 +438,15 @@ const h: {
|
|
|
436
438
|
};
|
|
437
439
|
```
|
|
438
440
|
|
|
439
|
-
A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying
|
|
440
|
-
`HTMLElement`s (see also `s`).
|
|
441
|
+
A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `HTMLElement`s (see also `s`).
|
|
441
442
|
|
|
442
443
|
- The first argument of type `string` specifies the tag of the element to be created.
|
|
443
444
|
- The first argument of type `Node` specifies the element to be modified.
|
|
444
|
-
- All other arguments of type `Partial<Record<PropertyKey, unknown>>` are mappings of attributes and properties.
|
|
445
|
-
Keys starting with `$` specify *properties* (without the leading `$`) to be set on the element being created or
|
|
446
|
-
modified. (Note that `$` is not a valid attribute name character.) All other keys specify *attributes* to be set by
|
|
447
|
-
`setAttribute`. An attribute equal to `false` causes the attribute to be removed by `removeAttribute`.
|
|
445
|
+
- All other arguments of type `Partial<Record<PropertyKey, unknown>>` are mappings of attributes and properties. Keys starting with `$` specify *properties* (without the leading `$`) to be set on the element being created or modified. (Note that `$` is not a valid attribute name character.) All other keys specify *attributes* to be set by `setAttribute`. An attribute equal to `false` causes the attribute to be removed by `removeAttribute`.
|
|
448
446
|
- All other arguments of type `null` or `undefined` are simply ignored.
|
|
449
447
|
- All other arguments of type `Node` are appended to the element being created or modified.
|
|
450
|
-
- All other arguments of type `string`/`number` are converted to `Text` nodes and appended to the element being
|
|
451
|
-
|
|
452
|
-
- All other arguments of type `HArgs` are passed to `h` and the results are appended to the element being created or
|
|
453
|
-
modified.
|
|
448
|
+
- All other arguments of type `string`/`number` are converted to `Text` nodes and appended to the element being created or modified.
|
|
449
|
+
- All other arguments of type `HArgs` are passed to `h` and the results are appended to the element being created or modified.
|
|
454
450
|
|
|
455
451
|
#### Usage Examples
|
|
456
452
|
|
|
@@ -748,7 +744,7 @@ A generic helper for syntax highlighting (see also `nanolightJs`).
|
|
|
748
744
|
const nanolightJs: (code: string) => HArgs1[];
|
|
749
745
|
```
|
|
750
746
|
|
|
751
|
-
A helper for highlighting JavaScript.
|
|
747
|
+
A helper for highlighting JavaScript (see also `nanolight`).
|
|
752
748
|
|
|
753
749
|
#### Usage Examples
|
|
754
750
|
|
|
@@ -772,7 +768,7 @@ expect(nanolightJs(codeJs)).to.deep.equal([
|
|
|
772
768
|
const omit: <T extends Partial<Record<PropertyKey, unknown>>, K extends Array<keyof T>>(obj: Partial<Record<PropertyKey, unknown>>, keys: Partial<Array<unknown>>) => Omit<T, K[number]>;
|
|
773
769
|
```
|
|
774
770
|
|
|
775
|
-
A helper that implements TypeScript’s `Omit` utility type.
|
|
771
|
+
A helper that implements TypeScript’s `Omit` utility type (see also `pick`).
|
|
776
772
|
|
|
777
773
|
#### Usage Examples
|
|
778
774
|
|
|
@@ -788,7 +784,7 @@ expect(omit(obj, ['c'])).to.deep.equal({ a: 42, b: '42' })
|
|
|
788
784
|
const pick: <T extends Partial<Record<PropertyKey, unknown>>, K extends Array<keyof T>>(obj: Partial<Record<PropertyKey, unknown>>, keys: Partial<Array<unknown>>) => Pick<T, K[number]>;
|
|
789
785
|
```
|
|
790
786
|
|
|
791
|
-
A helper that implements TypeScript’s `Pick` utility type.
|
|
787
|
+
A helper that implements TypeScript’s `Pick` utility type (see also `omit`).
|
|
792
788
|
|
|
793
789
|
#### Usage Examples
|
|
794
790
|
|
|
@@ -916,21 +912,15 @@ const s: {
|
|
|
916
912
|
};
|
|
917
913
|
```
|
|
918
914
|
|
|
919
|
-
A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying
|
|
920
|
-
`SVGElement`s (see also `h`).
|
|
915
|
+
A lightweight [HyperScript](https://github.com/hyperhype/hyperscript)-style helper for creating and modifying `SVGElement`s (see also `h`).
|
|
921
916
|
|
|
922
917
|
- The first argument of type `string` specifies the tag of the element to be created.
|
|
923
918
|
- The first argument of type `Node` specifies the element to be modified.
|
|
924
|
-
- All other arguments of type `Partial<Record<PropertyKey, unknown>>` are mappings of attributes and properties.
|
|
925
|
-
Keys starting with `$` specify *properties* (without the leading `$`) to be set on the element being created or
|
|
926
|
-
modified. (Note that `$` is not a valid attribute name character.) All other keys specify *attributes* to be set by
|
|
927
|
-
`setAttributeNS`. An attribute equal to `false` causes the attribute to be removed by `removeAttributeNS`.
|
|
919
|
+
- All other arguments of type `Partial<Record<PropertyKey, unknown>>` are mappings of attributes and properties. Keys starting with `$` specify *properties* (without the leading `$`) to be set on the element being created or modified. (Note that `$` is not a valid attribute name character.) All other keys specify *attributes* to be set by `setAttributeNS`. An attribute equal to `false` causes the attribute to be removed by `removeAttributeNS`.
|
|
928
920
|
- All other arguments of type `null` or `undefined` are simply ignored.
|
|
929
921
|
- All other arguments of type `Node` are appended to the element being created or modified.
|
|
930
|
-
- All other arguments of type `string`/`number` are converted to `Text` nodes and appended to the element being
|
|
931
|
-
|
|
932
|
-
- All other arguments of type `HArgs` are passed to `s` and the results are appended to the element being created or
|
|
933
|
-
modified.
|
|
922
|
+
- All other arguments of type `string`/`number` are converted to `Text` nodes and appended to the element being created or modified.
|
|
923
|
+
- All other arguments of type `HArgs` are passed to `s` and the results are appended to the element being created or modified.
|
|
934
924
|
|
|
935
925
|
### svgUse
|
|
936
926
|
|
|
@@ -951,8 +941,7 @@ const uuid1: ({ date, node }?: {
|
|
|
951
941
|
|
|
952
942
|
A helper that generates a UUID v1 identifier (with a creation timestamp).
|
|
953
943
|
|
|
954
|
-
- The optional `node` parameter should have the format `/^[0123456789abcdef]+$/`.
|
|
955
|
-
Its value will be trimmed to last 12 characters and left padded with zeros.
|
|
944
|
+
- The optional `node` parameter should have the format `/^[0123456789abcdef]+$/`. Its value will be trimmed to last 12 characters and left padded with zeros.
|
|
956
945
|
|
|
957
946
|
#### Usage Examples
|
|
958
947
|
|