@jackens/nnn 2024.2.12 → 2024.2.15
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/chartable.d.ts +3 -7
- package/chartable.js +24 -111
- package/escape.js +2 -2
- package/h.js +9 -9
- package/has.js +2 -2
- package/is.js +1 -1
- package/jsOnParse.js +1 -1
- package/nanolightJs.js +1 -1
- package/package.json +1 -1
- package/pick.js +6 -32
- package/plUral.js +2 -2
- package/pro.js +1 -1
- package/readme.md +4 -8
- package/refsInfo.js +1 -1
- package/uuid1.js +1 -1
package/chartable.d.ts
CHANGED
|
@@ -7,17 +7,15 @@
|
|
|
7
7
|
* - `gapY`: Y axis spacing
|
|
8
8
|
* - `headerColumn`: flag indicating that `table` has a header column (with X axis labels)
|
|
9
9
|
* - `id`: chart id
|
|
10
|
-
* - `left`: left padding
|
|
10
|
+
* - `left`: left padding
|
|
11
11
|
* - `maxY`: number of Y axis lines
|
|
12
12
|
* - `reverse`: flag to reverse all data series
|
|
13
13
|
* - `right`: right padding (for data series labels)
|
|
14
14
|
* - `rotate`: flag to rotate X axis labels
|
|
15
|
-
* - `singleScale`: flag to force single scale
|
|
16
15
|
* - `table`: `HTMLTableElement` to extract data, data series labels and X axis labels
|
|
17
|
-
* - `
|
|
18
|
-
* - `top`: top padding (for the title)
|
|
16
|
+
* - `top`: top padding
|
|
19
17
|
*/
|
|
20
|
-
export function chartable({ bottom, gapX, gapY, headerColumn, id, left, maxY, reverse, right, rotate,
|
|
18
|
+
export function chartable({ bottom, gapX, gapY, headerColumn, id, left, maxY, reverse, right, rotate, table, top }: {
|
|
21
19
|
bottom?: number;
|
|
22
20
|
gapX?: number;
|
|
23
21
|
gapY?: number;
|
|
@@ -28,9 +26,7 @@ export function chartable({ bottom, gapX, gapY, headerColumn, id, left, maxY, re
|
|
|
28
26
|
reverse?: boolean;
|
|
29
27
|
right?: number;
|
|
30
28
|
rotate?: boolean;
|
|
31
|
-
singleScale?: boolean;
|
|
32
29
|
table: HTMLTableElement;
|
|
33
|
-
title?: string;
|
|
34
30
|
top?: number;
|
|
35
31
|
}): SVGSVGElement;
|
|
36
32
|
|
package/chartable.js
CHANGED
|
@@ -11,15 +11,13 @@ const COLORS = ['#e22', '#e73', '#fc3', '#ad4', '#4d9', '#3be', '#45d', '#c3e']
|
|
|
11
11
|
* - `gapY`: Y axis spacing
|
|
12
12
|
* - `headerColumn`: flag indicating that `table` has a header column (with X axis labels)
|
|
13
13
|
* - `id`: chart id
|
|
14
|
-
* - `left`: left padding
|
|
14
|
+
* - `left`: left padding
|
|
15
15
|
* - `maxY`: number of Y axis lines
|
|
16
16
|
* - `reverse`: flag to reverse all data series
|
|
17
17
|
* - `right`: right padding (for data series labels)
|
|
18
18
|
* - `rotate`: flag to rotate X axis labels
|
|
19
|
-
* - `singleScale`: flag to force single scale
|
|
20
19
|
* - `table`: `HTMLTableElement` to extract data, data series labels and X axis labels
|
|
21
|
-
* - `
|
|
22
|
-
* - `top`: top padding (for the title)
|
|
20
|
+
* - `top`: top padding
|
|
23
21
|
*
|
|
24
22
|
* @param {{
|
|
25
23
|
* bottom?: number;
|
|
@@ -32,9 +30,7 @@ const COLORS = ['#e22', '#e73', '#fc3', '#ad4', '#4d9', '#3be', '#45d', '#c3e']
|
|
|
32
30
|
* reverse?: boolean;
|
|
33
31
|
* right?: number;
|
|
34
32
|
* rotate?: boolean;
|
|
35
|
-
* singleScale?: boolean;
|
|
36
33
|
* table: HTMLTableElement;
|
|
37
|
-
* title?: string;
|
|
38
34
|
* top?: number;
|
|
39
35
|
* }} options
|
|
40
36
|
*/
|
|
@@ -44,22 +40,20 @@ export const chartable = ({
|
|
|
44
40
|
gapY = 30,
|
|
45
41
|
headerColumn = false,
|
|
46
42
|
id,
|
|
47
|
-
left =
|
|
43
|
+
left = 15,
|
|
48
44
|
maxY = 10,
|
|
49
45
|
reverse = false,
|
|
50
46
|
right = 200,
|
|
51
47
|
rotate = false,
|
|
52
|
-
singleScale = false,
|
|
53
48
|
table,
|
|
54
|
-
|
|
55
|
-
top = 70
|
|
49
|
+
top = 15
|
|
56
50
|
}) => {
|
|
57
51
|
const /** @type {number[][]} */ zxY = []
|
|
58
52
|
const /** @type {string[]} */ xLabels = []
|
|
59
53
|
const /** @type {string[]} */ zLabels = []
|
|
60
54
|
|
|
61
55
|
table.querySelectorAll('tr').forEach((row, r) =>
|
|
62
|
-
// @ts-
|
|
56
|
+
// @ts-expect-error
|
|
63
57
|
row.querySelectorAll('td,th').forEach((/** @type {HTMLTableCellElement} */ col, c) => {
|
|
64
58
|
const x = r - 1
|
|
65
59
|
const z = c - +headerColumn
|
|
@@ -80,51 +74,6 @@ export const chartable = ({
|
|
|
80
74
|
zxY.forEach(xY => xY.reverse())
|
|
81
75
|
}
|
|
82
76
|
|
|
83
|
-
let bestScales = [Infinity, -Infinity, Infinity, -Infinity, Infinity]
|
|
84
|
-
|
|
85
|
-
const ranges = zxY.map(xY => {
|
|
86
|
-
xY = xY.filter(y => !isNaN(y))
|
|
87
|
-
return [Math.min(...xY), Math.max(...xY)]
|
|
88
|
-
})
|
|
89
|
-
|
|
90
|
-
if (singleScale) {
|
|
91
|
-
bestScales = ranges.reduce(
|
|
92
|
-
([totalMin, totalMax], [min, max]) => [Math.min(totalMin, min), Math.max(totalMax, max)],
|
|
93
|
-
bestScales
|
|
94
|
-
)
|
|
95
|
-
} else {
|
|
96
|
-
ranges.forEach(([min1, max0]) => ranges.forEach(([min0, max1]) => {
|
|
97
|
-
if (min0 >= min1 && max1 >= max0) {
|
|
98
|
-
let min2 = Infinity
|
|
99
|
-
let max2 = -Infinity
|
|
100
|
-
|
|
101
|
-
ranges.forEach(([min, max]) => {
|
|
102
|
-
if (min < min1 || max1 < max) {
|
|
103
|
-
if (min2 > min) {
|
|
104
|
-
min2 = min
|
|
105
|
-
}
|
|
106
|
-
if (max2 < max) {
|
|
107
|
-
max2 = max
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
let cost = 0
|
|
113
|
-
|
|
114
|
-
ranges.forEach(([min, max]) => {
|
|
115
|
-
if (min < max) {
|
|
116
|
-
cost += 1 - (max - min) / (min1 <= min && max <= max1 ? max1 - min1 : max2 - min2)
|
|
117
|
-
}
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
if (bestScales[4] > cost) {
|
|
121
|
-
bestScales = [min1, max1, min2, max2, cost]
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}))
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const [min1, max1, min2, max2] = bestScales
|
|
128
77
|
const maxX = zxY[0].length
|
|
129
78
|
const xi = Array.from({ length: maxX }, (_, x) => x * gapX)
|
|
130
79
|
const yi = Array.from({ length: maxY }, (_, y) => y * gapY)
|
|
@@ -135,42 +84,27 @@ export const chartable = ({
|
|
|
135
84
|
const /** @type {import('./h.js').HArgs1} */ graph = ['g', { transform: `translate(${left} ${top})` },
|
|
136
85
|
...yi.map(y => ['line', { x1: 0, x2: w, y1: y, y2: y, stroke: '#8888' }]),
|
|
137
86
|
...xi.map(x => ['line', { x1: x, x2: x, y1: 0, y2: h, stroke: '#8888' }])]
|
|
138
|
-
const /** @type {import('./h.js').HArgs1} */
|
|
139
|
-
const /** @type {import('./h.js').HArgs1} */
|
|
140
|
-
const /** @type {import('./h.js').HArgs1} */ rColors = ['g', { class: 'chartable-z-colors', transform: 'translate(80 0)' }]
|
|
141
|
-
const /** @type {import('./h.js').HArgs1} */ rLabels = ['g', { class: 'chartable-z-labels', transform: 'translate(95 0)' }]
|
|
142
|
-
const yLabel = (/** @type {number} */ min, /** @type {number} */ max, /** @type {number} */ y) =>
|
|
143
|
-
(min + (max - min) * (maxY - 1 - y) / (maxY - 1)).toFixed(2).replace(/\.?0+$/, '')
|
|
87
|
+
const /** @type {import('./h.js').HArgs1} */ colors = ['g', { transform: `translate(${left + w + 25} ${top + 15})` }]
|
|
88
|
+
const /** @type {import('./h.js').HArgs1} */ labels = ['g', { transform: `translate(${left + w + 40} ${top + 15})` }]
|
|
144
89
|
|
|
145
|
-
zxY.forEach((
|
|
146
|
-
const cls = `chartable-z-${z + 1}`
|
|
90
|
+
zxY.forEach((xY, z) => {
|
|
147
91
|
const fill = COLORS[z % COLORS.length]
|
|
148
|
-
|
|
92
|
+
const min = Math.min(...xY.filter(x => !isNaN(x)))
|
|
93
|
+
const max = Math.max(...xY.filter(x => !isNaN(x)))
|
|
149
94
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
lLabels.push(['text',
|
|
155
|
-
{ x: 0, y: gapY * (lLabels.length - 2), 'text-anchor': 'end', 'alignment-baseline': 'middle' },
|
|
156
|
-
zLabels[z]])
|
|
157
|
-
} else {
|
|
158
|
-
min = min2
|
|
159
|
-
max = max2
|
|
160
|
-
rColors.push(['circle', { class: cls, cx: 0, cy: gapY * (rColors.length - 2), r: 5, fill }])
|
|
161
|
-
rLabels.push(['text',
|
|
162
|
-
{ x: 0, y: gapY * (rLabels.length - 2), 'text-anchor': 'start', 'alignment-baseline': 'middle' },
|
|
163
|
-
zLabels[z]])
|
|
164
|
-
}
|
|
95
|
+
colors.push(['circle', { cx: 0, cy: gapY * (colors.length - 2), r: 5, fill }])
|
|
96
|
+
labels.push(['text',
|
|
97
|
+
{ x: 0, y: gapY * (labels.length - 2), 'text-anchor': 'start', 'alignment-baseline': 'middle' },
|
|
98
|
+
zLabels[z]])
|
|
165
99
|
|
|
166
|
-
const y =
|
|
100
|
+
const y = xY.map(x => isNaN(x) ? x : h * (max - x) / (max - min))
|
|
167
101
|
|
|
168
102
|
xi.forEach((x, i) => {
|
|
169
103
|
if (!isNaN(y[i])) {
|
|
170
|
-
graph.push(['circle', {
|
|
104
|
+
graph.push(['g', ['circle', { cx: x, cy: y[i], r: 5, fill }, ['title', `${zLabels[z]}: ${xY[i]}`]]])
|
|
171
105
|
|
|
172
106
|
if (!isNaN(y[i - 1])) {
|
|
173
|
-
graph.push(['line', {
|
|
107
|
+
graph.push(['line', { x1: x, x2: xi[i - 1], y1: y[i], y2: y[i - 1], stroke: fill }])
|
|
174
108
|
}
|
|
175
109
|
}
|
|
176
110
|
})
|
|
@@ -181,35 +115,14 @@ export const chartable = ({
|
|
|
181
115
|
width: `${svgW}px`,
|
|
182
116
|
height: `${svgH}px`,
|
|
183
117
|
class: 'chartable'
|
|
184
|
-
}, id != null ? { id } : null,
|
|
185
|
-
|
|
186
|
-
{ class: 'chartable-title', x: svgW / 2, y: top / 2, 'text-anchor': 'middle', 'alignment-baseline': 'middle' },
|
|
187
|
-
title]
|
|
188
|
-
: null,
|
|
189
|
-
graph,
|
|
190
|
-
min1 < Infinity
|
|
191
|
-
? ['g', { class: 'chartable-left', transform: `translate(${left} ${top})` },
|
|
192
|
-
['g', { class: 'chartable-y-labels', transform: 'translate(-15 0)' },
|
|
193
|
-
...yi.map((y, i) => ['text',
|
|
194
|
-
{ x: 0, y, 'text-anchor': 'end', 'alignment-baseline': 'middle' },
|
|
195
|
-
yLabel(min1, max1, i)])],
|
|
196
|
-
lColors, lLabels]
|
|
197
|
-
: null,
|
|
198
|
-
min2 < Infinity
|
|
199
|
-
? ['g', { class: 'chartable-right', transform: `translate(${left + w} ${top})` },
|
|
200
|
-
['g', { class: 'chartable-y-labels', transform: 'translate(15 0)' },
|
|
201
|
-
...yi.map((y, i) => ['text',
|
|
202
|
-
{ x: 0, y, 'text-anchor': 'start', 'alignment-baseline': 'middle' },
|
|
203
|
-
yLabel(min2, max2, i)])],
|
|
204
|
-
rColors, rLabels]
|
|
205
|
-
: null,
|
|
118
|
+
}, id != null ? { id } : null,
|
|
119
|
+
graph, colors, labels,
|
|
206
120
|
xLabels.length > 0
|
|
207
|
-
? ['g', { transform: `translate(${left} ${top + h})` },
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
xLabels[i]])]]
|
|
121
|
+
? ['g', { transform: `translate(${left} ${top + h + 15})` },
|
|
122
|
+
...xi.slice(0).map((x, i) => ['text', rotate
|
|
123
|
+
? { x: 0, y: -x, 'text-anchor': 'start', 'alignment-baseline': 'hanging', transform: 'rotate(90)' }
|
|
124
|
+
: { x, y: 0, 'text-anchor': 'middle', 'alignment-baseline': 'hanging' },
|
|
125
|
+
xLabels[i]])]
|
|
213
126
|
: null
|
|
214
127
|
)
|
|
215
128
|
}
|
package/escape.js
CHANGED
|
@@ -23,7 +23,7 @@ export const escape = (
|
|
|
23
23
|
|
|
24
24
|
export const tests = {
|
|
25
25
|
escape: (/** @type {import('bun:test').Expect} */ expect) => {
|
|
26
|
-
// @ts-
|
|
26
|
+
// @ts-expect-error
|
|
27
27
|
const /** @type {EscapeMap} */ escapeMap = new Map([
|
|
28
28
|
[undefined, () => 'NULL'],
|
|
29
29
|
[Array, (/** @type {any[]} */ values) => escapeValues(escapeMap, values).join(', ')],
|
|
@@ -33,7 +33,7 @@ export const tests = {
|
|
|
33
33
|
[String, (/** @type {string} */ value) => `'${value.replace(/'/g, "''")}'`]
|
|
34
34
|
])
|
|
35
35
|
|
|
36
|
-
// @ts-
|
|
36
|
+
// @ts-expect-error
|
|
37
37
|
const sql = escape.bind(null, escapeMap)
|
|
38
38
|
|
|
39
39
|
const actual = sql`
|
package/h.js
CHANGED
|
@@ -44,10 +44,10 @@ const _h = (/** @type {string?=} */ namespaceURI) => {
|
|
|
44
44
|
if (arg instanceof Node) {
|
|
45
45
|
child = arg
|
|
46
46
|
} else if (is(String, arg) || is(Number, arg)) {
|
|
47
|
-
// @ts-
|
|
47
|
+
// @ts-expect-error
|
|
48
48
|
child = new Text(arg)
|
|
49
49
|
} else if (is(Array, arg)) {
|
|
50
|
-
// @ts-
|
|
50
|
+
// @ts-expect-error
|
|
51
51
|
child = h(...arg)
|
|
52
52
|
} else if (arg != null) {
|
|
53
53
|
for (const name in arg) {
|
|
@@ -57,19 +57,19 @@ const _h = (/** @type {string?=} */ namespaceURI) => {
|
|
|
57
57
|
const name1 = name.slice(1)
|
|
58
58
|
|
|
59
59
|
if (is(Object, value)) {
|
|
60
|
-
// @ts-
|
|
60
|
+
// @ts-expect-error
|
|
61
61
|
node[name1] = node[name1] ?? {}
|
|
62
|
-
// @ts-
|
|
62
|
+
// @ts-expect-error
|
|
63
63
|
Object.assign(node[name1], value)
|
|
64
64
|
} else {
|
|
65
|
-
// @ts-
|
|
65
|
+
// @ts-expect-error
|
|
66
66
|
node[name1] = value
|
|
67
67
|
}
|
|
68
68
|
} else if (node instanceof Element) {
|
|
69
69
|
const indexOfColon = name.indexOf(':')
|
|
70
70
|
|
|
71
71
|
if (indexOfColon >= 0) {
|
|
72
|
-
// @ts-
|
|
72
|
+
// @ts-expect-error
|
|
73
73
|
const /** @type {string=} */ ns = NS[name.slice(0, indexOfColon)]
|
|
74
74
|
|
|
75
75
|
if (ns != null) {
|
|
@@ -197,17 +197,17 @@ export const tests = {
|
|
|
197
197
|
'h: nested properties': (/** @type {import('bun:test').Expect} */ expect) => {
|
|
198
198
|
const div = h('div')
|
|
199
199
|
|
|
200
|
-
// @ts-
|
|
200
|
+
// @ts-expect-error
|
|
201
201
|
expect(div.key).toBeUndefined()
|
|
202
202
|
|
|
203
203
|
h(div, { $key: { one: 1 } })
|
|
204
204
|
|
|
205
|
-
// @ts-
|
|
205
|
+
// @ts-expect-error
|
|
206
206
|
expect(div.key).toEqual({ one: 1 })
|
|
207
207
|
|
|
208
208
|
h(div, { $key: { two: 2 } })
|
|
209
209
|
|
|
210
|
-
// @ts-
|
|
210
|
+
// @ts-expect-error
|
|
211
211
|
expect(div.key).toEqual({ one: 1, two: 2 })
|
|
212
212
|
}
|
|
213
213
|
}
|
package/has.js
CHANGED
|
@@ -16,7 +16,7 @@ export const tests = {
|
|
|
16
16
|
expect('null' in obj).toBe(true)
|
|
17
17
|
expect(has('null', obj)).toBe(true)
|
|
18
18
|
|
|
19
|
-
// @ts-
|
|
19
|
+
// @ts-expect-error
|
|
20
20
|
expect(null in obj).toBe(true)
|
|
21
21
|
expect(has(null, obj)).toBe(false)
|
|
22
22
|
|
|
@@ -28,7 +28,7 @@ export const tests = {
|
|
|
28
28
|
let typeError
|
|
29
29
|
|
|
30
30
|
try {
|
|
31
|
-
// @ts-
|
|
31
|
+
// @ts-expect-error
|
|
32
32
|
'key' in null
|
|
33
33
|
} catch (error) {
|
|
34
34
|
typeError = error
|
package/is.js
CHANGED
package/jsOnParse.js
CHANGED
package/nanolightJs.js
CHANGED
|
@@ -4,7 +4,7 @@ import { nanolight } from './nanolight.js'
|
|
|
4
4
|
/**
|
|
5
5
|
* A helper for highlighting JavaScript.
|
|
6
6
|
*/
|
|
7
|
-
// @ts-
|
|
7
|
+
// @ts-expect-error
|
|
8
8
|
export const nanolightJs = nanolight.bind(0,
|
|
9
9
|
/('.*?'|".*?"|`[\s\S]*?`)|(\/\/.*?\n|\/\*[\s\S]*?\*\/)|(any|bigint|break|boolean|case|catch|const|continue|debugger|default|delete|do|else|eval|export|extends|false|finally|for|from|function|goto|if|import|in|instanceof|is|keyof|let|NaN|new|number|null|package|return|string|super|switch|symbol|this|throw|true|try|type|typeof|undefined|unknown|var|void|while|with|yield)(?!\w)|([<>=.?:&|!^~*/%+-])|(0x[\dabcdef]+|0o[01234567]+|0b[01]+|\d+(?:\.[\d_]+)?(?:e[+-]?[\d_]+)?)|([$\w]+)(?=\()|([$\wąćęłńóśżźĄĆĘŁŃÓŚŻŹ]+)/,
|
|
10
10
|
[
|
package/package.json
CHANGED
package/pick.js
CHANGED
|
@@ -2,45 +2,19 @@
|
|
|
2
2
|
* A helper that implements TypeScript’s `Pick` utility type.
|
|
3
3
|
*
|
|
4
4
|
* @type {<T extends Partial<Record<PropertyKey, any>>, K extends (keyof T)[]>(obj: T, keys: K) => Pick<T, K[number]>}
|
|
5
|
-
* @template {Partial<Record<PropertyKey, any>>} T
|
|
6
|
-
* @template {keyof T} K
|
|
7
5
|
*/
|
|
8
|
-
export const pick = (/** @type {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
for (const key in obj) {
|
|
12
|
-
// @ts-ignore
|
|
13
|
-
if (keys.includes(key)) {
|
|
14
|
-
// @ts-ignore
|
|
15
|
-
result[key] = obj[key]
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// @ts-ignore
|
|
20
|
-
return result
|
|
21
|
-
}
|
|
6
|
+
export const pick = (/** @type {Partial<Record<PropertyKey, any>>} */ obj, /** @type {any[]} */ keys) =>
|
|
7
|
+
// @ts-expect-error
|
|
8
|
+
Object.fromEntries(Object.entries(obj).filter(([key]) => keys.includes(key)))
|
|
22
9
|
|
|
23
10
|
/**
|
|
24
11
|
* A helper that implements TypeScript’s `Omit` utility type.
|
|
25
12
|
*
|
|
26
13
|
* @type {<T extends Partial<Record<PropertyKey, any>>, K extends (keyof T)[]>(obj: T, keys: K) => Omit<T, K[number]>}
|
|
27
|
-
* @template {Partial<Record<PropertyKey, any>>} T
|
|
28
|
-
* @template {keyof T} K
|
|
29
14
|
*/
|
|
30
|
-
export const omit = (/** @type {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
for (const key in obj) {
|
|
34
|
-
// @ts-ignore
|
|
35
|
-
if (!keys.includes(key)) {
|
|
36
|
-
// @ts-ignore
|
|
37
|
-
result[key] = obj[key]
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
// @ts-ignore
|
|
42
|
-
return result
|
|
43
|
-
}
|
|
15
|
+
export const omit = (/** @type {Partial<Record<PropertyKey, any>>} */ obj, /** @type {any[]} */ keys) =>
|
|
16
|
+
// @ts-expect-error
|
|
17
|
+
Object.fromEntries(Object.entries(obj).filter(([key]) => !keys.includes(key)))
|
|
44
18
|
|
|
45
19
|
export const tests = {
|
|
46
20
|
pick: (/** @type {import('bun:test').Expect} */ expect) => {
|
package/plUral.js
CHANGED
|
@@ -20,7 +20,7 @@ export const plUral = (
|
|
|
20
20
|
|
|
21
21
|
export const tests = {
|
|
22
22
|
plUral: (/** @type {import('bun:test').Expect} */ expect) => {
|
|
23
|
-
// @ts-
|
|
23
|
+
// @ts-expect-error
|
|
24
24
|
const auto = plUral.bind(null, 'auto', 'auta', 'aut')
|
|
25
25
|
|
|
26
26
|
expect(auto(0)).toEqual('aut')
|
|
@@ -28,7 +28,7 @@ export const tests = {
|
|
|
28
28
|
expect(auto(17)).toEqual('aut')
|
|
29
29
|
expect(auto(42)).toEqual('auta')
|
|
30
30
|
|
|
31
|
-
// @ts-
|
|
31
|
+
// @ts-expect-error
|
|
32
32
|
const car = plUral.bind(null, 'car', 'cars', 'cars')
|
|
33
33
|
|
|
34
34
|
expect(car(0)).toEqual('cars')
|
package/pro.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* A helper that protects calls to nested properties by a `Proxy` that initializes non-existent values with an empty object.
|
|
3
3
|
*/
|
|
4
|
-
// @ts-
|
|
4
|
+
// @ts-expect-error
|
|
5
5
|
export const pro = (/** @type {any} */ ref) => new Proxy(ref, {
|
|
6
6
|
get (target, key) {
|
|
7
7
|
return pro(target[key] = target[key] ?? {})
|
package/readme.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Jackens’ JavaScript helpers.
|
|
4
4
|
|
|
5
|
-
<sub>Version: <code class="version">2024.2.
|
|
5
|
+
<sub>Version: <code class="version">2024.2.15</code></sub>
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
@@ -103,7 +103,7 @@ The type of arguments of the `jcss` helper.
|
|
|
103
103
|
### chartable
|
|
104
104
|
|
|
105
105
|
```ts
|
|
106
|
-
export function chartable({ bottom, gapX, gapY, headerColumn, id, left, maxY, reverse, right, rotate,
|
|
106
|
+
export function chartable({ bottom, gapX, gapY, headerColumn, id, left, maxY, reverse, right, rotate, table, top }: {
|
|
107
107
|
bottom?: number;
|
|
108
108
|
gapX?: number;
|
|
109
109
|
gapY?: number;
|
|
@@ -114,9 +114,7 @@ export function chartable({ bottom, gapX, gapY, headerColumn, id, left, maxY, re
|
|
|
114
114
|
reverse?: boolean;
|
|
115
115
|
right?: number;
|
|
116
116
|
rotate?: boolean;
|
|
117
|
-
singleScale?: boolean;
|
|
118
117
|
table: HTMLTableElement;
|
|
119
|
-
title?: string;
|
|
120
118
|
top?: number;
|
|
121
119
|
}): SVGSVGElement;
|
|
122
120
|
```
|
|
@@ -129,15 +127,13 @@ Options:
|
|
|
129
127
|
- `gapY`: Y axis spacing
|
|
130
128
|
- `headerColumn`: flag indicating that `table` has a header column (with X axis labels)
|
|
131
129
|
- `id`: chart id
|
|
132
|
-
- `left`: left padding
|
|
130
|
+
- `left`: left padding
|
|
133
131
|
- `maxY`: number of Y axis lines
|
|
134
132
|
- `reverse`: flag to reverse all data series
|
|
135
133
|
- `right`: right padding (for data series labels)
|
|
136
134
|
- `rotate`: flag to rotate X axis labels
|
|
137
|
-
- `singleScale`: flag to force single scale
|
|
138
135
|
- `table`: `HTMLTableElement` to extract data, data series labels and X axis labels
|
|
139
|
-
- `
|
|
140
|
-
- `top`: top padding (for the title)
|
|
136
|
+
- `top`: top padding
|
|
141
137
|
|
|
142
138
|
### eq
|
|
143
139
|
|
package/refsInfo.js
CHANGED
|
@@ -32,7 +32,7 @@ export const tests = {
|
|
|
32
32
|
|
|
33
33
|
'refsInfo: browserFingerprint': (/** @type {import('bun:test').Expect} */ expect) => {
|
|
34
34
|
const browserFingerprint = () => {
|
|
35
|
-
// @ts-
|
|
35
|
+
// @ts-expect-error
|
|
36
36
|
const refs = Object.getOwnPropertyNames(window).map(name => window[name])
|
|
37
37
|
const info = refsInfo(...refs)
|
|
38
38
|
const json = JSON.stringify(info)
|