@mathzetta/inlinemath 0.1.0 → 0.2.0
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/README.md +64 -20
- package/dist/cas.external.js +2 -2
- package/dist/cas.js +2 -2
- package/dist/chunks/calculate-Cz87Lt0N.js +2 -0
- package/dist/chunks/draw-Bev17BJJ.js +2 -0
- package/dist/chunks/edit-C65xXzo8.js +2 -0
- package/dist/chunks/edit-M68aRA5o.js +2 -0
- package/dist/chunks/{html-CvuSyhzk.js → html-BimAqn7x.js} +2 -2
- package/dist/chunks/html-CupluJSh.js +2 -0
- package/dist/chunks/lite-3Fb-OHbt.js +2 -0
- package/dist/inlinemath-cas.external.global.min.js +2 -2
- package/dist/inlinemath-cas.global.min.js +2 -2
- package/dist/inlinemath-lite-calc.global.min.js +2 -2
- package/dist/inlinemath-lite.external.global.min.js +2 -2
- package/dist/inlinemath-lite.global.min.js +2 -2
- package/dist/inlinemath.css +32 -1
- package/dist/inlinemath.external.global.min.js +2 -2
- package/dist/inlinemath.external.js +2 -2
- package/dist/inlinemath.global.min.js +2 -2
- package/dist/inlinemath.js +2 -2
- package/dist/lite-calc.js +2 -2
- package/dist/lite.external.js +2 -2
- package/dist/lite.js +2 -2
- package/dist/markdown.external.js +2 -2
- package/dist/markdown.js +2 -2
- package/inlinemath.css +32 -1
- package/package.json +3 -3
- package/src/cas.js +25 -15
- package/src/edit.js +96 -0
- package/src/glyphs.js +2 -0
- package/src/index.d.ts +2 -2
- package/src/index.js +1 -1
- package/src/layout.js +55 -11
- package/src/markdown.d.ts +2 -2
- package/src/markdown.js +354 -39
- package/src/mathzetta.js +2 -1
- package/src/types.d.ts +77 -6
- package/src/variables.js +228 -0
- package/src/view.js +226 -6
- package/dist/chunks/calculate-BX9lJ7Ff.js +0 -2
- package/dist/chunks/draw-Cm4exbg7.js +0 -2
- package/dist/chunks/html-DWtfytjA.js +0 -2
- package/dist/chunks/lite-Bj_L6w2g.js +0 -2
package/src/variables.js
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Saved variables for '@mathzetta/inlinemath/markdown': `$A := 2+2$` saves A, and A in any maths
|
|
3
|
+
* after it is drawn as 2 + 2 (and `{{A}}` is 4). A store holds them for a whole page, so every
|
|
4
|
+
* part drawn with renderMarkdownInto sees the others' variables, and an input bound to a variable
|
|
5
|
+
* (`$A := [[2+2]]$`, a textbox) redraws everything that uses it.
|
|
6
|
+
*
|
|
7
|
+
* import { createVariables, variables } from '@mathzetta/inlinemath/markdown';
|
|
8
|
+
* variables.set('A', 'x^2'); // the page's store: A is x² everywhere
|
|
9
|
+
* variables.get('A'); // 'x^2'
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Where a scope carries the saved variables' expressions, for {{…}} handlers that work with
|
|
14
|
+
* expressions rather than values (casBlocks: {{diff(f, x)}} with f saved): name → MathZetta
|
|
15
|
+
* postfix, every saved name inside already put in. A symbol, so the calculator never sees it.
|
|
16
|
+
*/
|
|
17
|
+
export const EXPRESSIONS = Symbol.for('inlinemath.expressions');
|
|
18
|
+
|
|
19
|
+
// ---- names ----------------------------------------------------------------------------------
|
|
20
|
+
|
|
21
|
+
const LEAF = new Set(['symbol', 'number']);
|
|
22
|
+
|
|
23
|
+
/** The variable a node names: A, α, A_1 (a symbol with a plain subscript) — else null. */
|
|
24
|
+
export function nameOf(node) {
|
|
25
|
+
if (!node) return null;
|
|
26
|
+
if (node.type === 'symbol') return node.value;
|
|
27
|
+
if (node.type === 'op' && node.op === '_' && node.args.length === 2 && node.args[0].type === 'symbol' && LEAF.has(node.args[1].type)) {
|
|
28
|
+
return `${node.args[0].value}_${node.args[1].value}`;
|
|
29
|
+
}
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** A tree with its ids (and where-it-came-from marks) dropped, so it can be numbered again inside another. */
|
|
34
|
+
export function bare(node) {
|
|
35
|
+
const { id, from, ...rest } = node;
|
|
36
|
+
if (rest.args) rest.args = rest.args.map(bare);
|
|
37
|
+
return rest;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** Ids dropped (to be numbered again), `from` marks kept. */
|
|
41
|
+
function renumber(node) {
|
|
42
|
+
const { id, ...rest } = node;
|
|
43
|
+
if (rest.args) rest.args = rest.args.map(renumber);
|
|
44
|
+
return rest;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The part of a substituted tree a variable stands for, written back in its own terms: the
|
|
49
|
+
* variables inside it put back as their names. `named(name)` gives a name's own tree.
|
|
50
|
+
*/
|
|
51
|
+
export function unexpand(node, named) {
|
|
52
|
+
const visit = (n, top) => {
|
|
53
|
+
if (!top && n.from !== undefined) return named(n.from);
|
|
54
|
+
const { id, from, ...rest } = n;
|
|
55
|
+
if (rest.args) rest.args = rest.args.map((a) => visit(a, false));
|
|
56
|
+
return rest;
|
|
57
|
+
};
|
|
58
|
+
return visit(node, true);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Every saved name in a tree replaced by its own tree (which may use other saved names).
|
|
63
|
+
* `lookup(name)` gives a saved name's tree, or null. A name inside its own definition is left as it is.
|
|
64
|
+
* @returns {{ tree: object, changed: boolean }}
|
|
65
|
+
*/
|
|
66
|
+
export function substitute(tree, lookup) {
|
|
67
|
+
let changed = false;
|
|
68
|
+
const seen = new Set();
|
|
69
|
+
const visit = (node) => {
|
|
70
|
+
const name = nameOf(node);
|
|
71
|
+
if (name !== null) {
|
|
72
|
+
if (!seen.has(name)) {
|
|
73
|
+
const value = lookup(name);
|
|
74
|
+
if (value) {
|
|
75
|
+
changed = true;
|
|
76
|
+
seen.add(name);
|
|
77
|
+
const out = { ...visit(bare(value)), from: name }; // where it came from, for editing
|
|
78
|
+
seen.delete(name);
|
|
79
|
+
return out;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return node; // A_1 is one name: its A is not substituted
|
|
83
|
+
}
|
|
84
|
+
if (node.args) return { ...node, args: node.args.map(visit) };
|
|
85
|
+
return node;
|
|
86
|
+
};
|
|
87
|
+
const out = visit(tree);
|
|
88
|
+
return { tree: changed ? renumber(out) : tree, changed };
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// ---- inputs ---------------------------------------------------------------------------------
|
|
92
|
+
|
|
93
|
+
const NUMBER = '[-+]?(?:\\d+\\.?\\d*|\\.\\d+)';
|
|
94
|
+
const SLIDER = new RegExp(`^(${NUMBER})\\s*\\.\\.\\s*(${NUMBER})(?:\\s+step\\s+(${NUMBER}))?(?:\\s*=\\s*(${NUMBER}))?$`);
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* What `[[…]]` asks for: `[[2+2]]` a textbox, `[[2+2 | x^2]]` a dropdown,
|
|
98
|
+
* `[[1..10]]` a slider (`[[0..1 step 0.1 = 0.5]]` with a step and a starting value). Else null.
|
|
99
|
+
*/
|
|
100
|
+
export function inputOf(text) {
|
|
101
|
+
const m = /^\s*\[\[([\s\S]*)\]\]\s*$/.exec(text);
|
|
102
|
+
// [[2, 1], [1, 3]] is a matrix (rows of a list), not an input
|
|
103
|
+
if (!m || /\]\s*,\s*\[/.test(m[1])) return null;
|
|
104
|
+
const inner = m[1].trim();
|
|
105
|
+
const range = SLIDER.exec(inner);
|
|
106
|
+
if (range) {
|
|
107
|
+
const min = Number(range[1]);
|
|
108
|
+
const max = Number(range[2]);
|
|
109
|
+
if (!(max > min)) return null;
|
|
110
|
+
const step = range[3] !== undefined ? Number(range[3]) : Number.isInteger(min) && Number.isInteger(max) ? 1 : (max - min) / 100;
|
|
111
|
+
if (!(step > 0)) return null;
|
|
112
|
+
const start = range[4] !== undefined ? Math.min(max, Math.max(min, Number(range[4]))) : min;
|
|
113
|
+
return { kind: 'slider', min, max, step, default: String(start) };
|
|
114
|
+
}
|
|
115
|
+
if (inner.includes('|')) {
|
|
116
|
+
const options = inner.split('|').map((o) => o.trim()).filter(Boolean);
|
|
117
|
+
if (options.length) return { kind: 'dropdown', options, default: options[0] };
|
|
118
|
+
}
|
|
119
|
+
return { kind: 'textbox', default: inner };
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// ---- the store ------------------------------------------------------------------------------
|
|
123
|
+
|
|
124
|
+
const PAGE = Symbol('set on the page');
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Where a page's variables live. A part of the page owns the definitions it makes (drawing it
|
|
128
|
+
* again replaces them); `set` is how an input — or the page's own code — changes one.
|
|
129
|
+
*/
|
|
130
|
+
export class Variables {
|
|
131
|
+
constructor() {
|
|
132
|
+
this.owners = new Map(); // owner → Map(name → definition)
|
|
133
|
+
this.chosen = new Map(); // name → { key, text }: what an input was set to
|
|
134
|
+
this.listeners = new Set();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** Every definition, in the order the parts were drawn; `except` leaves one part out. */
|
|
138
|
+
definitions(except) {
|
|
139
|
+
const all = new Map();
|
|
140
|
+
for (const [owner, defs] of this.owners) {
|
|
141
|
+
if (owner === except) continue;
|
|
142
|
+
for (const [name, def] of defs) {
|
|
143
|
+
all.delete(name); // a later definition goes after the earlier ones
|
|
144
|
+
all.set(name, def);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return all;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** The text a definition stands for now: its expression, or what its input is set to. */
|
|
151
|
+
textOf(def) {
|
|
152
|
+
const chosen = this.chosen.get(def.name);
|
|
153
|
+
return chosen && chosen.key === def.key ? chosen.text : def.text;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** A variable's expression now, or undefined. */
|
|
157
|
+
get(name) {
|
|
158
|
+
const def = this.definitions().get(name);
|
|
159
|
+
return def ? this.textOf(def) : undefined;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/** The saved names. */
|
|
163
|
+
names() {
|
|
164
|
+
return [...this.definitions().keys()];
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** Set a variable: what its input holds, or (with no input) a definition for the whole page. */
|
|
168
|
+
set(name, text) {
|
|
169
|
+
text = String(text);
|
|
170
|
+
const def = this.definitions().get(name);
|
|
171
|
+
if (def && def.input) {
|
|
172
|
+
const chosen = this.chosen.get(name);
|
|
173
|
+
if (chosen && chosen.key === def.key && chosen.text === text) return this;
|
|
174
|
+
this.chosen.set(name, { key: def.key, text });
|
|
175
|
+
} else {
|
|
176
|
+
const defs = new Map(this.owners.get(PAGE));
|
|
177
|
+
defs.set(name, { name, text, key: `page:${text}`, input: null });
|
|
178
|
+
this.owners.delete(PAGE);
|
|
179
|
+
this.owners.set(PAGE, defs);
|
|
180
|
+
}
|
|
181
|
+
this.notify(null, name);
|
|
182
|
+
return this;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** Forget a variable set with `set`, or everything (no name). */
|
|
186
|
+
clear(name) {
|
|
187
|
+
if (name === undefined) {
|
|
188
|
+
this.owners.clear();
|
|
189
|
+
this.chosen.clear();
|
|
190
|
+
} else {
|
|
191
|
+
this.owners.get(PAGE)?.delete(name);
|
|
192
|
+
this.chosen.delete(name);
|
|
193
|
+
}
|
|
194
|
+
this.notify(null, name);
|
|
195
|
+
return this;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/** Called with (owner, name) when something changes; returns a function that stops it. */
|
|
199
|
+
subscribe(fn) {
|
|
200
|
+
this.listeners.add(fn);
|
|
201
|
+
return () => this.listeners.delete(fn);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/** A part's definitions (null: it has none any more). Tells the others only when they change. */
|
|
205
|
+
own(owner, defs) {
|
|
206
|
+
const before = this.owners.get(owner);
|
|
207
|
+
const same = (a, b) => (a?.size ?? 0) === (b?.size ?? 0) && [...(a ?? [])].every(([k, d]) => b?.get(k)?.key === d.key);
|
|
208
|
+
if (same(before, defs)) {
|
|
209
|
+
if (defs) this.owners.set(owner, defs);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
if (defs && defs.size) this.owners.set(owner, defs);
|
|
213
|
+
else this.owners.delete(owner);
|
|
214
|
+
this.notify(owner);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
notify(owner, name) {
|
|
218
|
+
for (const fn of [...this.listeners]) fn(owner, name);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/** A store of its own, for parts of a page that shouldn't share variables. */
|
|
223
|
+
export function createVariables() {
|
|
224
|
+
return new Variables();
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/** The page's store: renderMarkdownInto uses it unless told otherwise. */
|
|
228
|
+
export const variables = createVariables();
|
package/src/view.js
CHANGED
|
@@ -7,14 +7,28 @@
|
|
|
7
7
|
* view.highlight('2x'); // or an id, path, key, test
|
|
8
8
|
* view.color('x^2', 'crimson');
|
|
9
9
|
* view.on('click', ({ node }) => …);
|
|
10
|
-
* view.set('2x + 2', { animate: true }); // next step
|
|
10
|
+
* view.set('2x + 2', { animate: true }); // next step (instant for readers who ask for reduced motion)
|
|
11
11
|
* view.segments() // [{ text, id }] spoken pieces
|
|
12
|
+
*
|
|
13
|
+
* Once something listens for 'click', the drawing works from the keyboard too:
|
|
14
|
+
* Tab to it, arrow keys walk its parts (Down into a part, Up out of it,
|
|
15
|
+
* Left/Right between neighbours, Home or Escape back to the whole), Enter or
|
|
16
|
+
* Space fires the click handlers for the current part, and each part is spoken.
|
|
17
|
+
*
|
|
18
|
+
* view.editable({ toText }) (toText from 'mathzetta/text') lets the reader change it: double-click
|
|
19
|
+
* a part, or press F2 on the part the keyboard is on, and a text box opens over it; Enter puts
|
|
20
|
+
* the new text in its place, Escape leaves it. { onEdit } hears each change.
|
|
21
|
+
*
|
|
22
|
+
* With { announce: true }, each set() after the first reads the new expression
|
|
23
|
+
* to a screen reader through a polite live region placed after the element
|
|
24
|
+
* (or pass your own live-region element as `announce`).
|
|
12
25
|
*/
|
|
13
26
|
|
|
14
|
-
import { toSpeechSegments } from './mathzetta.js';
|
|
27
|
+
import { toSpeechSegments, toAudioSpeech } from './mathzetta.js';
|
|
15
28
|
import { treeOf, layoutOptions } from './html.js';
|
|
16
29
|
import { layout } from './layout.js';
|
|
17
|
-
import { select, signature, pathOf } from './select.js';
|
|
30
|
+
import { select, signature, pathOf, nodeAt } from './select.js';
|
|
31
|
+
import { openEditor, replaceAt } from './edit.js';
|
|
18
32
|
|
|
19
33
|
export class View {
|
|
20
34
|
/**
|
|
@@ -27,20 +41,56 @@ export class View {
|
|
|
27
41
|
this.options = options;
|
|
28
42
|
this.p = options.prefix || 'mv';
|
|
29
43
|
this.handlers = [];
|
|
44
|
+
this.clicks = []; // the 'click' handlers, which Enter and Space call too
|
|
45
|
+
this.active = null; // the part the keyboard is on (null: the whole expression)
|
|
46
|
+
this.live = liveRegionFor(element, options.announce, this.p);
|
|
30
47
|
this.set(input);
|
|
31
48
|
}
|
|
32
49
|
|
|
33
50
|
/**
|
|
34
51
|
* Show a new expression. With { animate: true }, parts that appear in
|
|
35
|
-
* both move from their old place to their new one, and new parts fade in
|
|
52
|
+
* both move from their old place to their new one, and new parts fade in —
|
|
53
|
+
* unless the reader's system asks for reduced motion, when the new step
|
|
54
|
+
* simply appears. { animate: 'always' } animates regardless (a page whose
|
|
55
|
+
* point is the motion, started by the reader).
|
|
36
56
|
*/
|
|
37
57
|
set(input, { animate = false, duration = 600, easing = 'ease-in-out' } = {}) {
|
|
38
|
-
const before = animate && this.tree ? this.snapshot() : null;
|
|
58
|
+
const before = shouldAnimate(animate) && this.tree ? this.snapshot() : null;
|
|
59
|
+
const isStep = this.tree !== undefined;
|
|
39
60
|
this.tree = treeOf(input, this.options);
|
|
40
61
|
this.element.innerHTML = layout(this.tree, layoutOptions(this.tree, this.options)).html;
|
|
41
62
|
this.root = this.element.firstElementChild;
|
|
42
63
|
if (this.handlers.length) this.root.classList.add(`${this.p}-clickable`);
|
|
64
|
+
if (this.editing) this.root.classList.add(`${this.p}-editable`);
|
|
65
|
+
this.active = null;
|
|
66
|
+
if (this.clicks.length || this.editing) this.focusable();
|
|
43
67
|
if (before) this.morph(before, { duration, easing });
|
|
68
|
+
if (isStep && this.live) this.announce(this.spoken());
|
|
69
|
+
return this;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** The expression as a listener hears it: its accessible name, else MathZetta's audio speech. */
|
|
73
|
+
spoken() {
|
|
74
|
+
const label = this.root && this.root.getAttribute && this.root.getAttribute('aria-label');
|
|
75
|
+
if (label) return label;
|
|
76
|
+
try { return toAudioSpeech(this.tree); } catch { return ''; }
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Say something through the view's live region ({ announce } must be set): the new step is
|
|
81
|
+
* announced this way, and a page can add its own words ("Step 3: …"). The region is emptied
|
|
82
|
+
* first, so the same words twice are still read.
|
|
83
|
+
*/
|
|
84
|
+
announce(text) {
|
|
85
|
+
return this.say(this.live, text);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
say(live, text) {
|
|
89
|
+
if (!live) return this;
|
|
90
|
+
live.textContent = '';
|
|
91
|
+
const put = () => { live.textContent = text; };
|
|
92
|
+
if (typeof requestAnimationFrame === 'function') requestAnimationFrame(() => requestAnimationFrame(put));
|
|
93
|
+
else setTimeout(put, 50);
|
|
44
94
|
return this;
|
|
45
95
|
}
|
|
46
96
|
|
|
@@ -92,7 +142,151 @@ export class View {
|
|
|
92
142
|
this.element.addEventListener(type, listener);
|
|
93
143
|
this.handlers.push([type, listener]);
|
|
94
144
|
this.root.classList.add(`${this.p}-clickable`);
|
|
95
|
-
|
|
145
|
+
if (type === 'click') { this.clicks.push(fn); this.keyboard(); }
|
|
146
|
+
return () => {
|
|
147
|
+
this.element.removeEventListener(type, listener);
|
|
148
|
+
this.clicks = this.clicks.filter((f) => f !== fn);
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// ---- editing a part in place ---------------------------------------------------
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Let the reader edit the expression a part at a time (double-click, or F2 from the keyboard).
|
|
156
|
+
* @param {object} how
|
|
157
|
+
* @param {(node: object) => string} how.toText MathZetta's toText ('mathzetta/text')
|
|
158
|
+
* @param {(change: { tree, text, path, part }) => void} [how.onEdit] after each change: the
|
|
159
|
+
* new expression (tree, and as text), where the edited part is and what was typed
|
|
160
|
+
*/
|
|
161
|
+
editable({ toText, onEdit } = {}) {
|
|
162
|
+
if (typeof toText !== 'function') throw new Error("editable needs { toText } (import { toText } from 'mathzetta/text')");
|
|
163
|
+
this.editing = { toText, onEdit };
|
|
164
|
+
if (this.root && this.root.classList) this.root.classList.add(`${this.p}-editable`);
|
|
165
|
+
this.keyboard();
|
|
166
|
+
if (!this.editOn && this.element.addEventListener) {
|
|
167
|
+
this.editOn = true;
|
|
168
|
+
this.element.addEventListener('dblclick', (event) => {
|
|
169
|
+
const element = event.target.closest?.('[data-node]');
|
|
170
|
+
if (!element || !this.root.contains(element)) return;
|
|
171
|
+
event.preventDefault();
|
|
172
|
+
this.edit(select(this.tree, Number(element.dataset.node))[0]);
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
return this;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/** Open the text box over a part (a node, or any target select() takes). */
|
|
179
|
+
edit(target = this.tree, { returnFocus = false } = {}) {
|
|
180
|
+
if (!this.editing) throw new Error('call editable({ toText }) first');
|
|
181
|
+
const node = typeof target === 'object' && target && target.type ? target : this.nodes(target)[0];
|
|
182
|
+
if (!node) return null;
|
|
183
|
+
const path = pathOf(this.tree, node.id) || [];
|
|
184
|
+
const element = this.elementOf(node) || this.root;
|
|
185
|
+
let label = 'Edit';
|
|
186
|
+
try { label = `Edit ${toAudioSpeech(node)}`; } catch { /* the plain name will do */ }
|
|
187
|
+
const back = () => { if (returnFocus && this.root.focus) this.root.focus(); };
|
|
188
|
+
return openEditor(element, this.editing.toText(node), {
|
|
189
|
+
label,
|
|
190
|
+
parse: (text) => treeOf(text, this.options),
|
|
191
|
+
commit: (part, typed) => {
|
|
192
|
+
this.set(replaceAt(this.tree, path, part), { animate: true });
|
|
193
|
+
const inPlace = nodeAt(this.tree, path);
|
|
194
|
+
if (returnFocus && inPlace) this.focusPart(inPlace === this.tree ? null : inPlace);
|
|
195
|
+
back();
|
|
196
|
+
if (this.editing.onEdit) this.editing.onEdit({ tree: this.tree, text: this.editing.toText(this.tree), path, part: typed });
|
|
197
|
+
},
|
|
198
|
+
cancel: back,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// ---- the keyboard: what a click does, without a pointer -----------------------
|
|
203
|
+
|
|
204
|
+
/** Make the expression one tab stop, with the keys explained to a screen reader. */
|
|
205
|
+
focusable() {
|
|
206
|
+
if (!this.root || !this.root.setAttribute) return;
|
|
207
|
+
this.root.setAttribute('tabindex', '0');
|
|
208
|
+
// a focusable element needs a name: with { mathml: true } the drawing has none of its own (the MathML has it)
|
|
209
|
+
if (!this.root.getAttribute('aria-label')) { this.root.setAttribute('role', 'math'); this.root.setAttribute('aria-label', this.spoken()); }
|
|
210
|
+
this.root.setAttribute('aria-description', this.editing
|
|
211
|
+
? 'Arrow keys move between parts, F2 edits one.'
|
|
212
|
+
: 'Arrow keys move between parts, Enter selects one.');
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** Listen for the keys once, on the element (it outlives every set()). */
|
|
216
|
+
keyboard() {
|
|
217
|
+
this.focusable();
|
|
218
|
+
if (this.keysOn || !this.element.addEventListener) return;
|
|
219
|
+
this.keysOn = true;
|
|
220
|
+
this.partsLive = this.live || liveRegionFor(this.element, true, this.p);
|
|
221
|
+
this.element.addEventListener('keydown', (event) => this.key(event));
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
key(event) {
|
|
225
|
+
if (!this.root || !this.root.contains(event.target)) return;
|
|
226
|
+
const at = this.active;
|
|
227
|
+
let next;
|
|
228
|
+
switch (event.key) {
|
|
229
|
+
case 'ArrowDown': next = at ? this.partsOf(at)[0] : this.partsOf(this.tree)[0]; break;
|
|
230
|
+
case 'ArrowUp': next = at ? this.outerOf(at) : undefined; break;
|
|
231
|
+
case 'ArrowRight': next = at ? this.neighbour(at, 1) : this.partsOf(this.tree)[0]; break;
|
|
232
|
+
case 'ArrowLeft': next = at ? this.neighbour(at, -1) : undefined; break;
|
|
233
|
+
case 'Home': case 'Escape': next = null; break;
|
|
234
|
+
case 'F2':
|
|
235
|
+
if (!this.editing) return;
|
|
236
|
+
event.preventDefault();
|
|
237
|
+
this.edit(at || this.tree, { returnFocus: true });
|
|
238
|
+
return;
|
|
239
|
+
case 'Enter': case ' ': {
|
|
240
|
+
event.preventDefault();
|
|
241
|
+
const node = at || this.tree;
|
|
242
|
+
const element = this.elementOf(node) || this.root;
|
|
243
|
+
const info = { node, id: node.id, path: pathOf(this.tree, node.id), element, event };
|
|
244
|
+
for (const fn of this.clicks) fn(info);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
default: return;
|
|
248
|
+
}
|
|
249
|
+
event.preventDefault();
|
|
250
|
+
if (next === undefined) return; // nowhere to go: stay put
|
|
251
|
+
this.focusPart(next);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/** Put the keyboard on a part (null: the whole expression) and say it. */
|
|
255
|
+
focusPart(node) {
|
|
256
|
+
const cls = `${this.p}-focus`;
|
|
257
|
+
this.root.querySelectorAll(`.${cls}`).forEach((e) => e.classList.remove(cls));
|
|
258
|
+
this.active = node;
|
|
259
|
+
const element = node && this.elementOf(node);
|
|
260
|
+
if (element) element.classList.add(cls);
|
|
261
|
+
let words = '';
|
|
262
|
+
try { words = node ? toAudioSpeech(node) : this.spoken(); } catch { words = ''; }
|
|
263
|
+
this.say(this.partsLive, words);
|
|
264
|
+
return this;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/** The parts directly inside a node that are drawn (an undrawn wrapper is looked through). */
|
|
268
|
+
partsOf(node) {
|
|
269
|
+
const out = [];
|
|
270
|
+
const visit = (n) => { if (this.elementOf(n)) out.push(n); else if (n.type === 'op') n.args.forEach(visit); };
|
|
271
|
+
if (node && node.type === 'op') node.args.forEach(visit);
|
|
272
|
+
return out;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/** The drawn part a node sits in, or null for the whole expression. */
|
|
276
|
+
outerOf(node) {
|
|
277
|
+
const path = pathOf(this.tree, node.id);
|
|
278
|
+
for (let k = path ? path.length - 1 : -1; k > 0; k--) {
|
|
279
|
+
const up = nodeAt(this.tree, path.slice(0, k));
|
|
280
|
+
if (up && this.elementOf(up)) return up;
|
|
281
|
+
}
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/** The part beside this one (dir 1 next, -1 previous), or undefined at the end. */
|
|
286
|
+
neighbour(node, dir) {
|
|
287
|
+
const siblings = this.partsOf(this.outerOf(node) || this.tree);
|
|
288
|
+
const i = siblings.indexOf(node);
|
|
289
|
+
return i < 0 ? undefined : siblings[i + dir];
|
|
96
290
|
}
|
|
97
291
|
|
|
98
292
|
/** The expression read aloud in pieces, each tagged with the node it describes. */
|
|
@@ -156,6 +350,32 @@ export class View {
|
|
|
156
350
|
}
|
|
157
351
|
}
|
|
158
352
|
|
|
353
|
+
/**
|
|
354
|
+
* The live region steps are announced through: the element given, or a visually hidden polite
|
|
355
|
+
* region created right after the view's element (its contents are replaced by every set()).
|
|
356
|
+
*/
|
|
357
|
+
function liveRegionFor(element, announce, prefix) {
|
|
358
|
+
if (!announce) return null;
|
|
359
|
+
if (typeof announce === 'object' && announce.nodeType === 1) return announce;
|
|
360
|
+
if (typeof document === 'undefined' || !element.insertAdjacentElement) return null;
|
|
361
|
+
const live = document.createElement('span');
|
|
362
|
+
live.className = `${prefix}-sr-only`;
|
|
363
|
+
live.setAttribute('aria-live', 'polite');
|
|
364
|
+
live.setAttribute('aria-atomic', 'true');
|
|
365
|
+
element.insertAdjacentElement('afterend', live);
|
|
366
|
+
return live;
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Should a step animate? true honours prefers-reduced-motion (no motion for a reader who asked
|
|
371
|
+
* for none), 'always' does not, false never animates.
|
|
372
|
+
*/
|
|
373
|
+
export function shouldAnimate(animate) {
|
|
374
|
+
if (!animate) return false;
|
|
375
|
+
if (animate === 'always') return true;
|
|
376
|
+
return !(typeof matchMedia === 'function' && matchMedia('(prefers-reduced-motion: reduce)').matches);
|
|
377
|
+
}
|
|
378
|
+
|
|
159
379
|
/** Draw an expression into an element and return a View for it. */
|
|
160
380
|
export function render(element, input, options = {}) {
|
|
161
381
|
return new View(element, input, options);
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/* Inline Math 0.1.0 — MIT licence; includes mathzetta (and @mathzetta/cas, for the CAS) */
|
|
2
|
-
import{f as t,g as n,h as e,i as r,j as o,k as i}from"./lite-Bj_L6w2g.js";const a={pi:Math.PI,"π":Math.PI,e:Math.E,tau:2*Math.PI,"τ":2*Math.PI,"∞":1/0,"-∞":-1/0,true:!0,false:!1},s=(t,n)=>n?s(n,t%n):Math.abs(t),u={neg:t=>-t,pm:t=>[t,-t],"!":t=>{if(!Number.isInteger(t)||t<0)return NaN;if(t>170)return 1/0;let n=1;for(let e=2;e<=t;e++)n*=e;return n},"\\not":t=>!t,sqrt:Math.sqrt,abs:Math.abs,floor:Math.floor,ceil:Math.ceil,ln:Math.log,loglog:t=>Math.log(Math.log(t)),logloglog:t=>Math.log(Math.log(Math.log(t))),expm1:Math.expm1,sin:Math.sin,cos:Math.cos,tan:Math.tan,csc:t=>1/Math.sin(t),sec:t=>1/Math.cos(t),cot:t=>1/Math.tan(t),sinh:Math.sinh,cosh:Math.cosh,tanh:Math.tanh,arcsin:Math.asin,arccos:Math.acos,arctan:Math.atan,arcsinh:Math.asinh,arccosh:Math.acosh,arctanh:Math.atanh},c={"+":(t,n)=>t+n,"-":(t,n)=>t-n,"*":(t,n)=>t*n,"/":(t,n)=>t/n,"^":(t,n)=>t**n,mod:(t,n)=>t%n,log:(t,n)=>Math.log(n)/Math.log(t),root:(t,n)=>n**(1/t),atan2:Math.atan2,round:(t,n)=>Math.round(t*10**n)/10**n,"±":(t,n)=>[t+n,t-n],fixed:(t,n)=>Number(t).toFixed(n),perm:(t,n)=>{if(!Number.isInteger(t)||!Number.isInteger(n)||n<0||n>t)return NaN;let e=1;for(let r=t-n+1;r<=t&&e!==1/0;r++)e*=r;return e},comb:(t,n)=>{if(!Number.isInteger(t)||!Number.isInteger(n)||n<0||n>t)return NaN;n=Math.min(n,t-n);let e=1;for(let r=1;r<=n&&e!==1/0;r++)e=e*(t-n+r)/r;return Math.round(e)},"=":(t,n)=>t==n,"===":(t,n)=>t===n,"≠":(t,n)=>t!=n,"≠=":(t,n)=>t!==n,"≈":(t,n)=>Math.abs(t-n)<1e-9,"≡":(t,n)=>t===n,"∪":(t,n)=>[...new Set([...[].concat(t),...[].concat(n)])],"∩":(t,n)=>[].concat(t).filter(t=>[].concat(n).includes(t)),"<":(t,n)=>t<n,">":(t,n)=>t>n,"≤":(t,n)=>t<=n,"≥":(t,n)=>t>=n,"&":(t,n)=>t&&n,"|":(t,n)=>t||n,"\\xor":(t,n)=>Boolean(t)!==Boolean(n),"\\nor":(t,n)=>!(t||n),"\\nand":(t,n)=>!(t&&n)},l={max:t=>Math.max(...t),min:t=>Math.min(...t),sum:t=>t.reduce((t,n)=>t+n,0),prod:t=>t.reduce((t,n)=>t*n,1),mean:t=>t.reduce((t,n)=>t+n,0)/t.length,gcd:t=>t.reduce(s),"()":t=>t,"[]":t=>t,"{}":t=>t};const f=5e6;let h=0,m=0;function g(t,e){if(++h>f)throw new Error("Too much to work out");switch(t.type){case"number":return Number(t.value);case"string":return t.value.slice(1,-1);case"symbol":if(Object.prototype.hasOwnProperty.call(e,t.value))return e[t.value];if(Object.prototype.hasOwnProperty.call(a,t.value))return a[t.value];throw new Error(`No value for '${t.value}'`)}const r=n(t);if(r)return g(r,e);const{op:o,args:i}=t;if("?:"===o)return g(i[0],e)?g(i[1],e):g(i[2],e);if("∈"===o||"∉"===o)return function(t,n){const[e,r]=t.args,o=g(e,n);let i;if("symbol"===r.type&&b[r.value])return i=b[r.value](o),"∈"===t.op?i:!i;if("op"===r.type&&["()","[]","(]","[)"].includes(r.op)&&2===r.args.length){const[t,e]=r.args.map(t=>g(t,n)),a="["===r.op[0]?o>=t:o>t,s="]"===r.op[1]?o<=e:o<e;i=a&&s}else{const t=g(r,n);i=Array.isArray(t)&&t.includes(o)}return"∈"===t.op?i:!i}(t,e);if("random"===o)return Math.random();if(("\\sumidx"===o||"\\prodidx"===o)&&3===i.length&&"op"===i[1].type&&"="===i[1].op&&"symbol"===i[1].args[0].type){const[t,n,r]=[i[0],i[1].args[1],i[2]],a=i[1].args[0].value,s=g(n,e),u=g(r,e);if(!Number.isFinite(s)||!Number.isFinite(u)||u-s>1e6)throw new Error(`Can't evaluate '${o}' over that range`);let c="\\sumidx"===o?0:1;for(let n=s;n<=u;n++){const r=g(t,{...e,[a]:n});c="\\sumidx"===o?c+r:c*r}return c}if("pmod"===o){const[t,n]=i,r=g(n,e);if("op"===t.type&&["≡","="].includes(t.op)){const[n,o]=t.args.map(t=>g(t,e));return(n-o)%r===0}return g(t,e)%r}const s=i.map(t=>g(t,e));if(u[o]&&1===s.length)return u[o](s[0]);if(c[o]&&2===s.length)return c[o](s[0],s[1]);if(l[o])return l[o](s);throw new Error(`Can't evaluate '${o}'`)}const b={"ℝ":Number.isFinite,"ℤ":Number.isInteger,"ℕ":t=>Number.isInteger(t)&&t>0,"ℚ":Number.isFinite,"ℂ":t=>"number"==typeof t&&!Number.isNaN(t)};for(const t of[a,u,c,l,b])Object.setPrototypeOf(t,null);class d extends Error{}class p extends Error{}const M={bits:2e5,factorial:2e4,terms:1e5,rootIndex:12,steps:5e6};let w=0,y=0;const N=t=>t<0n?-t:t,v=t=>0n===t?0:N(t).toString(2).length;function x(t,n){for(t=N(t),n=N(n);n;)[t,n]=[n,t%n];return t}function I(t,n=1n){if(0n===n)throw new d("division by zero");n<0n&&(t=-t,n=-n);const e=x(t,n)||1n;return{n:t/e,d:n/e}}const $=I(0n),B=I(1n),F=(t,n)=>I(t.n*n.d+n.n*t.d,t.d*n.d),A=(t,n)=>I(t.n*n.n,t.d*n.d),O=(t,n)=>I(t.n*n.d,t.d*n.n),S=t=>({n:-t.n,d:t.d}),P=(t,n)=>{const e=t.n*n.d-n.n*t.d;return e<0n?-1:e>0n?1:0},j=t=>{const n=t.n/t.d;return t.n<0n&&n*t.d!==t.n?n-1n:n};function k(t){const n=v(t.n),e=v(t.d);if(n<1e3&&e<1e3)return Number(t.n)/Number(t.d);const r=BigInt(Math.max(n,e)-1e3),o=t.d>>r;return 0n===o?t.n<0n?-1/0:1/0:Number(t.n>>r)/Number(o)}function E(t){let n=String(t).trim(),e=1n;n.startsWith("-")&&(e=-1n,n=n.slice(1));const r=n.endsWith("..");r&&(n=n.slice(0,-2));let o=0;const i=n.search(/e/i);i>=0&&(o=Number(n.slice(i+1)),n=n.slice(0,i));const[a="",s=""]=n.split(".");if(!(/^\d*$/.test(a)&&/^\d*$/.test(s)&&a+s))throw new p(`'${t}' is not a number`);let u;if(r&&s){let t=1;for(let n=1;2*n<=s.length;n++)if(s.slice(-n)===s.slice(-2*n,-n)){t=n;break}const n=s.slice(-t);let e=s;for(;e.endsWith(n);)e=e.slice(0,-t);const r=BigInt(e||"0"),o=BigInt(e+n);u=F(I(BigInt(a||"0")),I(o-r,(10n**BigInt(t)-1n)*10n**BigInt(e.length)))}else u=I(BigInt(a+s||"0"),10n**BigInt(s.length));return o&&(u=o>0?A(u,I(10n**BigInt(o))):O(u,I(10n**BigInt(-o)))),e<0n?S(u):u}function z(t,n=0,e=0,r=null){return 0n===t.n?{kind:"x",c:$,pi:0,e:0,root:null}:{kind:"x",c:t,pi:n,e:e,root:r}}const W=(t,n=1n)=>z(I(BigInt(t),BigInt(n))),q=z(B,1),D=z(B,0,1),_=t=>null!==t&&"object"==typeof t&&"x"===t.kind,C=t=>_(t)&&!t.pi&&!t.e&&!t.root,T=t=>_(t)?0n===t.c.n:0===t,G=t=>C(t)&&1n===t.c.d?t.c.n:null,J=(t,n)=>Object.assign(t,{group:n}),L=t=>({kind:"s",text:t});function R(t,n){return t&&n?t.n===n.n&&t.r===n.r:t===n}const X=(t,n)=>0===P(t.c,n.c)&&t.pi===n.pi&&t.e===n.e&&R(t.root,n.root);function Z(t){if("number"==typeof t)return t;if(_(t)){let n=k(t.c);return t.pi&&(n*=Math.PI**t.pi),t.e&&(n*=Math.E**t.e),t.root&&(n*=k(I(t.root.r))**(1/t.root.n)),n}if("boolean"==typeof t)return t?1:0;throw new p("not a number")}function H(t,...n){if(Number.isNaN(t))throw new d("undefined");if(!Number.isFinite(t)&&n.every(Number.isFinite))throw new p("too large to calculate");return t}const K=t=>"boolean"==typeof t?t:_(t)?0n!==t.c.n:"number"==typeof t?0!==t:Boolean(t);function Q(t){if("bigint"==typeof t)return z(I(t));if("number"==typeof t)return Number.isFinite(t)?z(Number.isInteger(t)&&Math.abs(t)<=Number.MAX_SAFE_INTEGER?I(BigInt(t)):E(String(t))):t;if("boolean"==typeof t)return t;if("string"==typeof t)return/^-?(\d+\.?\d*|\.\d+)(\.\.)?$/.test(t.trim())?z(E(t)):kt(e(t),{});if(Array.isArray(t))return J(t.map(Q),t.group||"()");if(_(t)||"function"==typeof t)return t;throw new p(`can't use ${typeof t} as a value`)}function U(t){return Array.isArray(t)?t.map(U):t&&"s"===t.kind?t.text:"boolean"==typeof t?t:Z(t)}function V(t,n){if(t<2n)return t;const e=BigInt(n);let r=1n<<BigInt(Math.ceil(v(t)/n));for(;;){const n=((e-1n)*r+t/r**(e-1n))/e;if(n>=r)return r;r=n}}function Y(t,n,e,r=0,o=0){if(0n===e)return z($);const{coef:i,root:a}=function(t,n){let e=1n,r=n;const o=BigInt(t),i=r<10n**24n?1000000n:10000n;for(let t=2n;t<=i&&t*t<=r;t+=2n===t?1n:2n){const n=t**o;for(;r%n===0n;)r/=n,e*=t}const a=V(r,t);if(a**o===r&&(e*=a,r=1n),1n===r)return{coef:e,root:null};for(let n=t;n>=2;n--){if(t%n!==0)continue;const o=V(r,n);if(o**BigInt(n)===r)return{coef:e,root:{n:t/n,r:o}}}return{coef:e,root:{n:t,r:r}}}(n,e);return a&&1===a.n?z(A(t,I(i*a.r)),r,o):z(A(t,I(i)),r,o,a)}function tt(t,n){const e=A(t.c,n.c);if(v(e.n)+v(e.d)>M.bits)return null;const r=t.pi+n.pi,o=t.e+n.e;if(!t.root||!n.root)return z(e,r,o,t.root||n.root);const i=Bt(t.root.n,n.root.n);if(i>M.rootIndex)return null;const a=t.root.r**BigInt(i/t.root.n)*n.root.r**BigInt(i/n.root.n);return v(a)>4e3?null:Y(e,i,a,r,o)}function nt(t){if(0n===t.c.n)throw new d("division by zero");const n=z(O(B,t.c),-t.pi,-t.e);if(!t.root)return n;const{n:e,r:r}=t.root;return tt(n,Y(I(1n,r),e,r**BigInt(e-1)))}function et(t,n){if(0n===n){if(0n===t.c.n)throw new d("0^0 is undefined");return z(B)}if(n<0n){const e=nt(t);return e&&et(e,-n)}if((v(t.c.n)+v(t.c.d)+(t.root?v(t.root.r):0))*Number(n)>M.bits||n>100000n)return null;const e=I(t.c.n**n,t.c.d**n),r=Number(n);if(!t.root)return z(e,t.pi*r,t.e*r);const{n:o,r:i}=t.root,a=i**(n/BigInt(o));return Y(A(e,I(a)),o,i**(n%BigInt(o))||1n,t.pi*r,t.e*r)}function rt(t,n,e){if(!C(t)||e>1000n)return null;const r=et(t,n);if(!r)return null;let{n:o,d:i}=r.c,a=!1;if(o<0n){if(e%2n==0n)throw new d("not a real number");a=!0,o=-o}const s=function(t,n){const e=t.n*t.d**BigInt(n-1);return v(e)>4e3?null:Y(I(1n,t.d),n,e)}({n:o,d:i},Number(e));return s?a?z(S(s.c),s.pi,s.e,s.root):s:null}function ot(t){return n=>Array.isArray(n)?J(n.map(n=>ot(t)(n)),n.group):t(n)}function it(t){const n=(e,r)=>{const o=Array.isArray(e),i=Array.isArray(r);if(o&&i){if(e.length!==r.length)throw new d("lists of different lengths");return J(e.map((t,e)=>n(t,r[e])),e.group)}return o?J(e.map(t=>n(t,r)),e.group):i?J(r.map(t=>n(e,t)),r.group):t(e,r)};return n}const at=it((t,n)=>_(t)&&_(n)&&function(t,n){if(0n===t.c.n)return n;if(0n===n.c.n)return t;if(t.pi!==n.pi||t.e!==n.e||!R(t.root,n.root))return null;const e=F(t.c,n.c);return v(e.n)+v(e.d)>M.bits?null:z(e,t.pi,t.e,t.root)}(t,n)||H(Z(t)+Z(n),Z(t),Z(n))),st=ot(t=>_(t)?z(S(t.c),t.pi,t.e,t.root):-Z(t)),ut=(t,n)=>at(t,st(n)),ct=it((t,n)=>_(t)&&_(n)&&tt(t,n)||H(Z(t)*Z(n),Z(t),Z(n))),lt=it((t,n)=>{if(T(n))throw new d("division by zero");if(_(t)&&_(n)){const e=nt(n),r=e&&tt(t,e);if(r)return r}return H(Z(t)/Z(n),Z(t),Z(n))}),ft=it((t,n)=>{if(_(t)&&C(n)){const{n:e,d:r}=n.c,o=1n===r?et(t,e):rt(t,e,r);if(o)return o}const e=Z(t),r=Z(n);if(0===e&&0===r)throw new d("0^0 is undefined");if(0===e&&r<0)throw new d("division by zero");if(e<0&&!Number.isInteger(r))throw new d("not a real number");return H(e**r,e,r)});function ht(t,n){if(C(t)&&C(n))return P(t.c,n.c);if(_(t)&&_(n)&&X(t,n))return 0;const e=Z(t),r=Z(n);return e===r||Number.isFinite(e)&&Number.isFinite(r)&&Math.abs(e-r)<=1e-12*Math.max(1,Math.abs(e),Math.abs(r))?0:e<r?-1:1}function mt(t,n){return Array.isArray(t)||Array.isArray(n)?Array.isArray(t)&&Array.isArray(n)&&t.length===n.length&&t.every((t,e)=>mt(t,n[e])):t&&"s"===t.kind?Boolean(n&&"s"===n.kind&&t.text===n.text):"boolean"==typeof t||"boolean"==typeof n?t===n:0===ht(t,n)}const gt={0:()=>W(0),2:()=>W(1,2),3:()=>Y(I(1n,2n),2,2n),4:()=>Y(I(1n,2n),2,3n),6:()=>W(1)};function bt(t){t=(t%24+24)%24;const[n,e]=t<=6?[t,1]:t<=12?[12-t,1]:t<=18?[t-12,-1]:[24-t,-1],r=gt[n];return r?e<0?st(r()):r():null}const dt=t=>bt(t+6),pt=(t,n)=>Math.abs(t)<1e-15&&Math.abs(n)>1e-6?0:t;function Mt(t,n){const e=function(t){if(T(t))return 0;if(!_(t)||1!==t.pi||t.e||t.root)return null;const n=A(t.c,I(12n));return 1n!==n.d?null:Number((n.n%24n+24n)%24n)}(n);if(null!==e){const n=bt(e),r=dt(e);if(n&&r)switch(t){case"sin":return n;case"cos":return r;case"tan":return lt(n,r);case"cot":return lt(r,n);case"sec":return lt(W(1),r);case"csc":return lt(W(1),n)}}const r=Z(n),o=pt(Math.sin(r),r),i=pt(Math.cos(r),r),a={sin:o,cos:i,tan:o/i,cot:i/o,sec:1/i,csc:1/o}[t];if(!Number.isFinite(a)&&Number.isFinite(r))throw new d("undefined");return H(a)}function wt(t,n){const e={arcsin:[-6,6],arccos:[0,12],arctan:[-5,5]}[t],r=n=>"arcsin"===t?bt(n):"arccos"===t?dt(n):dt(n)&&!T(dt(n))?lt(bt(n),dt(n)):null;if(_(n))for(let t=e[0];t<=e[1];t++){const e=r(t);if(e&&_(e)&&X(e,n))return z(I(BigInt(t),12n),1)}const o=Z(n);if("arctan"!==t&&Math.abs(o)>1)throw new d("not a real number");return{arcsin:Math.asin,arccos:Math.acos,arctan:Math.atan}[t](o)}function yt(t){if(_(t)){if(0n===t.c.n)throw new d("ln 0 is undefined");if(t.c.n<0n)throw new d("not a real number");if(1n===t.c.n&&1n===t.c.d&&!t.pi&&!t.root)return W(t.e)}const n=Z(t);if(n<=0)throw new d(0===n?"ln 0 is undefined":"not a real number");return Math.log(n)}function Nt(t){if(t<.5)return Math.PI/(Math.sin(Math.PI*t)*Nt(1-t));const n=[.9999999999998099,676.5203681218851,-1259.1392167224028,771.3234287776531,-176.6150291621406,12.507343278686905,-.13857109526572012,9984369578019572e-21,1.5056327351493116e-7];let e=n[0];const r=(t-=1)+7+.5;for(let r=1;r<9;r++)e+=n[r]/(t+r);return Math.sqrt(2*Math.PI)*r**(t+.5)*Math.exp(-r)*e}function vt(t,n){const e=G(t)??("number"==typeof t&&Number.isInteger(t)?BigInt(t):null);if(null===e)throw new d(`${n} needs whole numbers`);return e}const xt=ot(t=>C(t)?z(I(j(t.c))):Q(Math.floor(Z(t)))),It=ot(t=>C(t)?z(I(-j(S(t.c)))):Q(Math.ceil(Z(t))));function $t(t,n){const e=Number(vt(n,"round"));if(C(t)){const n=I(10n**BigInt(Math.abs(e))),r=e>=0?A(t.c,n):O(t.c,n),o=j(F(A(I(2n),I(N(r.n),r.d)),B))/2n,i=I(r.n<0n?-o:o);return z(e>=0?O(i,n):A(i,n))}const r=10**e;return Math.sign(Z(t))*Math.round(Math.abs(Z(t))*r)/r}const Bt=(t,n)=>t/Ft(t,n)*n,Ft=(t,n)=>n?Ft(n,t%n):t,At={pi:()=>q,"π":()=>q,tau:()=>z(I(2n),1),"τ":()=>z(I(2n),1),e:()=>D,"∞":()=>1/0,"-∞":()=>-1/0,true:()=>!0,false:()=>!1},Ot={abs:t=>_(t)?z(I(N(t.c.n),t.c.d),t.pi,t.e,t.root):Math.abs(Z(t)),floor:xt,ceil:It,sqrt:t=>ft(t,W(1,2)),ln:ot(yt),loglog:ot(t=>yt(yt(t))),logloglog:ot(t=>yt(yt(yt(t)))),expm1:ot(t=>T(t)?W(0):Math.expm1(Z(t))),sinh:ot(t=>T(t)?W(0):Math.sinh(Z(t))),cosh:ot(t=>T(t)?W(1):Math.cosh(Z(t))),tanh:ot(t=>T(t)?W(0):Math.tanh(Z(t))),arcsinh:ot(t=>T(t)?W(0):Math.asinh(Z(t))),arccosh:ot(t=>{const n=Z(t);if(n<1)throw new d("not a real number");return 1===n?W(0):Math.acosh(n)}),arctanh:ot(t=>{const n=Z(t);if(Math.abs(n)>=1)throw new d("undefined");return T(t)?W(0):Math.atanh(n)}),"!":ot(function(t){const n=G(t)??("number"==typeof t&&Number.isInteger(t)?BigInt(t):null);if(null!==n){if(n<0n)throw new d("factorial of a negative number");if(n>BigInt(M.factorial))throw new p("too large to calculate");let t=1n;for(let e=2n;e<=n;e++)t*=e;return z(I(t))}const e=Z(t);if(e<0&&Number.isInteger(e))throw new d("factorial of a negative number");return H(Nt(e+1),e)}),neg:st,pm:t=>J([t,st(t)],"pm"),"\\not":t=>!K(t)};for(const t of["sin","cos","tan","csc","sec","cot"])Ot[t]=ot(n=>Mt(t,n));for(const t of["arcsin","arccos","arctan"])Ot[t]=ot(n=>wt(t,n));const St={"+":at,"-":ut,"*":ct,"/":lt,"^":ft,"±":(t,n)=>J([at(t,n),ut(t,n)],"pm"),mod:it(function(t,n){if(T(n))throw new d("division by zero");if(C(t)&&C(n))return z(F(t.c,S(A(n.c,I(j(O(t.c,n.c)))))));const e=Z(t),r=Z(n);return H((e%r+r)%r)}),log:it(function(t,n){if(_(t)&&X(t,D))return yt(n);const e=Z(t),r=Z(n);if(e<=0||1===e)throw new d("not a valid base");if(r<=0)throw new d(0===r?"log 0 is undefined":"not a real number");const o=Math.log(r)/Math.log(e);if(C(t)&&C(n))for(let e=1n;e<=12n;e++){const r=Math.round(o*Number(e));if(Math.abs(o*Number(e)-r)>1e-9)continue;const i=et(t,BigInt(r)),a=et(n,e);if(i&&a&&X(i,a))return z(I(BigInt(r),e))}return o}),root:it((t,n)=>ft(n,lt(W(1),t))),atan2:(t,n)=>Math.atan2(Z(t),Z(n)),round:$t,fixed:function(t,n){const e=Number(vt(n,"fixed"));if(e<0)throw new d("fixed needs 0 or more decimal places");const r=$t(t,n);if(C(r)){const t=r.c.n*10n**BigInt(e)/r.c.d,n=(t<0n?-t:t).toString().padStart(e+1,"0");return L(`${t<0n?"-":""}${n.slice(0,n.length-e)}${e?"."+n.slice(-e):""}`)}return L(Number(Z(r)).toFixed(e))},perm:function(t,n){const e=vt(t,"permutations"),r=vt(n,"permutations");if(r<0n||r>e)throw new d("undefined");if(r>BigInt(M.terms))throw new p("too large to calculate");let o=1n;for(let t=e-r+1n;t<=e;t++)o*=t;return z(I(o))},comb:function(t,n){const e=vt(t,"combinations");let r=vt(n,"combinations");if(r<0n||r>e)throw new d("undefined");if(e-r<r&&(r=e-r),r>BigInt(M.terms))throw new p("too large to calculate");let o=1n;for(let t=1n;t<=r;t++)o=o*(e-r+t)/t;return z(I(o))},"=":(t,n)=>mt(t,n),"===":(t,n)=>mt(t,n),"≠":(t,n)=>!mt(t,n),"≠=":(t,n)=>!mt(t,n),"≈":(t,n)=>Math.abs(Z(t)-Z(n))<=1e-9*Math.max(1,Math.abs(Z(t)),Math.abs(Z(n))),"<":(t,n)=>ht(t,n)<0,">":(t,n)=>ht(t,n)>0,"≤":(t,n)=>ht(t,n)<=0,"≥":(t,n)=>ht(t,n)>=0,"&":(t,n)=>K(t)&&K(n),"|":(t,n)=>K(t)||K(n),"\\xor":(t,n)=>K(t)!==K(n),"\\nor":(t,n)=>!(K(t)||K(n)),"\\nand":(t,n)=>!(K(t)&&K(n))},Pt={sum:t=>t.reduce((t,n)=>at(t,n),W(0)),prod:t=>t.reduce((t,n)=>ct(t,n),W(1)),max:t=>t.reduce((t,n)=>ht(n,t)>0?n:t),min:t=>t.reduce((t,n)=>ht(n,t)<0?n:t),mean:t=>lt(Pt.sum(t),W(t.length)),gcd:t=>z(I(t.map(t=>vt(t,"gcd")).reduce(x)))},jt=["∈","∉","∪","∩","pmod","random","(]","[)"];function kt(e,o){if(++w>M.steps)throw new p("too much to work out");switch(e.type){case"number":return z(E(e.value));case"string":return L(e.value.slice(1,-1));case"symbol":return Et(e.value,o)}const i=n(e);if(i)return kt(i,o);const{op:a,args:s}=e,u=t=>kt(t,o);if("?:"===a)return K(u(s[0]))?u(s[1]):u(s[2]);if("_"===a){if(s.every(t=>"op"!==t.type))return Et(`${s[0].value}_${s[1].value}`,o);throw new p("subscript")}if("der"===a)return function(t,n){const[e,r]=t.args,o=Wt(r);if(!o||!Object.prototype.hasOwnProperty.call(n,o))throw new p(`a derivative needs a value for ${o||"its variable"}`);const i=Z(n[o]),a=zt(e,o,n);if(!Number.isFinite(a(i)))throw new d("undefined");const s=1e-6*Math.max(1,Math.abs(i)),u=(a(i+s)-a(i))/s,c=(a(i)-a(i-s))/s;if(!Number.isFinite(u)||!Number.isFinite(c)||Math.abs(u-c)>.001*Math.max(1,Math.abs(u)))throw new d("not differentiable here");let l=.1*Math.max(1,Math.abs(i));const f=1.4,h=[[(a(i+l)-a(i-l))/(2*l)]];let m=h[0][0],g=1/0;for(let t=1;t<12;t++){l/=f,h[t]=[(a(i+l)-a(i-l))/(2*l)];let n=f*f;for(let e=1;e<=t;e++){h[t][e]=(h[t][e-1]*n-h[t-1][e-1])/(n-1),n*=f*f;const r=Math.max(Math.abs(h[t][e]-h[t][e-1]),Math.abs(h[t][e]-h[t-1][e-1]));r<=g&&(g=r,m=h[t][e])}if(Math.abs(h[t][t]-h[t-1][t-1])>=2*g)break}if(!Number.isFinite(m))throw new d("not differentiable here");return Ct(m,g)}(e,o);if("int"===a)return function(t,n){const[e,o,i,a]=t,s=t=>t&&"symbol"===t.type&&/^[a-zA-Zʹ-Ͽ]$/.test(t.value);let u,c,l;if(4===t.length)[u,c,l]=[Wt(o),i,a];else{if(3!==t.length||s(o))throw new p("an integral needs limits to be calculated");[u,c,l]=[r(e)||"x",o,i]}let f=Z(kt(c,n)),h=Z(kt(l,n));if(f===h)return W(0);let m=1;f>h&&([f,h]=[h,f],m=-1);const g=zt(e,u,n),{value:b,error:d}=qt(g,f,h);return Ct(m*b,d)}(s,o);if("lim"===a)return function(t,n){const[e,o,i,a]=t;let s,u,c=0;if(2===t.length&&"op"===o.type&&"→"===o.op)[s,u]=[Wt(o.args[0]),o.args[1]];else if(2===t.length)[s,u]=[r(e),o];else{if(!(t.length>=3))throw new p("a limit needs a point");[s,u]=[Wt(o),i]}if(4===t.length){const t="op"===a.type?"":String(a.value).toLowerCase();c=t.startsWith("r")||"+"===t?1:-1}if(!s)throw new p("a limit needs a variable");const l=kt(u,n),f=Z(l),h=zt(e,s,n);let m,g;if(Number.isFinite(f))if(c)({value:m,error:g}=_t(t=>h(f+c*t*Math.max(1,Math.abs(f)))));else{const t=_t(t=>h(f+t*Math.max(1,Math.abs(f)))),r=_t(t=>h(f-t*Math.max(1,Math.abs(f))));if(t.value===r.value)({value:m,error:g}=t);else{if(!(Number.isFinite(t.value)&&Number.isFinite(r.value)&&Math.abs(t.value-r.value)<=1e-6*Math.max(1,Math.abs(t.value))))throw new d("the limit does not exist");m=(t.value+r.value)/2,g=Math.max(t.error,r.error,Math.abs(t.value-r.value))}try{const t=kt(e,{...n,[s]:l});if(Math.abs(Z(t)-m)<=1e-6*Math.max(1,Math.abs(m)))return t}catch(t){if(!(t instanceof d))throw t}}else({value:m,error:g}=_t(t=>h(Math.sign(f)/t)));return Number.isFinite(m)?Ct(m,g):m}(s,o);if("\\sumidx"===a||"\\prodidx"===a)return function(t,n,e){const[o,i,a]=n;if(n.length<3)throw new p("a sum needs its limits");let s,u=i;"op"===i.type&&"="===i.op&&"symbol"===i.args[0].type?[s,u]=[i.args[0].value,i.args[1]]:s=r(o)||"n";const c=vt(kt(u,e),"a sum"),l=kt(a,e),f=t?at:ct;if(l===1/0){if(!t)throw new p("an infinite product");return function(t,n){const e=[],r=[];let o=0,i=n;for(let a=4;a<=17;a++){const s=2**a;for(;i<n+s;i++){const n=t(i);if(!Number.isFinite(n))throw new d("undefined");o+=n}if(e.push(s),r.push(o),a>=6&&r[r.length-1]===r[r.length-2])return Ct(o,0)}const a=r[r.length-1]-r[r.length-2],s=r[r.length-2]-r[r.length-3];if(Math.abs(a)>=.9*Math.abs(s)&&Math.abs(a)>1e-12)throw new d("the series diverges");const u=e.slice(-7).map(t=>1/t),c=r.slice(-7),l=r.slice(-8,-1),f=(t,n)=>{const e=n.slice();for(let n=1;n<t.length;n++)for(let r=0;r<t.length-n;r++)e[r]=(t[r+n]*e[r]-t[r]*e[r+1])/(t[r+n]-t[r]);return e[0]},h=f(u,c),m=f(e.slice(-8,-1).map(t=>1/t),l);return Ct(h,Math.abs(h-m))}(zt(o,s,e),Number(c))}const h=vt(l,"a sum");if(h-c+1n>BigInt(M.terms))throw new p("too many terms to add one by one");let m=W(t?0:1);for(let t=c;t<=h;t++)m=f(m,kt(o,{...e,[s]:z(I(t))}));return m}("\\sumidx"===a,s,o);if(["()","[]","{}"].includes(a))return J(s.map(u),a);if(jt.includes(a))return function(n,e){const r={};for(const[t,n]of Object.entries(e))"function"!=typeof n&&(r[t]=U(n));try{return Q(function(n,e={}){0===m&&(h=0),m++;try{return g(t(n),e)}finally{m--}}(n,r))}catch(t){throw new p(t.message)}}(e,o);if(a.startsWith("\\:")){const t=o[a.slice(2)];if("function"!=typeof t)throw new p(`no function ${a.slice(2)}`);return Q(t(...s.map(t=>U(u(t)))))}if(Ot[a]&&1===s.length)return Ot[a](u(s[0]));if(St[a]&&2===s.length)return St[a](u(s[0]),u(s[1]));if(Pt[a])return Pt[a](s.map(u));throw new p(`can't calculate '${a}'`)}function Et(t,n){if(Object.prototype.hasOwnProperty.call(n,t))return n[t];if(Object.prototype.hasOwnProperty.call(At,t))return At[t]();throw new p(`no value for '${t}'`)}function zt(t,n,e){return r=>{try{return Z(kt(t,{...e,[n]:r}))}catch(t){if(t instanceof d)return NaN;throw t}}}const Wt=t=>"symbol"===t.type?t.value:null;function qt(t,n,e){if(n===-1/0&&e===1/0){const n=qt(t,-1/0,0),e=qt(t,0,1/0);return{value:n.value+e.value,error:n.error+e.error}}return e===1/0?Dt(e=>t(n+e/(1-e))/((1-e)*(1-e)),0,1):n===-1/0?Dt(n=>t(e-n/(1-n))/((1-n)*(1-n)),0,1):Dt(t,n,e)}function Dt(t,n,e){const r=(e-n)/2;let o=1,i=0,a=NaN,s=NaN,u=0;const c=o=>{const i=Math.PI/2*Math.sinh(Math.abs(o)),a=Math.exp(-2*i),s=2*r*a/(1+a),c=r*(Math.PI/2)*Math.cosh(o)*(4*a)/((1+a)*(1+a));if(0===s||0===c)return 0;const l=o>0?e-s:n+s;if(0!==o&&(l<=n||l>=e))return 0;const f=t(0===o?(n+e)/2:l);if(!Number.isFinite(f)){if(s<1e-6*r)return 0;throw new d("the integral diverges")}return Math.abs(o)>3.5&&(u=Math.max(u,Math.abs(c*f))),c*f};i=c(0);for(let t=o;t<=4;t+=o)i+=c(t)+c(-t);a=o*i;for(let t=1;t<=8;t++){o/=2;for(let t=o;t<=4;t+=2*o)i+=c(t)+c(-t);s=a,a=o*i;const n=Math.max(1,Math.abs(a));if(u>1e-8*n)throw new d("the integral diverges");if(t>=3&&Math.abs(a-s)<=1e-13*n)break}const l=Math.abs(a-s);if(!Number.isFinite(a)||l>1e-6*Math.max(1,Math.abs(a)))throw new d("the integral does not converge");return{value:a,error:l}}function _t(t){const n=[],e=[];for(let r=0;r<30;r++){const o=.1/2**r,i=t(o);Number.isFinite(i)&&(n.push(o),e.push(i))}if(e.length<6)throw new d("undefined");const r=e.slice(1).map((t,n)=>t-e[n]).slice(-6);if(r.every(t=>Math.sign(t)===Math.sign(r[0])&&0!==t)&&Math.abs(r[5])>=.95*Math.abs(r[0])&&Math.abs(e[e.length-1])>10)return{value:Math.sign(r[0])*(1/0),error:0};const o=t=>{const r=n.slice(t,t+8),o=e.slice(t,t+8);for(let t=1;t<r.length;t++)for(let n=0;n<r.length-t;n++)o[n]=(r[n+t]*o[n]-r[n]*o[n+1])/(r[n+t]-r[n]);return o[0]};let i=null;for(let t=0;t+9<=e.length;t++){const n=o(t),e=o(t+1),r=Math.abs(n-e);Number.isFinite(n)&&(!i||r<i.error)&&(i={value:n,error:r})}const a=e[e.length-1],s=Math.abs(a-e[e.length-2]);if(!i||i.error>Math.max(s,1e-6*Math.max(1,Math.abs(a)))){if(s<=1e-6*Math.max(1,Math.abs(a)))return{value:a,error:10*s};throw new d("the limit could not be found")}return i}function Ct(t,n=0){if(!Number.isFinite(t))return t;const e=Math.max(1e-10,4*n)*Math.max(1,Math.abs(t));if(e>1e-6*Math.max(1,Math.abs(t)))return t;if(Math.abs(t)<e)return W(0);const r=[[W(1),1e3],[q,100],[z(B,2),100],[D,100],...[2n,3n,5n,6n,7n].map(t=>[z(B,0,0,{n:2,r:t}),100])];for(const[n,o]of r){const r=t/Z(n),i=Tt(r,o);if(i&&Math.abs(Number(i.n)/Number(i.d)-r)*Z(n)<=e)return tt(z(i),n)}return t}function Tt(t,n){if(!Number.isFinite(t)||Math.abs(t)>1e12)return null;let[e,r,o,i]=[0,1,1,0],a=t;for(let t=0;t<40;t++){const t=Math.floor(a),s=t*r+e,u=t*i+o;if(u>n)break;if([e,r,o,i]=[r,s,i,u],Math.abs(a-t)<1e-15)break;a=1/(a-t)}return i?I(BigInt(r),BigInt(i)):null}function Gt(t,n){if("boolean"==typeof t)return String(t);if(t&&"s"===t.kind)return JSON.stringify(t.text);if(Array.isArray(t)){if("pm"===t.group&&2===t.length&&mt(t[1],st(t[0])))return`±${Jt(t[0],n)}`;const[e,r]={"()":"()","[]":"[]","{}":"{}"}[t.group]||"{}";return e+t.map(t=>Gt(t,n)).join(", ")+r}return"number"==typeof t?Lt(t,n):n.decimal||null!==n.places?function(t,n){if(C(t)&&null===n.places){let e=t.c.d,r=0,o=0;for(;e%2n==0n;)e/=2n,r++;for(;e%5n==0n;)e/=5n,o++;const i=Math.max(r,o);if(1n===e&&i<=n.digits){const e=t.c.n*10n**BigInt(i)/t.c.d,r=e<0n,o=N(e).toString().padStart(i+1,"0"),a=i?`${o.slice(0,-i)}.${o.slice(-i)}`:o;if(o.length<=n.maxDigits)return(r?"-":"")+Rt(a)}}return C(t)&&null!==n.places?Gt($t(t,W(n.places)),{...n,places:null,decimal:!0}):Lt(Z(t),n)}(t,n):function(t,n){const{c:e}=t,r=N(e.n);if(r.toString().length>n.maxDigits||e.d.toString().length>n.maxDigits)return function(t,n){if(!C(t)||1n!==t.c.d)return Lt(Z(t),n);const e=N(t.c.n).toString(),r=BigInt(e.slice(0,n.digits+1)),o=((r+5n)/10n).toString(),i=e.length-1+(o.length>n.digits?1:0),a=Rt(`${o[0]}.${o.slice(1,n.digits)}`);return`${t.c.n<0n?"-":""}${a}*10^(${i})`}(t,n);const o=(t,n)=>1===n?t:`${t}^${n}`,i=[],a=[];t.pi>0&&i.push(o("pi",t.pi));t.pi<0&&a.push(o("pi",-t.pi));t.e>0&&i.push(o("e",t.e));t.e<0&&a.push(o("e",-t.e));t.root&&i.push(2===t.root.n?`sqrt(${t.root.r})`:`root(${t.root.n}, ${t.root.r})`);1n===r&&i.length||i.unshift(r.toString());1n!==e.d&&a.unshift(e.d.toString());const s=t=>t.length>1?`(${t.join("*")})`:t[0],u=a.length?`${s(i)}/${s(a)}`:i.join("*");return(e.n<0n?"-":"")+u}(t,n)}const Jt=(t,n)=>{const e=Gt(t,n);return/^[\d.]+$|^[a-zπ]+$/i.test(e)?e:`(${e})`};function Lt(t,n){if(t===1/0)return"∞";if(t===-1/0)return"-∞";if(Object.is(t,-0)||0===t)return"0";if(null!==n.places&&Math.abs(t)<1e21)return t.toFixed(n.places);const e=Math.abs(t);if(e>=1e15||e<1e-6){const[e,r]=t.toExponential(n.digits-1).split("e");return`${Rt(e)}*10^(${Number(r)})`}return String(Number(t.toPrecision(n.digits)))}const Rt=t=>t.includes(".")?t.replace(/\.?0+$/,""):t;function Xt(t,n={},r={}){const i="string"==typeof t?e(t):o(t),a={};for(const[t,e]of Object.entries(n))a[t]=Q(e);let s;0===y&&(w=0),y++;try{s=kt(i,a)}finally{y--}const u={decimal:!1,places:null,digits:12,maxDigits:50,...r};void 0===u.places&&(u.places=null);const c=t=>Array.isArray(t)?t.every(c):"number"!=typeof t;return{value:U(s),text:Gt(s,u),exact:c(s)}}function Zt(t,n={}){let e=t.trim();const r={},o=/^(~|≈)\s*(\d+)?/.exec(e);o&&(r.decimal=!0,void 0!==o[2]&&(r.places=Number(o[2])),e=e.slice(o[0].length)),/\d\.\d|\.\d/.test(e)&&(r.decimal=!0);try{const{text:t}=Xt(e,n,r);return t.startsWith('"')||/^\d+(\.\d+)?$/.test(t)?t:`(${t})`}catch(t){if(t instanceof d)return'"undefined"';if(t instanceof p)return`(${e})`;throw t}}i(Zt);for(const t of[M,gt,At,Ot,St,Pt])Object.setPrototypeOf(t,null);export{Xt as a,Zt as c};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/* Inline Math 0.1.0 — MIT licence; MathZetta not included: map mathzetta, mathzetta/speech and mathzetta/calculate with an import map */
|
|
2
|
-
import{GREEK as t,isCustomFunction as e,unaryNeedsBrackets as r,isMinusOneTimes as s,bracketedSides as i,isImplicitProduct as n,customName as l,needsBrackets as a,derivativeOrder as h,bracketOp as o,precedenceOf as c,isVariable as u,firstLeaf as d,firstVariable as p,walk as f,toPostfix as m,operator as g,VARIADIC as b,parseTree as $,fromPostfix as v}from"mathzetta";import{toSpeech as x}from"mathzetta/speech";const y={"(":{fill:"M0.92,0 C0.1,0.2 0.1,0.8 0.92,1 L1,0.975 C0.48,0.75 0.48,0.25 1,0.025 Z"},")":{fill:"M0.08,0 C0.9,0.2 0.9,0.8 0.08,1 L0,0.975 C0.52,0.75 0.52,0.25 0,0.025 Z"},"{":{fill:"M1,0 C0.45,0 0.5,0.05 0.5,0.2 L0.5,0.38 C0.5,0.46 0.35,0.49 0.05,0.5 C0.35,0.51 0.5,0.54 0.5,0.62 L0.5,0.8 C0.5,0.95 0.45,1 1,1 L1,0.985 C0.68,0.985 0.64,0.95 0.64,0.8 L0.64,0.62 C0.64,0.53 0.55,0.505 0.3,0.5 C0.55,0.495 0.64,0.47 0.64,0.38 L0.64,0.2 C0.64,0.05 0.68,0.015 1,0.015 Z"},"}":{fill:"M0,0 C0.55,0 0.5,0.05 0.5,0.2 L0.5,0.38 C0.5,0.46 0.65,0.49 0.95,0.5 C0.65,0.51 0.5,0.54 0.5,0.62 L0.5,0.8 C0.5,0.95 0.55,1 0,1 L0,0.985 C0.32,0.985 0.36,0.95 0.36,0.8 L0.36,0.62 C0.36,0.53 0.45,0.505 0.7,0.5 C0.45,0.495 0.36,0.47 0.36,0.38 L0.36,0.2 C0.36,0.05 0.32,0.015 0,0.015 Z"},sqrt:{stroke:"M0,0.62 L0.18,0.55 L0.45,0.97 L0.98,0.015"},int:{stroke:"M0.95,0.09 C0.9,0.01 0.72,0 0.66,0.12 C0.6,0.25 0.42,0.75 0.34,0.88 C0.28,0.99 0.1,0.99 0.05,0.91"},sum:{fill:"M0.04,0 L0.94,0 L0.98,0.24 L0.94,0.24 C0.9,0.1 0.8,0.07 0.62,0.07 L0.24,0.07 L0.58,0.5 L0.2,0.93 L0.64,0.93 C0.82,0.93 0.92,0.9 0.95,0.76 L0.99,0.76 L0.94,1 L0.02,1 L0.47,0.47 Z"},prod:{fill:"M0,0 L1,0 L1,0.04 L0.88,0.05 L0.88,0.95 L1,0.96 L1,1 L0.62,1 L0.62,0.96 L0.74,0.95 L0.74,0.06 L0.26,0.06 L0.26,0.95 L0.38,0.96 L0.38,1 L0,1 L0,0.96 L0.12,0.95 L0.12,0.05 L0,0.04 Z"}};function w(t,e,r=""){const s=y[t];return`<svg class="${e}" viewBox="0 0 1 1" preserveAspectRatio="none" aria-hidden="true"${r?` style="${r}"`:""}>${s.fill?`<path d="${s.fill}" fill="currentColor"/>`:`<path d="${s.stroke}" fill="none" stroke="currentColor" vector-effect="non-scaling-stroke"/>`}</svg>`}const L=.8,M=.2,C=.25,k=.7,z="−",P={"+":"add","-":"sub","*":"mul","/":"frac","^":"pow",_:"subscript",neg:"neg",pm:"pm","!":"factorial","=":"eq","===":"eq","≠":"neq","≠=":"neq","<":"lt",">":"gt","≤":"le","≥":"ge","≈":"approx","≡":"equiv","∈":"in","∉":"notin","∪":"union","∩":"intersect","→":"to","±":"pm","&":"and","|":"or","\\not":"not","\\xor":"xor","\\nand":"nand","\\nor":"nor","?:":"cases","()":"tuple","[]":"list","{}":"set","(]":"interval","[)":"interval","\\sumidx":"sum","\\prodidx":"prod",mod:"mod",pmod:"pmod"},j={"=":"=","===":"=","≠":"≠","≠=":"≠","<":"<",">":">","≤":"≤","≥":"≥","∈":"∈","∉":"∉","→":"→","≈":"≈","≡":"≡","&":"∧","|":"∨","\\xor":"⊕","\\nand":"↑","\\nor":"↓"},A={"±":"±","∪":"∪","∩":"∩",mod:"mod"},Z=["sin","cos","tan","csc","sec","cot","sinh","cosh","tanh"],q={arcsin:"sin",arccos:"cos",arctan:"tan",arcsinh:"sinh",arccosh:"cosh",arctanh:"tanh"},B=[...Z,...Object.keys(q),"ln"],F={atan2:"atan2",max:"max",min:"min",gcd:"gcd",mean:"mean",round:"round",fixed:"fixed",expm1:"expm1",random:"random"},O={"()":["(",")"],"[]":["[","]"],"{}":["{","}"],"(]":["(","]"],"[)":["[",")"]},W={"\\partial":"∂","\\nabla":"∇","\\ell":"ℓ","\\infty":"∞","\\emptyset":"∅"},S={vec:"→",hat:"ˆ",widehat:"ˆ",tilde:"˜",dot:"˙",ddot:"¨"},E=["boxed","overline","bar","underline","cancel",...Object.keys(S)],_={prefix:"mv",display:!0,fnParens:"auto",trigPowers:!0,inverseTrig:"arc",derivativeBrackets:"[",scriptFractions:"slash",cases:!0,label:!0,attributes:null,style:null},I=t=>String(t).replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,"""),N=t=>+t.toFixed(3)+"em",T=(t,e=L,r=M)=>({html:t,h:e,d:r});function D(...t){const e=t.flat().filter(Boolean);return{html:e.map(t=>t.html).join(""),h:Math.max(L,...e.map(t=>t.h)),d:Math.max(M,...e.map(t=>t.d))}}function R(t,e={}){const r=new G({..._,...e}),s=r.render(t,{level:0}),i=`${r.p}${r.o.display?` ${r.p}-display`:""}`,n=function(t,e){if(!1===e||null===e)return null;if("string"==typeof e)return e;try{return"function"==typeof e?e(t):x(t)}catch{return null}}(t,r.o.label),l=null===n?s.html:s.html.replace(/^<span /,'<span aria-hidden="true" ');return{html:`<span class="${i}"${null===n?"":` role="math" aria-label="${I(n)}"`}>${l}</span>`,h:s.h,d:s.d}}class G{constructor(t){this.o=t,this.p=t.prefix}el(t,e,r="",s=""){return`<span class="${t.split(" ").map(t=>`${this.p}-${t}`).join(" ")}"${r?` style="${r}"`:""}${s}>${e}</span>`}text(t,e){const r=T(this.el(t,I(e)));return r.leaf={kind:t,content:I(e)},r}bin(t){return this.text("bin",t)}rel(t){return this.text("rel",t)}punct(t){return this.text("punct",t)}word(t){return this.text("word",t)}wrap(t,e,r){let s="";void 0!==t.id&&(s+=` data-node="${t.id}"`),"op"===t.type&&(s+=` data-op="${I(t.op)}"`);const i=this.o.attributes&&this.o.attributes(t)||{};for(const[t,e]of Object.entries(i))"class"!==t&&"style"!==t&&(s+=` ${t}="${I(e)}"`);const n=[i.style,this.o.style&&this.o.style(t)].filter(Boolean).join(";"),l=(r.leaf?["n",...e,r.leaf.kind]:["n",...e]).map(t=>`${this.p}-${t}`).concat(i.class?[i.class]:[]).join(" "),a=r.leaf?r.leaf.content:r.html;return{html:`<span class="${l}"${n?` style="${I(n)}"`:""}${s}>${a}</span>`,h:r.h,d:r.d}}render(t,e){return"number"===t.type?this.number(t):"string"===t.type?this.wrap(t,["text"],this.text("text",t.value.replace(/^["'`]|["'`]$/g,""))):"symbol"===t.type?this.wrap(t,["symbol"],this.symbol(t.value)):this.operation(t,e)}number(t){return this.wrap(t,["number"],this.text("num",t.value.replace(/^-/,z)))}symbol(e){return t[e]&&(e=t[e]),W[e]?this.text("ord",W[e]):"\\+"===e||"\\-"===e?this.text("ord",e[1]):"-∞"===e?this.text("ord","−∞"):/^[A-Za-z]$/.test(e)||/^[α-ω]$/.test(e)?this.text("var",e):/^[A-Za-z]′+$/.test(e)?T(this.el("var",I(e[0]))+this.el("prime",I(e.slice(1)))):/^Δ[A-Za-z]$/.test(e)?T(this.el("ord","Δ")+this.el("var",e[1])):e.endsWith("⁻¹")?this.script(this.symbol(e.slice(0,-2)),this.text("num","−1"),{level:0}):/^\\[A-Za-z]+$/.test(e)?this.text("name",e.slice(1)):/^[A-Za-z]{2,}$/.test(e)?this.text("name",e):this.text("ord",e)}operation(t,i){const{op:n,args:l}=t,[h,o]=l,c=(t,e={})=>this.render(t,{...i,...e,forceParens:e.forceParens||!1,before:e.before||!1}),u=P[n]??(/^[a-z0-9]+$/i.test(n)?n:"other"),d=e=>this.wrap(t,["op",`op-${u}`],e),p=(e,r)=>a(t,e,r)&&"/"!==e.op?this.fence(c(e)):c(e);if(B.includes(n)||"log"===n)return d(this.named(t,i));if(F[n])return d(D(this.word(F[n]),this.fence(this.list(l,i))));if(e(n))return d(this.custom(t,i));if(O[n])return d(this.fence(this.list(l,i),...O[n]));if(j[n]&&2===l.length)return d(D(p(h,"left"),this.rel(j[n]),p(o,"right")));if(A[n]&&2===l.length)return d(D(p(h,"left"),this.bin(A[n]),p(o,"right")));switch(n){case"+":return s(o)?d(D(p(h,"left"),this.bin(z),this.wrap(o,["op","op-mul"],this.render(o.args[1],i)))):"number"===o.type&&o.value.startsWith("-")?d(D(p(h,"left"),this.bin(z),this.wrap(o,["number"],this.text("num",o.value.slice(1))))):d(D(p(h,"left"),this.bin("+"),this.signed(o,p(o,"right"))));case"-":return d(D(p(h,"left"),this.bin(z),this.signed(o,p(o,"right"))));case"*":return d(this.product(t,i));case"/":return d(this.fraction(t,i));case"^":return d(this.power(t,i));case"_":return d(this.script(c(h,{forceParens:!0}),null,i,c(o,{level:i.level+1})));case"neg":return d(D(this.text("sign",z),r(n,h)?this.fence(c(h)):c(h,{before:i.before})));case"pm":return d(D(this.text("sign","±"),r(n,h)?this.fence(c(h)):c(h)));case"!":return d(D(r(n,h)?this.fence(c(h)):c(h,{forceParens:!0}),this.text("ord","!")));case"\\not":return d(D(this.text("sign","¬"),r(n,h)?this.fence(c(h)):c(h)));case"pmod":return d(D(c(h),this.fence(D(this.word("mod"),this.text("space",""),c(o)))));case"sqrt":return d(this.radical(c(h)));case"root":return d(this.radical(c(o),this.render(h,{level:i.level+2})));case"abs":return d(this.fence(c(h),"|","|"));case"floor":return d(this.fence(c(h),"⌊","⌋"));case"ceil":return d(this.fence(c(h),"⌈","⌉"));case"loglog":return d(D(this.word("ln"),this.fence(D(this.word("ln"),this.fence(c(h))))));case"logloglog":return d(D(this.word("ln"),this.fence(D(this.word("ln"),this.fence(D(this.word("ln"),this.fence(c(h))))))));case"perm":return d(this.script(this.script(T(""),this.render(h,{level:i.level+1}),i),null,i,this.render(o,{level:i.level+1}),this.word("P")));case"comb":return d(this.fence(this.stack(c(h),c(o),!1)));case"?:":return d(this.o.cases?this.cases(t,i):D(c(h),this.bin("?"),c(o),this.bin(":"),c(l[2])));case"sum":return d(D(l.map((t,e)=>e?[this.bin("+"),c(t)]:[c(t)]).flat()));case"prod":return d(D(l.map((t,e)=>e?[this.bin("·"),c(t)]:[c(t)]).flat()));case"der":return d(this.derivative(t,i));case"int":return d(this.integral(l,i));case"lim":return d(this.limit(l,i));case"\\sumidx":return d(this.bigOperator("sum",l,i));case"\\prodidx":return d(this.bigOperator("prod",l,i))}throw new Error(`Inline Math cannot draw '${n}'`)}signed(t,e){return("number"===t.type?t.value.startsWith("-"):"neg"===t.op||"pm"===t.op)&&!e.fenced?this.fence(e):e}list(t,e){return D(t.map((t,r)=>r?[this.punct(","),this.render(t,e)]:[this.render(t,e)]).flat())}product(t,r){const[l,a]=t.args;if(s(t))return D(this.text("sign",z),this.render(a,r));const h=i(t),o=n(l,a,h),c=function(t){for(;"op"===t.type;){if(B.includes(t.op)||"log"===t.op||F[t.op]||e(t.op))return!0;if("^"!==t.op&&"*"!==t.op)return!1;t=t.args[0]}return!1}(a),u=h.left?this.fence(this.render(l,r)):this.render(l,{...r,before:o&&!c}),d=h.right?this.fence(this.render(a,r)):this.render(a,{...r,before:r.before});return D(u,o?T(this.el(c?"fnspace":"times","")):this.bin("·"),d)}named(t,e,r=null){const{op:s,args:i}=t,n="log"===s?i[1]:i[0];let l;l=q[s]&&"power"===this.o.inverseTrig?this.script(this.word(q[s]),this.text("num","−1"),e):this.word(s),r&&(l=this.script(l,r,e)),"log"===s&&(l=this.script(l,null,e,this.render(i[0],{level:e.level+1})));const a="auto"===this.o.fnParens&&!e.forceParens&&!e.before&&H(n),h=this.render(n,{...e,forceParens:!1,before:!1});return D(l,a?D(T(this.el("fnspace","")),h):this.fence(h))}custom(t,e){const r=l(t.op),s=t.args;if(E.includes(r)&&1===s.length)return this.decorate(r,this.render(s[0],e));return D(/^[A-Za-z]′*(⁻¹)?$/.test(r)?this.symbol(r):this.word(r),T(this.el("callgap","")),this.fence(this.list(s,e)))}decorate(t,e){switch(t){case"boxed":return T(this.el("boxed",e.html),e.h+.22,e.d+.22);case"cancel":return T(this.el("cancel",e.html),e.h,e.d);case"underline":return T(this.el("underline",e.html),e.h,e.d+.12);case"overline":case"bar":return T(this.el("over",e.html),e.h+.14,e.d);default:return T(this.el("accent",this.el("accent-mark",S[t])+e.html),e.h+.3,e.d)}}fraction(t,e){const[r,s]=t.args;if(e.level>0&&"slash"===this.o.scriptFractions&&H(r,!0)&&H(s,!0)){const t=t=>"op"!==t.type||H(t)?this.render(t,e):this.fence(this.render(t,e));return D(t(r),this.text("ord","/"),t(s))}const i=e.level>0||e.inFraction||!this.o.display?.8:1,n={...e,inFraction:!0,forceParens:!1,before:!1};return this.stack(this.render(r,n),this.render(s,n),!0,i)}stack(t,e,r=!0,s=1){const i=t=>1===s?t.html:this.el("scaled",t.html,`font-size:${N(s)}`),n=r?.06:0,l=C+n/2+.1+Math.max(M,s*t.d),a=this.el("frac"+(r?"":" frac-nobar"),this.el("numer",i(t))+this.el("denom",i(e)),`vertical-align:${N(l)}`);return T(a,l+Math.max(L,s*t.h),Math.max(L,s*e.h)+Math.max(M,s*e.d)+.1+n/2-C)}power(t,e){const[r,s]=t.args,i={...e,level:e.level+1,forceParens:!1,before:!1,inFraction:!1},n=()=>this.render(s,i);if(this.o.trigPowers&&Z.includes(r.op)&&K(s))return this.wrap(r,["op",`op-${r.op}`],this.named(r,e,n()));if("_"===r.op){const t=this.render(r.args[1],i);return this.wrap(r,["op","op-subscript"],this.script(this.render(r.args[0],{...e,forceParens:!0}),n(),e,t))}const l=a(t,r,"left")||"number"===r.type&&r.value.startsWith("-")||"/"===r.op||B.includes(r.op)?this.fence(this.render(r,e)):this.render(r,{...e,forceParens:!0});return this.script(l,n(),e)}script(t,e,r,s=null,i=null){const n=r.level>0?.8:k,l=i?D(t,i):t;let a=e?Math.max(.42,t.h-.38,n*e.d+.12):0,h=s?Math.max(.2,t.d-.05,n*s.h-.45):0;if(e&&s){const t=.1-(a-n*e.d-(n*s.h-h));t>0&&(h+=t)}const o=t=>this.el("script",t.html,`font-size:${N(n)}`);if(e&&!s)return T(t.html+this.el("sup",e.html,`font-size:${N(n)};vertical-align:${N(a/n)}`),Math.max(l.h,a+n*e.h),Math.max(l.d,n*e.d-a));if(s&&!e)return T(l.html+this.el("sub",s.html,`font-size:${N(n)};vertical-align:${N(-h/n)}`),Math.max(l.h,n*s.h-h),Math.max(l.d,h+n*s.d));const c=a+n*e.h,u=h+n*s.d,d=this.el("subsup",o(e)+o(s),`vertical-align:${N(a)};height:${N(c+u)}`);return T(l.html+d,Math.max(l.h,c),Math.max(l.d,u))}radical(t,e=null){const r=Math.max(t.h,L)+.1+.06,s=Math.max(t.d,M),i=r+s,n=w("sqrt",`${this.p}-hook`,`height:${N(i)};width:${N(.5+.06*(i-1))};vertical-align:${N(-s)}`);let l="";if(e){const t=.8*k;l=this.el("rootindex",e.html,`font-size:${N(t)};vertical-align:${N((.55*i-s)/t)}`)}return T(this.el("sqrt",l+n+this.el("radicand",t.html)),r,s)}fence(t,e="(",r=")"){const s=Math.max(t.h,L)+Math.max(t.d,M),i=s>1.25,n=i?.1:0,l=(t,e)=>{if(!t)return{html:"",w:0};const r={"(":.26,")":.26,"{":.36,"}":.36}[t];if(r){const n=r+(i?Math.min(.2,.05*(s-1)):0);return{html:w(t,`${this.p}-delim ${this.p}-delim-${e}`,`width:${N(n)}`),w:n+.1}}const n={"[":"lbrack","]":"rbrack","|":"vert","⌊":"lfloor","⌋":"rfloor","⌈":"lceil","⌉":"rceil"}[t];return{html:this.el(`delim ${n} delim-${e}`,""),w:"|"===t?.18:.3}},a=l(e,"l"),h=l(r,"r"),o=`padding:${N(n)} ${N(h.w)} ${N(n)} ${N(a.w)}`,c=T(this.el("fence",a.html+t.html+h.html,o),Math.max(t.h,L)+n,Math.max(t.d,M)+n);return c.fenced=!0,c}derivative(t,e){const{n:r,body:s,by:i,variable:n}=h(t),l={...e,level:e.level+1},a=()=>this.text("d","d"),u=()=>r>1?this.render({type:"number",value:String(r)},l):null,d={...e,inFraction:!0},p=D(a(),u()?this.script(this.render(i,d),u(),d):this.render(i,d)),f=t=>D(u()?this.script(a(),u(),d):a(),t||[]),m=e.level>0||e.inFraction||!this.o.display?.8:1;if(n)return this.stack(f(this.render(s,d)),p,!0,m);const g=o(s)&&c(o(s))<100,[b,$]="("===this.o.derivativeBrackets?["(",")"]:["[","]"],v=g?this.fence(this.render(s,e),b,$):this.render(s,e);return D(this.stack(f(),p,!0,m),v)}integral(t,e){const[r,s,i,n]=t,l=t=>this.render(t,e),a=t=>t?this.render(t,{...e,level:e.level+1}):null,h=()=>this.text("var",p(r)||"x");let o,c=null,d=null;switch(t.length){case 1:o=h();break;case 2:u(s)?o=l(s):(o=h(),c=a(s));break;case 3:u(s)?(o=l(s),c=a(i)):(o=h(),c=a(s),d=a(i));break;default:o=l(s),c=a(i),d=a(n)}const f=l(r),m=T(this.el("dx",this.el("d","d")+o.html),o.h,o.d);return D(this.bigSign("int",f,c,d,e),f,m)}bigSign(t,e,r,s,i){const n=!this.o.display||i.level>0,l=Math.max(n?.6:.95,Math.max(e.h-C,e.d+C)+.12),a=w(t,`${this.p}-bigsign ${this.p}-${t}sign`,`height:${N(2*l)};width:${N(n?.38:.5)};vertical-align:${N(C-l)}`);if(!r&&!s)return T(a,C+l,l-C);const h=k,o=s||T(""),c=r||T(""),u=C+l-h*o.h;c.d;const d=this.el("limits",this.el("script",o.html,`font-size:${N(h)}`)+this.el("script lower",c.html,`font-size:${N(h)}`),`vertical-align:${N(u)};height:${N(2*l)}`);return T(a+d,C+l,l-C)}limit(t,e){const[r,s,i,n]=t,l={...e,level:e.level+1},a=t=>this.render(t,l),h=()=>this.rel("→");let o;switch(t.length){case 1:return D(this.word("lim"),T(this.el("fnspace","")),this.render(r,e));case 2:{const t=p(r),e="number"===s.type||"symbol"===s.type&&s.value.includes("∞");o=t&&e?D(this.text("var",t),h(),a(s)):a(s);break}case 3:o=D(a(s),h(),a(i));break;default:{const t=d(n).toLowerCase().startsWith("r")?"+":z;o=D(a(s),h(),this.script(a(i),this.wrap(n,["symbol"],this.text("ord",t)),l))}}return D(this.under(this.word("lim"),o,e),this.render(r,e))}under(t,e,r){return!this.o.display||r.level>0?this.script(t,null,r,e):T(this.el("under",t.html+this.el("script",e.html,`font-size:${N(.7)}`)),t.h,Math.max(t.d,M)+.05+.7*(e.h+e.d))}bigOperator(t,e,r){const[s,i,n]=e,l={...r,level:r.level+1},a=i?this.render(i,l):null,h=n?this.render(n,l):null,o=this.render(s,r);if(!this.o.display||r.level>0){const e=.55,s=w(t,`${this.p}-bigsign`,`height:${N(2*e)};width:${N(.8)};vertical-align:${N(C-e)}`);return D(this.script(T(s,C+e,e-C),h,r,a),o)}const c=.68,u=k,d=w(t,`${this.p}-bigsign`,`height:${N(1.36)};width:${N("sum"===t?1:1.05)}`),p=h?1.01+u*h.d:C-c,f=t=>this.el("script",t.html,`font-size:${N(u)}`),m=this.el("bigop",(h?f(h):"")+d+(a?f(a):""),`vertical-align:${N(p)}`);return D(T(m,.93+(h?.08+u*(h.h+h.d):0),c-C+(a?.08+u*(a.h+a.d):0)),o)}cases(t,e){const r=[];let s=t;for(;"op"===s.type&&"?:"===s.op;)r.push([this.render(s.args[1],e),D(this.word("if"),this.text("space",""),this.render(s.args[0],e))]),s=s.args[2];r.push([this.render(s,e),this.word("otherwise")]);const i=r.map(([t,e])=>({h:Math.max(t.h,e.h),d:Math.max(t.d,e.d)})),n=i.reduce((t,e)=>t+e.h+e.d,0)+.25*(r.length-1),l=C+n/2-i[0].h,a=r.map(([t,e])=>this.el("case-value",t.html)+this.el("case-cond",e.html)).join(""),h=T(this.el("cases",a,`vertical-align:${N(l)}`),C+n/2,n/2-C);return this.fence(h,"{","")}}function H(t,e=!1){return"number"===t.type?!t.value.startsWith("-")||e:"symbol"===t.type||"op"===t.type&&("abs"===t.op?!e:!e||"neg"!==t.op&&"^"!==t.op?"*"===t.op&&!s(t)&&t.args.every(t=>"number"===t.type&&!t.value.startsWith("-")||J(t)||"*"===t.op&&H(t,e)):H(t.args[0],!0)&&("neg"===t.op||H(t.args[1],!0)))}const J=e=>"symbol"===e.type&&(1===e.value.length||/^[α-ωΑ-Ω]$/.test(e.value)||Boolean(t[e.value])),K=t=>"number"===t.type&&/^[1-9]\d*$/.test(t.value)&&Number(t.value)<10;const Q=t=>m(t).join(" ");function U(t,e){const r=new Set;V(t,e,r);const s=[];return f(t,t=>{r.has(t)&&s.push(t)}),s}function V(t,e,r){if(null!=e)if(Array.isArray(e))e.forEach(e=>V(t,e,r));else if("number"!=typeof e)if("function"!=typeof e){if("string"==typeof e){const s=Q($(e));return void f(t,t=>{Q(t)===s&&r.add(t)})}if(e.path){const s=X(t,e.path);return void(s&&r.add(s))}if(e.type){const s=Q(e);f(t,t=>{t!==e&&Q(t)!==s||r.add(t)})}}else f(t,(t,s)=>{e(t,s)&&r.add(t)});else f(t,t=>{t.id===e&&r.add(t)})}function X(t,e){let r=t;for(const t of e){if("op"!==r.type||!r.args[t])return null;r=r.args[t]}return r}function Y(t,e){const r=[],s=t=>{if(t.id===e)return!0;if("op"!==t.type)return!1;for(let e=0;e<t.args.length;e++){if(r.push(e),s(t.args[e]))return!0;r.pop()}return!1};return s(t)?r:null}function tt(t){let e=0;const r=t=>{"op"===t.type&&(t.args.forEach(r),g(t.op)?.arity===b&&e++),t.id=e++};return r(t),t}function et(t,e={}){const{blocks:r}=e;if("string"==typeof t)return $(t,r?{blocks:t=>r(t,e.scope)}:{});if(Array.isArray(t))return v(t);if(t&&"object"==typeof t&&t.type)return void 0===t.id?tt(structuredClone(t)):t;throw new Error("Inline Math needs an expression, standard postfix or a tree")}function rt(t,e={}){const r=et(t,e);return R(r,st(r,e)).html}function st(t,e){const{colors:r,highlight:s,scope:i,blocks:n,...l}=e,a=new Map;for(const[e,s]of function(t){return t?Array.isArray(t)?t:Object.entries(t).map(([t,e])=>[/^\d+$/.test(t)?Number(t):t,e]):[]}(r))if(it(s))for(const r of U(t,e))a.set(r,`color:${s}`);const h=new Set(void 0===s?[]:U(t,s));if(!a.size&&!h.size)return l;const o=l.prefix||"mv";return{...l,style:t=>[a.get(t),l.style&&l.style(t)].filter(Boolean).join(";"),attributes:t=>{const e={...l.attributes?l.attributes(t):{}};return h.has(t)&&(e.class=[e.class,`${o}-hl`].filter(Boolean).join(" ")),e}}}function it(t){return"string"==typeof t&&/^[#\w\s.,%()/+-]+$/.test(t)&&!/url\s*\(|expression/i.test(t)}export{_ as D,y as P,et as a,st as b,Q as c,X as d,R as l,tt as n,Y as p,U as s,rt as t};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
/* Inline Math 0.1.0 — MIT licence; includes mathzetta (and @mathzetta/cas, for the CAS) */
|
|
2
|
-
import{c as o}from"./calculate-BX9lJ7Ff.js";import{d as s,e as t}from"./lite-Bj_L6w2g.js";function c(s,c={}){return t(s,{...c,blocks:c.blocks??o})}function r(t,c={}){return s(t,{...c,blocks:c.blocks??o})}export{r as a,c as t};
|