cellml-text-editor 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,13 +1,13 @@
1
- var n = /* @__PURE__ */ ((r) => (r[r.Unknown = 0] = "Unknown", r[r.EOF = 1] = "EOF", r[r.Identifier = 2] = "Identifier", r[r.Number = 3] = "Number", r[r.String = 4] = "String", r[r.KwDef = 5] = "KwDef", r[r.KwModel = 6] = "KwModel", r[r.KwComp = 7] = "KwComp", r[r.KwEndDef = 8] = "KwEndDef", r[r.KwAs = 9] = "KwAs", r[r.KwVar = 10] = "KwVar", r[r.KwUnit = 11] = "KwUnit", r[r.KwSel = 12] = "KwSel", r[r.KwCase = 13] = "KwCase", r[r.KwOtherwise = 14] = "KwOtherwise", r[r.KwEndSel = 15] = "KwEndSel", r[r.OpAss = 16] = "OpAss", r[r.OpPlus = 17] = "OpPlus", r[r.OpMinus = 18] = "OpMinus", r[r.OpTimes = 19] = "OpTimes", r[r.OpDivide = 20] = "OpDivide", r[r.OpComma = 21] = "OpComma", r[r.Colon = 22] = "Colon", r[r.SemiColon = 23] = "SemiColon", r[r.LParam = 24] = "LParam", r[r.RParam = 25] = "RParam", r[r.LBrace = 26] = "LBrace", r[r.RBrace = 27] = "RBrace", r[r.OpEq = 28] = "OpEq", r[r.OpNe = 29] = "OpNe", r[r.OpLt = 30] = "OpLt", r[r.OpLe = 31] = "OpLe", r[r.OpGt = 32] = "OpGt", r[r.OpGe = 33] = "OpGe", r[r.OpAnd = 34] = "OpAnd", r[r.OpOr = 35] = "OpOr", r))(n || {});
2
- class $ {
1
+ var n = /* @__PURE__ */ ((a) => (a[a.Unknown = 0] = "Unknown", a[a.EOF = 1] = "EOF", a[a.Identifier = 2] = "Identifier", a[a.Number = 3] = "Number", a[a.String = 4] = "String", a[a.KwDef = 5] = "KwDef", a[a.KwModel = 6] = "KwModel", a[a.KwComp = 7] = "KwComp", a[a.KwEndDef = 8] = "KwEndDef", a[a.KwAs = 9] = "KwAs", a[a.KwVar = 10] = "KwVar", a[a.KwUnit = 11] = "KwUnit", a[a.KwSel = 12] = "KwSel", a[a.KwCase = 13] = "KwCase", a[a.KwOtherwise = 14] = "KwOtherwise", a[a.KwEndSel = 15] = "KwEndSel", a[a.OpAss = 16] = "OpAss", a[a.OpPlus = 17] = "OpPlus", a[a.OpMinus = 18] = "OpMinus", a[a.OpTimes = 19] = "OpTimes", a[a.OpDivide = 20] = "OpDivide", a[a.OpComma = 21] = "OpComma", a[a.Colon = 22] = "Colon", a[a.SemiColon = 23] = "SemiColon", a[a.LParam = 24] = "LParam", a[a.RParam = 25] = "RParam", a[a.LBrace = 26] = "LBrace", a[a.RBrace = 27] = "RBrace", a[a.OpEq = 28] = "OpEq", a[a.OpNe = 29] = "OpNe", a[a.OpLt = 30] = "OpLt", a[a.OpLe = 31] = "OpLe", a[a.OpGt = 32] = "OpGt", a[a.OpGe = 33] = "OpGe", a[a.OpAnd = 34] = "OpAnd", a[a.OpOr = 35] = "OpOr", a))(n || {});
2
+ class x {
3
3
  input;
4
4
  pos = 0;
5
5
  line = 1;
6
6
  length;
7
7
  currentToken = 1;
8
8
  currentValue = "";
9
- constructor(t) {
10
- this.input = t, this.length = t.length, this.nextToken();
9
+ constructor(e) {
10
+ this.input = e, this.length = e.length, this.nextToken();
11
11
  }
12
12
  get token() {
13
13
  return this.currentToken;
@@ -17,28 +17,28 @@ class $ {
17
17
  }
18
18
  // Advance to the next token
19
19
  nextToken() {
20
- const t = this.skipWhitespace();
21
- if (this.line += t, this.pos >= this.length) {
20
+ const e = this.skipWhitespace();
21
+ if (this.line += e, this.pos >= this.length) {
22
22
  this.currentToken = 1;
23
23
  return;
24
24
  }
25
25
  const s = this.input[this.pos];
26
26
  if (/[a-zA-Z_]/.test(s || "")) {
27
- let a = this.pos;
27
+ let i = this.pos;
28
28
  for (; this.pos < this.length && /[a-zA-Z0-9_]/.test(this.input[this.pos] || ""); )
29
29
  this.pos++;
30
- const e = this.input.slice(a, this.pos);
31
- this.currentValue = e, this.currentToken = this.getKeywordType(e);
30
+ const t = this.input.slice(i, this.pos);
31
+ this.currentValue = t, this.currentToken = this.getKeywordType(t);
32
32
  return;
33
33
  }
34
34
  if (/[0-9]/.test(s || "") || s === "." && /[0-9]/.test(this.input[this.pos + 1] || "")) {
35
- let a = this.pos;
35
+ let i = this.pos;
36
36
  for (; this.pos < this.length && /[0-9]/.test(this.input[this.pos] || ""); ) this.pos++;
37
37
  if (this.input[this.pos] === ".")
38
38
  for (this.pos++; this.pos < this.length && /[0-9]/.test(this.input[this.pos] || ""); ) this.pos++;
39
39
  if (this.input[this.pos] === "e" || this.input[this.pos] === "E")
40
40
  for (this.pos++, (this.input[this.pos] === "+" || this.input[this.pos] === "-") && this.pos++; this.pos < this.length && /[0-9]/.test(this.input[this.pos] || ""); ) this.pos++;
41
- this.currentValue = this.input.slice(a, this.pos), this.currentToken = 3;
41
+ this.currentValue = this.input.slice(i, this.pos), this.currentToken = 3;
42
42
  return;
43
43
  }
44
44
  switch (this.pos++, this.currentValue = s || "", s) {
@@ -97,22 +97,22 @@ class $ {
97
97
  return this.line;
98
98
  }
99
99
  skipWhitespace() {
100
- let t = 0;
100
+ let e = 0;
101
101
  for (; this.pos < this.length; ) {
102
102
  const s = this.input[this.pos];
103
103
  if (/\s/.test(s || ""))
104
104
  s === `
105
- ` && t++, this.pos++;
105
+ ` && e++, this.pos++;
106
106
  else if (s === "/" && this.input[this.pos + 1] === "/")
107
107
  for (this.pos += 2; this.pos < this.length && this.input[this.pos] !== `
108
108
  `; ) this.pos++;
109
109
  else
110
110
  break;
111
111
  }
112
- return t;
112
+ return e;
113
113
  }
114
- getKeywordType(t) {
115
- switch (t) {
114
+ getKeywordType(e) {
115
+ switch (e) {
116
116
  case "def":
117
117
  return 5;
118
118
  case "model":
@@ -149,11 +149,11 @@ class g {
149
149
  scanner;
150
150
  doc;
151
151
  sourceLineAttr;
152
- constructor(t = {}) {
153
- this.sourceLineAttr = t.sourceLineAttribute === void 0 ? "data-source-location" : t.sourceLineAttribute;
152
+ constructor(e = {}) {
153
+ this.sourceLineAttr = e.sourceLineAttribute === void 0 ? "data-source-location" : e.sourceLineAttribute;
154
154
  }
155
- parse(t) {
156
- this.scanner = new $(t), this.doc = document.implementation.createDocument(m, "model", null);
155
+ parse(e) {
156
+ this.scanner = new x(e), this.doc = document.implementation.createDocument(m, "model", null);
157
157
  try {
158
158
  const s = this.doc.documentElement;
159
159
  for (this.expect(n.KwDef), this.expect(n.KwModel), this.scanner.token === n.Identifier && (s.setAttribute("name", this.scanner.value), this.scanner.nextToken()), this.expect(n.KwAs); this.scanner.token !== n.KwEndDef && this.scanner.token !== n.EOF; )
@@ -164,145 +164,183 @@ class g {
164
164
  return { xml: null, errors: [{ line: this.scanner.getLine(), message: s.message || "Unknown parsing error" }] };
165
165
  }
166
166
  }
167
- parseBlock(t) {
167
+ parseBlock(e) {
168
168
  if (this.expect(n.KwDef), this.scanner.token === n.KwComp)
169
- this.parseComponent(t);
169
+ this.parseComponent(e);
170
170
  else if (this.scanner.token === n.KwUnit)
171
- this.parseUnit(t);
171
+ this.parseUnit(e);
172
172
  else
173
173
  throw new Error("Expected 'comp' or 'unit' after 'def'");
174
174
  }
175
- parseComponent(t) {
175
+ parseComponent(e) {
176
176
  this.expect(n.KwComp);
177
177
  const s = this.expectValue(n.Identifier);
178
178
  this.expect(n.KwAs);
179
- const a = this.doc.createElementNS(m, "component");
180
- for (a.setAttribute("name", s), t.appendChild(a); this.scanner.token !== n.KwEndDef && this.scanner.token !== n.EOF; )
181
- this.scanner.token === n.KwVar ? this.parseVariable(a) : this.scanner.token === n.Identifier || this.scanner.token === n.KwSel ? this.parseMathEquation(a) : this.scanner.nextToken();
179
+ const i = this.doc.createElementNS(m, "component");
180
+ for (i.setAttribute("name", s), e.appendChild(i); this.scanner.token !== n.KwEndDef && this.scanner.token !== n.EOF; )
181
+ this.scanner.token === n.KwVar ? this.parseVariable(i) : this.scanner.token === n.Identifier || this.scanner.token === n.KwSel ? this.parseMathEquation(i) : this.scanner.nextToken();
182
182
  this.expect(n.KwEndDef), this.expect(n.SemiColon);
183
183
  }
184
184
  // var V: millivolt {init: -65, interface: public};
185
- parseVariable(t) {
185
+ parseVariable(e) {
186
186
  this.expect(n.KwVar);
187
187
  const s = this.expectValue(n.Identifier);
188
188
  this.expect(n.Colon);
189
- const a = this.expectValue(n.Identifier), e = this.doc.createElementNS(m, "variable");
190
- if (e.setAttribute("name", s), e.setAttribute("units", a), this.scanner.token === n.LBrace) {
189
+ const i = this.expectValue(n.Identifier), t = this.doc.createElementNS(m, "variable");
190
+ if (t.setAttribute("name", s), t.setAttribute("units", i), this.scanner.token === n.LBrace) {
191
191
  for (this.scanner.nextToken(); this.scanner.token !== n.RBrace && this.scanner.token !== n.EOF; ) {
192
- const i = this.expectValue(n.Identifier);
192
+ const r = this.expectValue(n.Identifier);
193
193
  this.expect(n.Colon);
194
194
  let c = "";
195
- this.scanner.token === n.OpMinus ? (this.scanner.nextToken(), c = "-" + this.expectValue(n.Number)) : this.scanner.token === n.Number ? c = this.expectValue(n.Number) : c = this.expectValue(n.Identifier), i === "init" ? e.setAttribute("initial_value", c) : i === "interface" && e.setAttribute("interface", c), this.scanner.token === n.OpComma && this.scanner.nextToken();
195
+ this.scanner.token === n.OpMinus ? (this.scanner.nextToken(), c = "-" + this.expectValue(n.Number)) : this.scanner.token === n.Number ? c = this.expectValue(n.Number) : c = this.expectValue(n.Identifier), r === "init" ? t.setAttribute("initial_value", c) : r === "interface" && t.setAttribute("interface", c), this.scanner.token === n.OpComma && this.scanner.nextToken();
196
196
  }
197
197
  this.expect(n.RBrace);
198
198
  }
199
- this.expect(n.SemiColon), t.appendChild(e);
199
+ this.expect(n.SemiColon), e.appendChild(t);
200
200
  }
201
- parseUnit(t) {
201
+ parseUnit(e) {
202
202
  for (this.expect(n.KwUnit); this.scanner.token !== n.KwEndDef && this.scanner.token !== n.EOF; )
203
203
  this.scanner.nextToken();
204
204
  this.expect(n.KwEndDef), this.expect(n.SemiColon);
205
205
  }
206
206
  // --- Math Parsing ---
207
- parseMathEquation(t) {
207
+ parseMathEquation(e) {
208
208
  const s = this.scanner.getLine();
209
- let a = t.getElementsByTagNameNS(h, "math")[0];
210
- a || (a = this.doc.createElementNS(h, "math"), t.appendChild(a));
211
- const e = this.doc.createElementNS(h, "apply"), i = this.doc.createElementNS(h, "eq");
212
- e.appendChild(i);
209
+ let i = e.getElementsByTagNameNS(h, "math")[0];
210
+ i || (i = this.doc.createElementNS(h, "math"), e.appendChild(i));
211
+ const t = this.doc.createElementNS(h, "apply"), r = this.doc.createElementNS(h, "eq");
212
+ t.appendChild(r);
213
213
  const c = this.parseExpression();
214
214
  this.expect(n.OpAss);
215
215
  const o = this.parseExpression(), u = this.scanner.getLine();
216
- this.sourceLineAttr && e.setAttribute(
216
+ this.sourceLineAttr && t.setAttribute(
217
217
  this.sourceLineAttr,
218
218
  `${s.toString()}` + (u !== s ? `-${u.toString()}` : "")
219
- ), e.appendChild(c), e.appendChild(o), a.appendChild(e), this.expect(n.SemiColon);
219
+ ), t.appendChild(c), t.appendChild(o), i.appendChild(t), this.expect(n.SemiColon);
220
220
  }
221
221
  // Recursive Descent for Math: Condition -> Comparison -> Expression -> Term -> Factor
222
222
  parseCondition() {
223
- let t = this.parseComparison();
223
+ let e = this.parseComparison();
224
224
  for (; this.scanner.token === n.OpAnd || this.scanner.token === n.OpOr; ) {
225
225
  const s = this.scanner.token;
226
226
  this.scanner.nextToken();
227
- const a = this.parseComparison(), e = this.doc.createElementNS(h, "apply"), i = this.doc.createElementNS(h, s === n.OpAnd ? "and" : "or");
228
- e.appendChild(i), e.appendChild(t), e.appendChild(a), t = e;
227
+ const i = this.parseComparison(), t = this.doc.createElementNS(h, "apply"), r = this.doc.createElementNS(h, s === n.OpAnd ? "and" : "or");
228
+ t.appendChild(r), t.appendChild(e), t.appendChild(i), e = t;
229
229
  }
230
- return t;
230
+ return e;
231
231
  }
232
- isComparisonToken(t) {
233
- return [n.OpEq, n.OpNe, n.OpLt, n.OpLe, n.OpGt, n.OpGe].includes(t);
232
+ isComparisonToken(e) {
233
+ return [n.OpEq, n.OpNe, n.OpLt, n.OpLe, n.OpGt, n.OpGe].includes(e);
234
234
  }
235
235
  // The new parsing layer
236
236
  parseComparison() {
237
- let t = this.parseExpression();
237
+ let e = this.parseExpression();
238
238
  if (this.isComparisonToken(this.scanner.token)) {
239
239
  const s = this.scanner.token;
240
240
  this.scanner.nextToken();
241
- const a = this.parseExpression(), e = this.doc.createElementNS(h, "apply");
242
- let i = "";
241
+ const i = this.parseExpression(), t = this.doc.createElementNS(h, "apply");
242
+ let r = "";
243
243
  switch (s) {
244
244
  case n.OpEq:
245
- i = "eq";
245
+ r = "eq";
246
246
  break;
247
247
  case n.OpNe:
248
- i = "neq";
248
+ r = "neq";
249
249
  break;
250
250
  case n.OpLt:
251
- i = "lt";
251
+ r = "lt";
252
252
  break;
253
253
  case n.OpLe:
254
- i = "leq";
254
+ r = "leq";
255
255
  break;
256
256
  case n.OpGt:
257
- i = "gt";
257
+ r = "gt";
258
258
  break;
259
259
  case n.OpGe:
260
- i = "geq";
260
+ r = "geq";
261
261
  break;
262
262
  case n.OpAnd:
263
- i = "and";
263
+ r = "and";
264
264
  break;
265
265
  }
266
- const c = this.doc.createElementNS(h, i);
267
- return e.appendChild(c), e.appendChild(t), e.appendChild(a), e;
266
+ const c = this.doc.createElementNS(h, r);
267
+ return t.appendChild(c), t.appendChild(e), t.appendChild(i), t;
268
268
  }
269
- return t;
269
+ return e;
270
+ }
271
+ /**
272
+ * Checks if an element is an <apply> block for a specific operator.
273
+ * e.g. isMathMLApply(node, 'plus') returns true for <apply><plus/>...</apply>
274
+ */
275
+ isMathMLApply(e, s) {
276
+ if (e.localName !== "apply") return !1;
277
+ const i = e.firstElementChild;
278
+ return i ? i.localName === s : !1;
270
279
  }
271
280
  parseExpression() {
272
- let t = this.parseTerm();
281
+ let e = this.parseTerm();
273
282
  for (; this.scanner.token === n.OpPlus || this.scanner.token === n.OpMinus; ) {
274
283
  const s = this.scanner.token;
275
284
  this.scanner.nextToken();
276
- const a = this.parseTerm(), e = this.doc.createElementNS(h, "apply"), i = this.doc.createElementNS(h, s === n.OpPlus ? "plus" : "minus");
277
- e.appendChild(i), e.appendChild(t), e.appendChild(a), t = e;
285
+ const i = this.parseTerm();
286
+ if (s === n.OpPlus && this.isMathMLApply(e, "plus"))
287
+ e.appendChild(i);
288
+ else {
289
+ const t = this.doc.createElementNS(h, "apply"), r = this.doc.createElementNS(h, s === n.OpPlus ? "plus" : "minus");
290
+ t.appendChild(r), t.appendChild(e), t.appendChild(i), e = t;
291
+ }
278
292
  }
279
- return t;
293
+ return e;
280
294
  }
281
295
  parseTerm() {
282
- let t = this.parseFactor();
296
+ let e = this.parseFactor();
283
297
  for (; this.scanner.token === n.OpTimes || this.scanner.token === n.OpDivide; ) {
284
298
  const s = this.scanner.token;
285
299
  this.scanner.nextToken();
286
- const a = this.parseFactor(), e = this.doc.createElementNS(h, "apply"), i = this.doc.createElementNS(h, s === n.OpTimes ? "times" : "divide");
287
- e.appendChild(i), e.appendChild(t), e.appendChild(a), t = e;
300
+ const i = this.parseFactor();
301
+ if (s === n.OpTimes && this.isMathMLApply(e, "times"))
302
+ e.appendChild(i);
303
+ else {
304
+ const t = this.doc.createElementNS(h, "apply"), r = this.doc.createElementNS(h, s === n.OpTimes ? "times" : "divide");
305
+ t.appendChild(r), t.appendChild(e), t.appendChild(i), e = t;
306
+ }
288
307
  }
289
- return t;
308
+ return e;
309
+ }
310
+ /**
311
+ * Checks if the identifier is a reserved MathML constant name
312
+ * and returns the corresponding element, or null if it's a variable.
313
+ */
314
+ createMathMLConstant(e) {
315
+ const s = {
316
+ pi: "pi",
317
+ e: "exponentiale",
318
+ // Standard math constant e
319
+ inf: "infinity",
320
+ // Common abbreviation
321
+ infinity: "infinity",
322
+ NaN: "notanumber",
323
+ true: "true",
324
+ // Boolean constants
325
+ false: "false"
326
+ };
327
+ return s.hasOwnProperty(e) ? this.doc.createElementNS(h, s[e] || "") : null;
290
328
  }
291
329
  parseFactor() {
292
330
  if (this.scanner.token === n.OpMinus) {
293
331
  this.scanner.nextToken();
294
- const t = this.parseFactor(), s = this.doc.createElementNS(h, "apply"), a = this.doc.createElementNS(h, "minus");
295
- return s.appendChild(a), s.appendChild(t), s;
332
+ const e = this.parseFactor(), s = this.doc.createElementNS(h, "apply"), i = this.doc.createElementNS(h, "minus");
333
+ return s.appendChild(i), s.appendChild(e), s;
296
334
  }
297
335
  if (this.scanner.token === n.Number) {
298
- const t = this.scanner.value;
336
+ const e = this.scanner.value;
299
337
  this.scanner.nextToken();
300
338
  const s = this.doc.createElementNS(h, "cn");
301
- if (s.textContent = t, this.scanner.token === n.LBrace) {
339
+ if (s.textContent = e, this.scanner.token === n.LBrace) {
302
340
  if (this.scanner.nextToken(), this.scanner.value === "units") {
303
341
  this.scanner.nextToken(), this.expect(n.Colon);
304
- const a = this.expectValue(n.Identifier);
305
- s.setAttributeNS(m, "cellml:units", a);
342
+ const i = this.expectValue(n.Identifier);
343
+ s.setAttributeNS(m, "cellml:units", i);
306
344
  }
307
345
  for (; this.scanner.token !== n.RBrace && this.scanner.token !== n.EOF; )
308
346
  this.scanner.nextToken();
@@ -310,95 +348,98 @@ class g {
310
348
  }
311
349
  return s;
312
350
  } else if (this.scanner.token === n.Identifier) {
313
- const t = this.scanner.value;
351
+ const e = this.scanner.value;
314
352
  if (this.scanner.nextToken(), this.scanner.token === n.LParam)
315
- return this.parseFunctionCall(t);
316
- const s = this.doc.createElementNS(h, "ci");
317
- return s.textContent = t, s;
353
+ return this.parseFunctionCall(e);
354
+ const s = this.createMathMLConstant(e);
355
+ if (s)
356
+ return s;
357
+ const i = this.doc.createElementNS(h, "ci");
358
+ return i.textContent = e, i;
318
359
  } else if (this.scanner.token === n.LParam) {
319
360
  this.scanner.nextToken();
320
- const t = this.parseExpression();
321
- return this.expect(n.RParam), t;
361
+ const e = this.parseExpression();
362
+ return this.expect(n.RParam), e;
322
363
  } else if (this.scanner.token === n.KwSel)
323
364
  return this.parsePiecewise();
324
365
  throw new Error(`Unexpected token in math: ${this.scanner.value}`);
325
366
  }
326
367
  parsePiecewise() {
327
- const t = this.doc.createElementNS(h, "piecewise");
368
+ const e = this.doc.createElementNS(h, "piecewise");
328
369
  for (this.expect(n.KwSel); this.scanner.token === n.KwCase; ) {
329
370
  this.expect(n.KwCase);
330
371
  const s = this.parseCondition();
331
372
  this.expect(n.Colon);
332
- const a = this.parseExpression();
373
+ const i = this.parseExpression();
333
374
  this.expect(n.SemiColon);
334
- const e = this.doc.createElementNS(h, "piece");
335
- e.appendChild(a), e.appendChild(s), t.appendChild(e);
375
+ const t = this.doc.createElementNS(h, "piece");
376
+ t.appendChild(i), t.appendChild(s), e.appendChild(t);
336
377
  }
337
378
  if (this.scanner.token === n.KwOtherwise) {
338
379
  this.expect(n.KwOtherwise), this.expect(n.Colon);
339
380
  const s = this.parseExpression();
340
381
  this.expect(n.SemiColon);
341
- const a = this.doc.createElementNS(h, "otherwise");
342
- a.appendChild(s), t.appendChild(a);
382
+ const i = this.doc.createElementNS(h, "otherwise");
383
+ i.appendChild(s), e.appendChild(i);
343
384
  }
344
- return this.expect(n.KwEndSel), t;
385
+ return this.expect(n.KwEndSel), e;
345
386
  }
346
- parseFunctionCall(t) {
347
- if (this.expect(n.LParam), t === "ode") {
348
- const e = this.parseExpression();
387
+ parseFunctionCall(e) {
388
+ if (this.expect(n.LParam), e === "ode") {
389
+ const t = this.parseExpression();
349
390
  this.expect(n.OpComma);
350
- const i = this.parseExpression();
391
+ const r = this.parseExpression();
351
392
  this.expect(n.RParam);
352
393
  const c = this.doc.createElementNS(h, "apply");
353
394
  c.appendChild(this.doc.createElementNS(h, "diff"));
354
395
  const o = this.doc.createElementNS(h, "bvar");
355
- return o.appendChild(i), c.appendChild(o), c.appendChild(e), c;
396
+ return o.appendChild(r), c.appendChild(o), c.appendChild(t), c;
356
397
  }
357
- const s = this.doc.createElementNS(h, "apply"), a = this.doc.createElementNS(h, t);
358
- if (s.appendChild(a), this.scanner.token !== n.RParam)
398
+ const s = this.doc.createElementNS(h, "apply"), i = this.doc.createElementNS(h, e);
399
+ if (s.appendChild(i), this.scanner.token !== n.RParam)
359
400
  do
360
401
  this.scanner.token === n.OpComma && this.scanner.nextToken(), s.appendChild(this.parseExpression());
361
402
  while (this.scanner.token === n.OpComma);
362
403
  return this.expect(n.RParam), s;
363
404
  }
364
405
  // --- Helpers ---
365
- expect(t) {
366
- if (this.scanner.token !== t)
367
- throw new Error(`Syntax Error: Expected ${n[t]} but found '${this.scanner.value}'`);
406
+ expect(e) {
407
+ if (this.scanner.token !== e)
408
+ throw new Error(`Syntax Error: Expected ${n[e]} but found '${this.scanner.value}'`);
368
409
  this.scanner.nextToken();
369
410
  }
370
- expectValue(t) {
371
- if (this.scanner.token !== t)
372
- throw new Error(`Expected value of type ${n[t]}, got ${this.scanner.token}`);
411
+ expectValue(e) {
412
+ if (this.scanner.token !== e)
413
+ throw new Error(`Expected value of type ${n[e]}, got ${this.scanner.token}`);
373
414
  const s = this.scanner.value;
374
415
  return this.scanner.nextToken(), s;
375
416
  }
376
- serialize(t, s = 0) {
377
- const a = " ".repeat(s), e = t.tagName, i = t.localName;
417
+ serialize(e, s = 0) {
418
+ const i = " ".repeat(s), t = e.tagName, r = e.localName;
378
419
  let c = "";
379
- for (let d = 0; d < t.attributes.length; d++) {
380
- const f = t.attributes[d];
420
+ r === "model" && !e.hasAttribute("xmlns") && (c += ` xmlns="${m}"`), r === "math" && !e.hasAttribute("xmlns") && (c += ` xmlns="${h}" xmlns:cellml="${m}"`);
421
+ for (let d = 0; d < e.attributes.length; d++) {
422
+ const f = e.attributes[d];
381
423
  if (f) {
382
424
  if (this.sourceLineAttr && f.name === this.sourceLineAttr)
383
425
  continue;
384
426
  c += ` ${f.name}="${f.value}"`;
385
427
  }
386
428
  }
387
- i === "model" && !t.hasAttribute("xmlns") && (c += ` xmlns="${m}"`), i === "math" && !t.hasAttribute("xmlns") && (c += ` xmlns="${h}" xmlns:cellml="${m}"`);
388
- const o = Array.from(t.childNodes), u = o.some((d) => d.nodeType === 1), l = t.textContent?.trim();
429
+ const o = Array.from(e.childNodes), u = o.some((d) => d.nodeType === 1), l = e.textContent?.trim();
389
430
  if (o.length === 0 && !l)
390
- return `${a}<${e}${c}/>`;
431
+ return `${i}<${t}${c}/>`;
391
432
  if (!u)
392
- return `${a}<${e}${c}>${l}</${e}>`;
393
- let p = `${a}<${e}${c}>
433
+ return `${i}<${t}${c}>${l}</${t}>`;
434
+ let p = `${i}<${t}${c}>
394
435
  `;
395
436
  return o.forEach((d) => {
396
437
  d.nodeType === 1 && (p += this.serialize(d, s + 1) + `
397
438
  `);
398
- }), p += `${a}</${e}>`, p;
439
+ }), p += `${i}</${t}>`, p;
399
440
  }
400
441
  }
401
- const x = "http://www.cellml.org/cellml/2.0#";
442
+ const $ = "http://www.cellml.org/cellml/2.0#";
402
443
  class N {
403
444
  output = "";
404
445
  indentLevel = 0;
@@ -411,90 +452,90 @@ class N {
411
452
  indent() {
412
453
  return this.standardIndent.repeat(this.indentLevel);
413
454
  }
414
- append(t, s = !0) {
415
- this.output += (s ? this.indent() : "") + t + (s ? `
455
+ append(e, s = !0) {
456
+ this.output += (s ? this.indent() : "") + e + (s ? `
416
457
  ` : "");
417
458
  }
418
459
  // --- Main Entry Point ---
419
- generate(t) {
460
+ generate(e) {
420
461
  this.output = "", this.indentLevel = 0;
421
462
  try {
422
- const s = this.domParser.parseFromString(t, "application/xml");
463
+ const s = this.domParser.parseFromString(e, "application/xml");
423
464
  if (s.querySelector("parsererror")) throw new Error("XML Parsing Error");
424
- const e = s.getElementsByTagNameNS("http://www.cellml.org/cellml/2.0#", "model")[0];
425
- if (!e) throw new Error("No CellML 2.0 Model found");
426
- this.processModel(e);
465
+ const t = s.getElementsByTagNameNS("http://www.cellml.org/cellml/2.0#", "model")[0];
466
+ if (!t) throw new Error("No CellML 2.0 Model found");
467
+ this.processModel(t);
427
468
  } catch (s) {
428
469
  return `// Error generating text: ${s.message}`;
429
470
  }
430
471
  return this.output;
431
472
  }
432
473
  // --- Recursive Processors ---
433
- processModel(t) {
434
- const s = t.getAttribute("name") || "unnamed_model";
474
+ processModel(e) {
475
+ const s = e.getAttribute("name") || "unnamed_model";
435
476
  this.append(`def model ${s} as`), this.indentLevel++;
436
- const a = t.getElementsByTagName("units");
437
- for (let i = 0; i < a.length; i++)
438
- a[i]?.parentElement === t && this.processUnits(a[i]);
439
- const e = t.getElementsByTagName("component");
440
- for (let i = 0; i < e.length; i++)
441
- this.processComponent(e[i]);
477
+ const i = e.getElementsByTagName("units");
478
+ for (let r = 0; r < i.length; r++)
479
+ i[r]?.parentElement === e && this.processUnits(i[r]);
480
+ const t = e.getElementsByTagName("component");
481
+ for (let r = 0; r < t.length; r++)
482
+ this.processComponent(t[r]);
442
483
  this.indentLevel--, this.append("enddef;");
443
484
  }
444
- processUnits(t) {
445
- const s = t?.getAttribute("name") || "unnamed_units";
485
+ processUnits(e) {
486
+ const s = e?.getAttribute("name") || "unnamed_units";
446
487
  this.append(`def unit ${s} as`), this.indentLevel++;
447
- const a = t?.getElementsByTagName("unit") || [];
448
- for (let e = 0; e < a.length; e++) {
449
- const i = a[e];
450
- if (!i) continue;
451
- const c = i.getAttribute("prefix"), o = i.getAttribute("units"), u = i.getAttribute("exponent"), l = i.getAttribute("multiplier");
488
+ const i = e?.getElementsByTagName("unit") || [];
489
+ for (let t = 0; t < i.length; t++) {
490
+ const r = i[t];
491
+ if (!r) continue;
492
+ const c = r.getAttribute("prefix"), o = r.getAttribute("units"), u = r.getAttribute("exponent"), l = r.getAttribute("multiplier");
452
493
  let p = `unit ${o}`;
453
494
  c && (p += ` {prefix: ${c}}`), u && (p += ` {exponent: ${u}}`), l && (p += ` {multiplier: ${l}}`), p += ";", this.append(p);
454
495
  }
455
496
  this.indentLevel--, this.append("enddef;"), this.append("");
456
497
  }
457
- processComponent(t) {
458
- const s = t?.getAttribute("name") || "unnamed_component";
498
+ processComponent(e) {
499
+ const s = e?.getAttribute("name") || "unnamed_component";
459
500
  this.append(`def comp ${s} as`), this.indentLevel++;
460
- const a = t?.getElementsByTagName("variable") || [];
461
- for (let i = 0; i < a.length; i++)
462
- this.processVariable(a[i]);
463
- const e = t?.getElementsByTagNameNS("http://www.w3.org/1998/Math/MathML", "math") || [];
464
- for (let i = 0; i < e.length; i++)
465
- this.processMath(e[i]);
501
+ const i = e?.getElementsByTagName("variable") || [];
502
+ for (let r = 0; r < i.length; r++)
503
+ this.processVariable(i[r]);
504
+ const t = e?.getElementsByTagNameNS("http://www.w3.org/1998/Math/MathML", "math") || [];
505
+ for (let r = 0; r < t.length; r++)
506
+ this.processMath(t[r]);
466
507
  this.indentLevel--, this.append("enddef;"), this.append("");
467
508
  }
468
- processVariable(t) {
469
- const s = t?.getAttribute("name"), a = t?.getAttribute("units"), e = t?.getAttribute("initial_value"), i = t?.getAttribute("interface");
470
- let c = `var ${s}: ${a}`, o = [];
471
- e && o.push(`init: ${e}`), i && o.push(`interface: ${i}`), o.length > 0 && (c += ` {${o.join(", ")}}`), c += ";", this.append(c);
509
+ processVariable(e) {
510
+ const s = e?.getAttribute("name"), i = e?.getAttribute("units"), t = e?.getAttribute("initial_value"), r = e?.getAttribute("interface");
511
+ let c = `var ${s}: ${i}`, o = [];
512
+ t && o.push(`init: ${t}`), r && o.push(`interface: ${r}`), o.length > 0 && (c += ` {${o.join(", ")}}`), c += ";", this.append(c);
472
513
  }
473
514
  // --- MathML Handling ---
474
- processMath(t) {
475
- const s = Array.from(t?.children || []);
476
- for (const a of s)
477
- if (a.localName === "apply" && a.firstElementChild?.localName === "eq") {
478
- const i = Array.from(a.children).slice(1), c = this.parseMathNode(i[0]), o = this.parseMathNode(i[1]);
515
+ processMath(e) {
516
+ const s = Array.from(e?.children || []);
517
+ for (const i of s)
518
+ if (i.localName === "apply" && i.firstElementChild?.localName === "eq") {
519
+ const r = Array.from(i.children).slice(1), c = this.parseMathNode(r[0]), o = this.parseMathNode(r[1]);
479
520
  this.append(`${c} = ${o};`);
480
521
  } else {
481
- const i = this.parseMathNode(a);
482
- i && this.append(i + ";");
522
+ const r = this.parseMathNode(i);
523
+ r && this.append(r + ";");
483
524
  }
484
525
  }
485
- parseMathNode(t) {
486
- if (!t) return "";
487
- const s = t.localName;
526
+ parseMathNode(e) {
527
+ if (!e) return "";
528
+ const s = e.localName;
488
529
  if (s === "apply")
489
- return this.parseApply(t);
530
+ return this.parseApply(e);
490
531
  if (s === "ci")
491
- return t.textContent?.trim() || "";
532
+ return e.textContent?.trim() || "";
492
533
  if (s === "cn") {
493
- const a = t.textContent?.trim() || "0", e = t.getAttributeNS(x, "units");
494
- return e ? `${a} {units: ${e}}` : a;
534
+ const i = e.textContent?.trim() || "0", t = e.getAttributeNS($, "units");
535
+ return t ? `${i} {units: ${t}}` : i;
495
536
  } else {
496
537
  if (s === "piecewise")
497
- return this.parsePiecewise(t);
538
+ return this.parsePiecewise(e);
498
539
  if (s === "pi")
499
540
  return "pi";
500
541
  if (s === "bvar")
@@ -502,37 +543,37 @@ class N {
502
543
  }
503
544
  return console.log(`Unsupported MathML node: ${s}`), `/* Unsupported MathML node: ${s} */`;
504
545
  }
505
- parseApply(t) {
506
- const s = Array.from(t.children);
546
+ parseApply(e) {
547
+ const s = Array.from(e.children);
507
548
  if (s.length === 0) return "";
508
- const a = s[0]?.localName, e = s.slice(1).map((i) => this.parseMathNode(i));
509
- switch (a) {
549
+ const i = s[0]?.localName, t = s.slice(1).map((r) => this.parseMathNode(r));
550
+ switch (i) {
510
551
  case "plus":
511
- return `(${e.join(" + ")})`;
552
+ return `(${t.join(" + ")})`;
512
553
  case "minus":
513
- return e.length === 1 ? `-${e[0]}` : `(${e[0]} - ${e[1]})`;
554
+ return t.length === 1 ? `-${t[0]}` : `(${t[0]} - ${t[1]})`;
514
555
  case "times":
515
- return `(${e.join(" * ")})`;
556
+ return `(${t.join(" * ")})`;
516
557
  case "divide":
517
- return `(${e[0]} / ${e[1]})`;
558
+ return `(${t[0]} / ${t[1]})`;
518
559
  case "eq":
519
- return `${e[0]} == ${e[1]}`;
560
+ return `${t[0]} == ${t[1]}`;
520
561
  case "neq":
521
- return `${e[0]} != ${e[1]}`;
562
+ return `${t[0]} != ${t[1]}`;
522
563
  case "lt":
523
- return `${e[0]} < ${e[1]}`;
564
+ return `${t[0]} < ${t[1]}`;
524
565
  case "leq":
525
- return `${e[0]} <= ${e[1]}`;
566
+ return `${t[0]} <= ${t[1]}`;
526
567
  case "gt":
527
- return `${e[0]} > ${e[1]}`;
568
+ return `${t[0]} > ${t[1]}`;
528
569
  case "geq":
529
- return `${e[0]} >= ${e[1]}`;
570
+ return `${t[0]} >= ${t[1]}`;
530
571
  case "and":
531
- return `${e.join(" and ")}`;
572
+ return `${t.join(" and ")}`;
532
573
  case "or":
533
- return `${e.join(" or ")}`;
574
+ return `${t.join(" or ")}`;
534
575
  case "diff":
535
- const i = s.find((l) => l.localName === "bvar"), c = s.find((l) => l.localName !== "diff" && l.localName !== "bvar"), o = i?.children[0]?.textContent || "t";
576
+ const r = s.find((l) => l.localName === "bvar"), c = s.find((l) => l.localName !== "diff" && l.localName !== "bvar"), o = r?.children[0]?.textContent || "t";
536
577
  return `ode(${c ? this.parseMathNode(c) : "unknown"}, ${o})`;
537
578
  // Functions
538
579
  case "sin":
@@ -541,22 +582,22 @@ class N {
541
582
  case "exp":
542
583
  case "ln":
543
584
  case "log":
544
- return `${a}(${e[0]})`;
585
+ return `${i}(${t[0]})`;
545
586
  case "root":
546
- return `sqrt(${e[0]})`;
587
+ return `sqrt(${t[0]})`;
547
588
  default:
548
- return `${a}(${e.join(", ")})`;
589
+ return `${i}(${t.join(", ")})`;
549
590
  }
550
591
  }
551
- parsePiecewise(t) {
592
+ parsePiecewise(e) {
552
593
  let s = [];
553
- return Array.from(t?.children || []).forEach((e) => {
554
- if (e.localName === "piece") {
555
- const i = this.parseMathNode(e.children[0]), c = this.parseMathNode(e.children[1]);
556
- s.push(`${this.standardIndent}case ${c}: ${i};`);
557
- } else if (e.localName === "otherwise") {
558
- const i = this.parseMathNode(e.children[0]);
559
- s.push(`${this.standardIndent}otherwise: ${i};`);
594
+ return Array.from(e?.children || []).forEach((t) => {
595
+ if (t.localName === "piece") {
596
+ const r = this.parseMathNode(t.children[0]), c = this.parseMathNode(t.children[1]);
597
+ s.push(`${this.standardIndent}case ${c}: ${r};`);
598
+ } else if (t.localName === "otherwise") {
599
+ const r = this.parseMathNode(t.children[0]);
600
+ s.push(`${this.standardIndent}otherwise: ${r};`);
560
601
  }
561
602
  }), `sel
562
603
  ${this.indent()}${s.join(`
@@ -565,23 +606,23 @@ ${this.indent()}endsel`;
565
606
  }
566
607
  }
567
608
  class C {
568
- convert(t) {
569
- if (!t) return "";
570
- if (t.localName === "math")
571
- return Array.from(t.children).map((s) => this.convert(s)).join(`
609
+ convert(e) {
610
+ if (!e) return "";
611
+ if (e.localName === "math")
612
+ return Array.from(e.children).map((s) => this.convert(s)).join(`
572
613
  `);
573
- if (t.localName === "apply" && t.firstElementChild?.localName === "eq") {
574
- const s = Array.from(t.children), a = this.parseNode(s[1]), e = this.parseNode(s[2]);
575
- return `${a} = ${e}`;
614
+ if (e.localName === "apply" && e.firstElementChild?.localName === "eq") {
615
+ const s = Array.from(e.children), i = this.parseNode(s[1]), t = this.parseNode(s[2]);
616
+ return `${i} = ${t}`;
576
617
  }
577
- return this.parseNode(t);
618
+ return this.parseNode(e);
578
619
  }
579
- parseNode(t) {
580
- if (!t) return "";
581
- const s = t.localName;
582
- return s === "apply" ? this.parseApply(t) : s === "ci" ? this.parseIdentifier(t.textContent || "") : s === "cn" ? t.textContent || "0" : s === "piecewise" ? this.parsePiecewise(t) : "";
620
+ parseNode(e) {
621
+ if (!e) return "";
622
+ const s = e.localName;
623
+ return s === "apply" ? this.parseApply(e) : s === "ci" ? this.parseIdentifier(e.textContent || "") : s === "cn" ? e.textContent || "0" : s === "piecewise" ? this.parsePiecewise(e) : "";
583
624
  }
584
- escapeGreek(t) {
625
+ escapeGreek(e) {
585
626
  return [
586
627
  "alpha",
587
628
  "beta",
@@ -607,72 +648,72 @@ class C {
607
648
  "chi",
608
649
  "psi",
609
650
  "omega"
610
- ].includes(t.toLowerCase()) ? `\\${t}` : t;
651
+ ].includes(e.toLowerCase()) ? `\\${e}` : e;
611
652
  }
612
653
  /**
613
654
  * Specialized identifier formatter.
614
655
  * Format: Base_Sub_Super_SubOfSuper
615
656
  * Example: v_AQ_api_i -> v_{AQ}^{api_{i}}
616
657
  */
617
- parseIdentifier(t) {
618
- if (!t.includes("_"))
619
- return this.escapeGreek(t);
620
- const s = t.split("_"), a = this.escapeGreek(s[0] || ""), e = [];
621
- s[1] && e.push(s[1]), s.length > 4 && e.push(...s.slice(4));
622
- let i = "";
623
- s.length === 3 && (s[2] || []).length === 1 ? e.push(this.escapeGreek(s[2] || "")) : s[2] && (i = this.escapeGreek(s[2]), s[3] && (i += `_{${this.escapeGreek(s[3])}}`)), e.forEach((u, l) => {
624
- e[l] = this.escapeGreek(u);
658
+ parseIdentifier(e) {
659
+ if (!e.includes("_"))
660
+ return this.escapeGreek(e);
661
+ const s = e.split("_"), i = this.escapeGreek(s[0] || ""), t = [];
662
+ s[1] && t.push(s[1]), s.length > 4 && t.push(...s.slice(4));
663
+ let r = "";
664
+ s.length === 3 && (s[2] || []).length === 1 ? t.push(this.escapeGreek(s[2] || "")) : s[2] && (r = this.escapeGreek(s[2]), s[3] && (r += `_{${this.escapeGreek(s[3])}}`)), t.forEach((u, l) => {
665
+ t[l] = this.escapeGreek(u);
625
666
  });
626
- const c = e.join(",");
627
- let o = a;
628
- return c && (o += `_{${c}}`), i && (o += `^{${i}}`), o;
667
+ const c = t.join(",");
668
+ let o = i;
669
+ return c && (o += `_{${c}}`), r && (o += `^{${r}}`), o;
629
670
  }
630
- parseApply(t) {
631
- const s = Array.from(t?.children || []), a = s[0]?.localName, e = s.slice(1).map((i) => this.parseNode(i));
632
- switch (a) {
671
+ parseApply(e) {
672
+ const s = Array.from(e?.children || []), i = s[0]?.localName, t = s.slice(1).map((r) => this.parseNode(r));
673
+ switch (i) {
633
674
  case "plus":
634
- return e.join(" + ");
675
+ return t.join(" + ");
635
676
  case "minus":
636
- return e.length === 1 ? `-${e[0]}` : `${e[0]} - ${e[1]}`;
677
+ return t.length === 1 ? `-${t[0]}` : `${t[0]} - ${t[1]}`;
637
678
  case "times":
638
- return e.join(" \\cdot ");
679
+ return t.join(" \\cdot ");
639
680
  case "divide":
640
- return `\\frac{${e[0]}}{${e[1]}}`;
681
+ return `\\frac{${t[0]}}{${t[1]}}`;
641
682
  case "eq":
642
- return `${e[0]} == ${e[1]}`;
683
+ return `${t[0]} == ${t[1]}`;
643
684
  case "neq":
644
- return `${e[0]} \\neq ${e[1]}`;
685
+ return `${t[0]} \\neq ${t[1]}`;
645
686
  case "lt":
646
- return `${e[0]} < ${e[1]}`;
687
+ return `${t[0]} < ${t[1]}`;
647
688
  case "leq":
648
- return `${e[0]} \\leq ${e[1]}`;
689
+ return `${t[0]} \\leq ${t[1]}`;
649
690
  case "gt":
650
- return `${e[0]} > ${e[1]}`;
691
+ return `${t[0]} > ${t[1]}`;
651
692
  case "geq":
652
- return `${e[0]} \\geq ${e[1]}`;
693
+ return `${t[0]} \\geq ${t[1]}`;
653
694
  case "and":
654
- return e.join(" \\land ");
695
+ return t.join(" \\land ");
655
696
  case "or":
656
- return e.join(" \\lor ");
697
+ return t.join(" \\lor ");
657
698
  case "power":
658
- const i = s[1], c = e[0] || "", o = e[1];
659
- return i?.localName === "ci" || i?.localName === "cn" && !c.trim().startsWith("-") ? `{${c}}^{${o}}` : `\\left({${c}}\\right)^{${o}}`;
699
+ const r = s[1], c = t[0] || "", o = t[1];
700
+ return r?.localName === "ci" || r?.localName === "cn" && !c.trim().startsWith("-") ? `{${c}}^{${o}}` : `\\left({${c}}\\right)^{${o}}`;
660
701
  case "root":
661
702
  case "sqrt":
662
- return `\\sqrt{${e[0]}}`;
703
+ return `\\sqrt{${t[0]}}`;
663
704
  // simple sqrt
664
705
  case "diff":
665
706
  const l = s.find((w) => w.localName === "bvar"), p = s.find((w) => w.localName !== "diff" && w.localName !== "bvar"), d = l ? this.parseNode(l.firstElementChild) : "x";
666
707
  return `\\frac{d${p ? this.parseNode(p) : "y"}}{d${d}}`;
667
708
  // Trig & Funcs
668
709
  case "exp":
669
- return `e^{${e[0]}}`;
710
+ return `e^{${t[0]}}`;
670
711
  case "abs":
671
- return `\\left|${e[0]}\\right|`;
712
+ return `\\left|${t[0]}\\right|`;
672
713
  case "floor":
673
- return `\\lfloor ${e[0]} \\rfloor`;
714
+ return `\\lfloor ${t[0]} \\rfloor`;
674
715
  case "ceil":
675
- return `\\lceil ${e[0]} \\rceil`;
716
+ return `\\lceil ${t[0]} \\rceil`;
676
717
  case "cos":
677
718
  case "cosh":
678
719
  case "log10":
@@ -684,20 +725,20 @@ class C {
684
725
  case "sinh":
685
726
  case "tan":
686
727
  case "tanh":
687
- return `\\${a}\\left(${e[0]}\\right)`;
728
+ return `\\${i}\\left(${t[0]}\\right)`;
688
729
  default:
689
- return console.log(`Unsupported MathML operator: ${a}`), `\\text{${a}}(${e.join(", ")})`;
730
+ return console.log(`Unsupported MathML operator: ${i}`), `\\text{${i}}(${t.join(", ")})`;
690
731
  }
691
732
  }
692
- parsePiecewise(t) {
733
+ parsePiecewise(e) {
693
734
  let s = "";
694
- return Array.from(t.children).forEach((e) => {
695
- if (e.localName === "piece") {
696
- const i = this.parseNode(e.children[0]), c = this.parseNode(e.children[1]);
697
- s += `${i} & \\text{if } ${c} \\\\ `;
698
- } else if (e.localName === "otherwise") {
699
- const i = this.parseNode(e.children[0]);
700
- s += `${i} & \\text{otherwise}`;
735
+ return Array.from(e.children).forEach((t) => {
736
+ if (t.localName === "piece") {
737
+ const r = this.parseNode(t.children[0]), c = this.parseNode(t.children[1]);
738
+ s += `${r} & \\text{if } ${c} \\\\ `;
739
+ } else if (t.localName === "otherwise") {
740
+ const r = this.parseNode(t.children[0]);
741
+ s += `${r} & \\text{otherwise}`;
701
742
  }
702
743
  }), `\\begin{cases} ${s} \\end{cases}`;
703
744
  }
@@ -1,11 +1,11 @@
1
- (function(m,n){typeof exports=="object"&&typeof module<"u"?n(exports):typeof define=="function"&&define.amd?define(["exports"],n):(m=typeof globalThis<"u"?globalThis:m||self,n(m.CellMLTextEditor={}))})(this,(function(m){"use strict";var n=(r=>(r[r.Unknown=0]="Unknown",r[r.EOF=1]="EOF",r[r.Identifier=2]="Identifier",r[r.Number=3]="Number",r[r.String=4]="String",r[r.KwDef=5]="KwDef",r[r.KwModel=6]="KwModel",r[r.KwComp=7]="KwComp",r[r.KwEndDef=8]="KwEndDef",r[r.KwAs=9]="KwAs",r[r.KwVar=10]="KwVar",r[r.KwUnit=11]="KwUnit",r[r.KwSel=12]="KwSel",r[r.KwCase=13]="KwCase",r[r.KwOtherwise=14]="KwOtherwise",r[r.KwEndSel=15]="KwEndSel",r[r.OpAss=16]="OpAss",r[r.OpPlus=17]="OpPlus",r[r.OpMinus=18]="OpMinus",r[r.OpTimes=19]="OpTimes",r[r.OpDivide=20]="OpDivide",r[r.OpComma=21]="OpComma",r[r.Colon=22]="Colon",r[r.SemiColon=23]="SemiColon",r[r.LParam=24]="LParam",r[r.RParam=25]="RParam",r[r.LBrace=26]="LBrace",r[r.RBrace=27]="RBrace",r[r.OpEq=28]="OpEq",r[r.OpNe=29]="OpNe",r[r.OpLt=30]="OpLt",r[r.OpLe=31]="OpLe",r[r.OpGt=32]="OpGt",r[r.OpGe=33]="OpGe",r[r.OpAnd=34]="OpAnd",r[r.OpOr=35]="OpOr",r))(n||{});class ${input;pos=0;line=1;length;currentToken=1;currentValue="";constructor(t){this.input=t,this.length=t.length,this.nextToken()}get token(){return this.currentToken}get value(){return this.currentValue}nextToken(){const t=this.skipWhitespace();if(this.line+=t,this.pos>=this.length){this.currentToken=1;return}const s=this.input[this.pos];if(/[a-zA-Z_]/.test(s||"")){let a=this.pos;for(;this.pos<this.length&&/[a-zA-Z0-9_]/.test(this.input[this.pos]||"");)this.pos++;const e=this.input.slice(a,this.pos);this.currentValue=e,this.currentToken=this.getKeywordType(e);return}if(/[0-9]/.test(s||"")||s==="."&&/[0-9]/.test(this.input[this.pos+1]||"")){let a=this.pos;for(;this.pos<this.length&&/[0-9]/.test(this.input[this.pos]||"");)this.pos++;if(this.input[this.pos]===".")for(this.pos++;this.pos<this.length&&/[0-9]/.test(this.input[this.pos]||"");)this.pos++;if(this.input[this.pos]==="e"||this.input[this.pos]==="E")for(this.pos++,(this.input[this.pos]==="+"||this.input[this.pos]==="-")&&this.pos++;this.pos<this.length&&/[0-9]/.test(this.input[this.pos]||"");)this.pos++;this.currentValue=this.input.slice(a,this.pos),this.currentToken=3;return}switch(this.pos++,this.currentValue=s||"",s){case"=":this.input[this.pos]==="="?(this.pos++,this.currentValue="==",this.currentToken=28):this.currentToken=16;break;case"!":this.input[this.pos]==="="?(this.pos++,this.currentValue="!=",this.currentToken=29):(console.warn(`Unexpected character '!' at pos ${this.pos}`),this.currentToken=0);break;case"<":this.input[this.pos]==="="?(this.pos++,this.currentValue="<=",this.currentToken=31):this.currentToken=30;break;case">":this.input[this.pos]==="="?(this.pos++,this.currentValue=">=",this.currentToken=33):this.currentToken=32;break;case"+":this.currentToken=17;break;case"-":this.currentToken=18;break;case"*":this.currentToken=19;break;case"/":this.currentToken=20;break;case"(":this.currentToken=24;break;case")":this.currentToken=25;break;case"{":this.currentToken=26;break;case"}":this.currentToken=27;break;case":":this.currentToken=22;break;case";":this.currentToken=23;break;case",":this.currentToken=21;break;default:console.warn("Unknown char:",s),this.currentToken=0}}getLine(){return this.line}skipWhitespace(){let t=0;for(;this.pos<this.length;){const s=this.input[this.pos];if(/\s/.test(s||""))s===`
2
- `&&t++,this.pos++;else if(s==="/"&&this.input[this.pos+1]==="/")for(this.pos+=2;this.pos<this.length&&this.input[this.pos]!==`
3
- `;)this.pos++;else break}return t}getKeywordType(t){switch(t){case"def":return 5;case"model":return 6;case"comp":return 7;case"enddef":return 8;case"as":return 9;case"var":return 10;case"unit":return 11;case"sel":return 12;case"case":return 13;case"otherwise":return 14;case"endsel":return 15;case"and":return 34;case"or":return 35;default:return 2}}}const f="http://www.cellml.org/cellml/2.0#",h="http://www.w3.org/1998/Math/MathML";class g{scanner;doc;sourceLineAttr;constructor(t={}){this.sourceLineAttr=t.sourceLineAttribute===void 0?"data-source-location":t.sourceLineAttribute}parse(t){this.scanner=new $(t),this.doc=document.implementation.createDocument(f,"model",null);try{const s=this.doc.documentElement;for(this.expect(n.KwDef),this.expect(n.KwModel),this.scanner.token===n.Identifier&&(s.setAttribute("name",this.scanner.value),this.scanner.nextToken()),this.expect(n.KwAs);this.scanner.token!==n.KwEndDef&&this.scanner.token!==n.EOF;)this.scanner.token===n.KwDef?this.parseBlock(s):this.scanner.nextToken();return this.expect(n.KwEndDef),this.expect(n.SemiColon),{xml:`<?xml version="1.0" encoding="UTF-8"?>
4
- `+this.serialize(s),errors:[]}}catch(s){return{xml:null,errors:[{line:this.scanner.getLine(),message:s.message||"Unknown parsing error"}]}}}parseBlock(t){if(this.expect(n.KwDef),this.scanner.token===n.KwComp)this.parseComponent(t);else if(this.scanner.token===n.KwUnit)this.parseUnit(t);else throw new Error("Expected 'comp' or 'unit' after 'def'")}parseComponent(t){this.expect(n.KwComp);const s=this.expectValue(n.Identifier);this.expect(n.KwAs);const a=this.doc.createElementNS(f,"component");for(a.setAttribute("name",s),t.appendChild(a);this.scanner.token!==n.KwEndDef&&this.scanner.token!==n.EOF;)this.scanner.token===n.KwVar?this.parseVariable(a):this.scanner.token===n.Identifier||this.scanner.token===n.KwSel?this.parseMathEquation(a):this.scanner.nextToken();this.expect(n.KwEndDef),this.expect(n.SemiColon)}parseVariable(t){this.expect(n.KwVar);const s=this.expectValue(n.Identifier);this.expect(n.Colon);const a=this.expectValue(n.Identifier),e=this.doc.createElementNS(f,"variable");if(e.setAttribute("name",s),e.setAttribute("units",a),this.scanner.token===n.LBrace){for(this.scanner.nextToken();this.scanner.token!==n.RBrace&&this.scanner.token!==n.EOF;){const i=this.expectValue(n.Identifier);this.expect(n.Colon);let c="";this.scanner.token===n.OpMinus?(this.scanner.nextToken(),c="-"+this.expectValue(n.Number)):this.scanner.token===n.Number?c=this.expectValue(n.Number):c=this.expectValue(n.Identifier),i==="init"?e.setAttribute("initial_value",c):i==="interface"&&e.setAttribute("interface",c),this.scanner.token===n.OpComma&&this.scanner.nextToken()}this.expect(n.RBrace)}this.expect(n.SemiColon),t.appendChild(e)}parseUnit(t){for(this.expect(n.KwUnit);this.scanner.token!==n.KwEndDef&&this.scanner.token!==n.EOF;)this.scanner.nextToken();this.expect(n.KwEndDef),this.expect(n.SemiColon)}parseMathEquation(t){const s=this.scanner.getLine();let a=t.getElementsByTagNameNS(h,"math")[0];a||(a=this.doc.createElementNS(h,"math"),t.appendChild(a));const e=this.doc.createElementNS(h,"apply"),i=this.doc.createElementNS(h,"eq");e.appendChild(i);const c=this.parseExpression();this.expect(n.OpAss);const o=this.parseExpression(),u=this.scanner.getLine();this.sourceLineAttr&&e.setAttribute(this.sourceLineAttr,`${s.toString()}`+(u!==s?`-${u.toString()}`:"")),e.appendChild(c),e.appendChild(o),a.appendChild(e),this.expect(n.SemiColon)}parseCondition(){let t=this.parseComparison();for(;this.scanner.token===n.OpAnd||this.scanner.token===n.OpOr;){const s=this.scanner.token;this.scanner.nextToken();const a=this.parseComparison(),e=this.doc.createElementNS(h,"apply"),i=this.doc.createElementNS(h,s===n.OpAnd?"and":"or");e.appendChild(i),e.appendChild(t),e.appendChild(a),t=e}return t}isComparisonToken(t){return[n.OpEq,n.OpNe,n.OpLt,n.OpLe,n.OpGt,n.OpGe].includes(t)}parseComparison(){let t=this.parseExpression();if(this.isComparisonToken(this.scanner.token)){const s=this.scanner.token;this.scanner.nextToken();const a=this.parseExpression(),e=this.doc.createElementNS(h,"apply");let i="";switch(s){case n.OpEq:i="eq";break;case n.OpNe:i="neq";break;case n.OpLt:i="lt";break;case n.OpLe:i="leq";break;case n.OpGt:i="gt";break;case n.OpGe:i="geq";break;case n.OpAnd:i="and";break}const c=this.doc.createElementNS(h,i);return e.appendChild(c),e.appendChild(t),e.appendChild(a),e}return t}parseExpression(){let t=this.parseTerm();for(;this.scanner.token===n.OpPlus||this.scanner.token===n.OpMinus;){const s=this.scanner.token;this.scanner.nextToken();const a=this.parseTerm(),e=this.doc.createElementNS(h,"apply"),i=this.doc.createElementNS(h,s===n.OpPlus?"plus":"minus");e.appendChild(i),e.appendChild(t),e.appendChild(a),t=e}return t}parseTerm(){let t=this.parseFactor();for(;this.scanner.token===n.OpTimes||this.scanner.token===n.OpDivide;){const s=this.scanner.token;this.scanner.nextToken();const a=this.parseFactor(),e=this.doc.createElementNS(h,"apply"),i=this.doc.createElementNS(h,s===n.OpTimes?"times":"divide");e.appendChild(i),e.appendChild(t),e.appendChild(a),t=e}return t}parseFactor(){if(this.scanner.token===n.OpMinus){this.scanner.nextToken();const t=this.parseFactor(),s=this.doc.createElementNS(h,"apply"),a=this.doc.createElementNS(h,"minus");return s.appendChild(a),s.appendChild(t),s}if(this.scanner.token===n.Number){const t=this.scanner.value;this.scanner.nextToken();const s=this.doc.createElementNS(h,"cn");if(s.textContent=t,this.scanner.token===n.LBrace){if(this.scanner.nextToken(),this.scanner.value==="units"){this.scanner.nextToken(),this.expect(n.Colon);const a=this.expectValue(n.Identifier);s.setAttributeNS(f,"cellml:units",a)}for(;this.scanner.token!==n.RBrace&&this.scanner.token!==n.EOF;)this.scanner.nextToken();this.expect(n.RBrace)}return s}else if(this.scanner.token===n.Identifier){const t=this.scanner.value;if(this.scanner.nextToken(),this.scanner.token===n.LParam)return this.parseFunctionCall(t);const s=this.doc.createElementNS(h,"ci");return s.textContent=t,s}else if(this.scanner.token===n.LParam){this.scanner.nextToken();const t=this.parseExpression();return this.expect(n.RParam),t}else if(this.scanner.token===n.KwSel)return this.parsePiecewise();throw new Error(`Unexpected token in math: ${this.scanner.value}`)}parsePiecewise(){const t=this.doc.createElementNS(h,"piecewise");for(this.expect(n.KwSel);this.scanner.token===n.KwCase;){this.expect(n.KwCase);const s=this.parseCondition();this.expect(n.Colon);const a=this.parseExpression();this.expect(n.SemiColon);const e=this.doc.createElementNS(h,"piece");e.appendChild(a),e.appendChild(s),t.appendChild(e)}if(this.scanner.token===n.KwOtherwise){this.expect(n.KwOtherwise),this.expect(n.Colon);const s=this.parseExpression();this.expect(n.SemiColon);const a=this.doc.createElementNS(h,"otherwise");a.appendChild(s),t.appendChild(a)}return this.expect(n.KwEndSel),t}parseFunctionCall(t){if(this.expect(n.LParam),t==="ode"){const e=this.parseExpression();this.expect(n.OpComma);const i=this.parseExpression();this.expect(n.RParam);const c=this.doc.createElementNS(h,"apply");c.appendChild(this.doc.createElementNS(h,"diff"));const o=this.doc.createElementNS(h,"bvar");return o.appendChild(i),c.appendChild(o),c.appendChild(e),c}const s=this.doc.createElementNS(h,"apply"),a=this.doc.createElementNS(h,t);if(s.appendChild(a),this.scanner.token!==n.RParam)do this.scanner.token===n.OpComma&&this.scanner.nextToken(),s.appendChild(this.parseExpression());while(this.scanner.token===n.OpComma);return this.expect(n.RParam),s}expect(t){if(this.scanner.token!==t)throw new Error(`Syntax Error: Expected ${n[t]} but found '${this.scanner.value}'`);this.scanner.nextToken()}expectValue(t){if(this.scanner.token!==t)throw new Error(`Expected value of type ${n[t]}, got ${this.scanner.token}`);const s=this.scanner.value;return this.scanner.nextToken(),s}serialize(t,s=0){const a=" ".repeat(s),e=t.tagName,i=t.localName;let c="";for(let d=0;d<t.attributes.length;d++){const w=t.attributes[d];if(w){if(this.sourceLineAttr&&w.name===this.sourceLineAttr)continue;c+=` ${w.name}="${w.value}"`}}i==="model"&&!t.hasAttribute("xmlns")&&(c+=` xmlns="${f}"`),i==="math"&&!t.hasAttribute("xmlns")&&(c+=` xmlns="${h}" xmlns:cellml="${f}"`);const o=Array.from(t.childNodes),u=o.some(d=>d.nodeType===1),l=t.textContent?.trim();if(o.length===0&&!l)return`${a}<${e}${c}/>`;if(!u)return`${a}<${e}${c}>${l}</${e}>`;let p=`${a}<${e}${c}>
5
- `;return o.forEach(d=>{d.nodeType===1&&(p+=this.serialize(d,s+1)+`
6
- `)}),p+=`${a}</${e}>`,p}}const C="http://www.cellml.org/cellml/2.0#";class N{output="";indentLevel=0;domParser;standardIndent=" ";constructor(){this.domParser=new DOMParser}indent(){return this.standardIndent.repeat(this.indentLevel)}append(t,s=!0){this.output+=(s?this.indent():"")+t+(s?`
7
- `:"")}generate(t){this.output="",this.indentLevel=0;try{const s=this.domParser.parseFromString(t,"application/xml");if(s.querySelector("parsererror"))throw new Error("XML Parsing Error");const e=s.getElementsByTagNameNS("http://www.cellml.org/cellml/2.0#","model")[0];if(!e)throw new Error("No CellML 2.0 Model found");this.processModel(e)}catch(s){return`// Error generating text: ${s.message}`}return this.output}processModel(t){const s=t.getAttribute("name")||"unnamed_model";this.append(`def model ${s} as`),this.indentLevel++;const a=t.getElementsByTagName("units");for(let i=0;i<a.length;i++)a[i]?.parentElement===t&&this.processUnits(a[i]);const e=t.getElementsByTagName("component");for(let i=0;i<e.length;i++)this.processComponent(e[i]);this.indentLevel--,this.append("enddef;")}processUnits(t){const s=t?.getAttribute("name")||"unnamed_units";this.append(`def unit ${s} as`),this.indentLevel++;const a=t?.getElementsByTagName("unit")||[];for(let e=0;e<a.length;e++){const i=a[e];if(!i)continue;const c=i.getAttribute("prefix"),o=i.getAttribute("units"),u=i.getAttribute("exponent"),l=i.getAttribute("multiplier");let p=`unit ${o}`;c&&(p+=` {prefix: ${c}}`),u&&(p+=` {exponent: ${u}}`),l&&(p+=` {multiplier: ${l}}`),p+=";",this.append(p)}this.indentLevel--,this.append("enddef;"),this.append("")}processComponent(t){const s=t?.getAttribute("name")||"unnamed_component";this.append(`def comp ${s} as`),this.indentLevel++;const a=t?.getElementsByTagName("variable")||[];for(let i=0;i<a.length;i++)this.processVariable(a[i]);const e=t?.getElementsByTagNameNS("http://www.w3.org/1998/Math/MathML","math")||[];for(let i=0;i<e.length;i++)this.processMath(e[i]);this.indentLevel--,this.append("enddef;"),this.append("")}processVariable(t){const s=t?.getAttribute("name"),a=t?.getAttribute("units"),e=t?.getAttribute("initial_value"),i=t?.getAttribute("interface");let c=`var ${s}: ${a}`,o=[];e&&o.push(`init: ${e}`),i&&o.push(`interface: ${i}`),o.length>0&&(c+=` {${o.join(", ")}}`),c+=";",this.append(c)}processMath(t){const s=Array.from(t?.children||[]);for(const a of s)if(a.localName==="apply"&&a.firstElementChild?.localName==="eq"){const i=Array.from(a.children).slice(1),c=this.parseMathNode(i[0]),o=this.parseMathNode(i[1]);this.append(`${c} = ${o};`)}else{const i=this.parseMathNode(a);i&&this.append(i+";")}}parseMathNode(t){if(!t)return"";const s=t.localName;if(s==="apply")return this.parseApply(t);if(s==="ci")return t.textContent?.trim()||"";if(s==="cn"){const a=t.textContent?.trim()||"0",e=t.getAttributeNS(C,"units");return e?`${a} {units: ${e}}`:a}else{if(s==="piecewise")return this.parsePiecewise(t);if(s==="pi")return"pi";if(s==="bvar")return""}return console.log(`Unsupported MathML node: ${s}`),`/* Unsupported MathML node: ${s} */`}parseApply(t){const s=Array.from(t.children);if(s.length===0)return"";const a=s[0]?.localName,e=s.slice(1).map(i=>this.parseMathNode(i));switch(a){case"plus":return`(${e.join(" + ")})`;case"minus":return e.length===1?`-${e[0]}`:`(${e[0]} - ${e[1]})`;case"times":return`(${e.join(" * ")})`;case"divide":return`(${e[0]} / ${e[1]})`;case"eq":return`${e[0]} == ${e[1]}`;case"neq":return`${e[0]} != ${e[1]}`;case"lt":return`${e[0]} < ${e[1]}`;case"leq":return`${e[0]} <= ${e[1]}`;case"gt":return`${e[0]} > ${e[1]}`;case"geq":return`${e[0]} >= ${e[1]}`;case"and":return`${e.join(" and ")}`;case"or":return`${e.join(" or ")}`;case"diff":const i=s.find(l=>l.localName==="bvar"),c=s.find(l=>l.localName!=="diff"&&l.localName!=="bvar"),o=i?.children[0]?.textContent||"t";return`ode(${c?this.parseMathNode(c):"unknown"}, ${o})`;case"sin":case"cos":case"tan":case"exp":case"ln":case"log":return`${a}(${e[0]})`;case"root":return`sqrt(${e[0]})`;default:return`${a}(${e.join(", ")})`}}parsePiecewise(t){let s=[];return Array.from(t?.children||[]).forEach(e=>{if(e.localName==="piece"){const i=this.parseMathNode(e.children[0]),c=this.parseMathNode(e.children[1]);s.push(`${this.standardIndent}case ${c}: ${i};`)}else if(e.localName==="otherwise"){const i=this.parseMathNode(e.children[0]);s.push(`${this.standardIndent}otherwise: ${i};`)}}),`sel
1
+ (function(m,n){typeof exports=="object"&&typeof module<"u"?n(exports):typeof define=="function"&&define.amd?define(["exports"],n):(m=typeof globalThis<"u"?globalThis:m||self,n(m.CellMLTextEditor={}))})(this,(function(m){"use strict";var n=(a=>(a[a.Unknown=0]="Unknown",a[a.EOF=1]="EOF",a[a.Identifier=2]="Identifier",a[a.Number=3]="Number",a[a.String=4]="String",a[a.KwDef=5]="KwDef",a[a.KwModel=6]="KwModel",a[a.KwComp=7]="KwComp",a[a.KwEndDef=8]="KwEndDef",a[a.KwAs=9]="KwAs",a[a.KwVar=10]="KwVar",a[a.KwUnit=11]="KwUnit",a[a.KwSel=12]="KwSel",a[a.KwCase=13]="KwCase",a[a.KwOtherwise=14]="KwOtherwise",a[a.KwEndSel=15]="KwEndSel",a[a.OpAss=16]="OpAss",a[a.OpPlus=17]="OpPlus",a[a.OpMinus=18]="OpMinus",a[a.OpTimes=19]="OpTimes",a[a.OpDivide=20]="OpDivide",a[a.OpComma=21]="OpComma",a[a.Colon=22]="Colon",a[a.SemiColon=23]="SemiColon",a[a.LParam=24]="LParam",a[a.RParam=25]="RParam",a[a.LBrace=26]="LBrace",a[a.RBrace=27]="RBrace",a[a.OpEq=28]="OpEq",a[a.OpNe=29]="OpNe",a[a.OpLt=30]="OpLt",a[a.OpLe=31]="OpLe",a[a.OpGt=32]="OpGt",a[a.OpGe=33]="OpGe",a[a.OpAnd=34]="OpAnd",a[a.OpOr=35]="OpOr",a))(n||{});class ${input;pos=0;line=1;length;currentToken=1;currentValue="";constructor(e){this.input=e,this.length=e.length,this.nextToken()}get token(){return this.currentToken}get value(){return this.currentValue}nextToken(){const e=this.skipWhitespace();if(this.line+=e,this.pos>=this.length){this.currentToken=1;return}const s=this.input[this.pos];if(/[a-zA-Z_]/.test(s||"")){let i=this.pos;for(;this.pos<this.length&&/[a-zA-Z0-9_]/.test(this.input[this.pos]||"");)this.pos++;const t=this.input.slice(i,this.pos);this.currentValue=t,this.currentToken=this.getKeywordType(t);return}if(/[0-9]/.test(s||"")||s==="."&&/[0-9]/.test(this.input[this.pos+1]||"")){let i=this.pos;for(;this.pos<this.length&&/[0-9]/.test(this.input[this.pos]||"");)this.pos++;if(this.input[this.pos]===".")for(this.pos++;this.pos<this.length&&/[0-9]/.test(this.input[this.pos]||"");)this.pos++;if(this.input[this.pos]==="e"||this.input[this.pos]==="E")for(this.pos++,(this.input[this.pos]==="+"||this.input[this.pos]==="-")&&this.pos++;this.pos<this.length&&/[0-9]/.test(this.input[this.pos]||"");)this.pos++;this.currentValue=this.input.slice(i,this.pos),this.currentToken=3;return}switch(this.pos++,this.currentValue=s||"",s){case"=":this.input[this.pos]==="="?(this.pos++,this.currentValue="==",this.currentToken=28):this.currentToken=16;break;case"!":this.input[this.pos]==="="?(this.pos++,this.currentValue="!=",this.currentToken=29):(console.warn(`Unexpected character '!' at pos ${this.pos}`),this.currentToken=0);break;case"<":this.input[this.pos]==="="?(this.pos++,this.currentValue="<=",this.currentToken=31):this.currentToken=30;break;case">":this.input[this.pos]==="="?(this.pos++,this.currentValue=">=",this.currentToken=33):this.currentToken=32;break;case"+":this.currentToken=17;break;case"-":this.currentToken=18;break;case"*":this.currentToken=19;break;case"/":this.currentToken=20;break;case"(":this.currentToken=24;break;case")":this.currentToken=25;break;case"{":this.currentToken=26;break;case"}":this.currentToken=27;break;case":":this.currentToken=22;break;case";":this.currentToken=23;break;case",":this.currentToken=21;break;default:console.warn("Unknown char:",s),this.currentToken=0}}getLine(){return this.line}skipWhitespace(){let e=0;for(;this.pos<this.length;){const s=this.input[this.pos];if(/\s/.test(s||""))s===`
2
+ `&&e++,this.pos++;else if(s==="/"&&this.input[this.pos+1]==="/")for(this.pos+=2;this.pos<this.length&&this.input[this.pos]!==`
3
+ `;)this.pos++;else break}return e}getKeywordType(e){switch(e){case"def":return 5;case"model":return 6;case"comp":return 7;case"enddef":return 8;case"as":return 9;case"var":return 10;case"unit":return 11;case"sel":return 12;case"case":return 13;case"otherwise":return 14;case"endsel":return 15;case"and":return 34;case"or":return 35;default:return 2}}}const f="http://www.cellml.org/cellml/2.0#",o="http://www.w3.org/1998/Math/MathML";class g{scanner;doc;sourceLineAttr;constructor(e={}){this.sourceLineAttr=e.sourceLineAttribute===void 0?"data-source-location":e.sourceLineAttribute}parse(e){this.scanner=new $(e),this.doc=document.implementation.createDocument(f,"model",null);try{const s=this.doc.documentElement;for(this.expect(n.KwDef),this.expect(n.KwModel),this.scanner.token===n.Identifier&&(s.setAttribute("name",this.scanner.value),this.scanner.nextToken()),this.expect(n.KwAs);this.scanner.token!==n.KwEndDef&&this.scanner.token!==n.EOF;)this.scanner.token===n.KwDef?this.parseBlock(s):this.scanner.nextToken();return this.expect(n.KwEndDef),this.expect(n.SemiColon),{xml:`<?xml version="1.0" encoding="UTF-8"?>
4
+ `+this.serialize(s),errors:[]}}catch(s){return{xml:null,errors:[{line:this.scanner.getLine(),message:s.message||"Unknown parsing error"}]}}}parseBlock(e){if(this.expect(n.KwDef),this.scanner.token===n.KwComp)this.parseComponent(e);else if(this.scanner.token===n.KwUnit)this.parseUnit(e);else throw new Error("Expected 'comp' or 'unit' after 'def'")}parseComponent(e){this.expect(n.KwComp);const s=this.expectValue(n.Identifier);this.expect(n.KwAs);const i=this.doc.createElementNS(f,"component");for(i.setAttribute("name",s),e.appendChild(i);this.scanner.token!==n.KwEndDef&&this.scanner.token!==n.EOF;)this.scanner.token===n.KwVar?this.parseVariable(i):this.scanner.token===n.Identifier||this.scanner.token===n.KwSel?this.parseMathEquation(i):this.scanner.nextToken();this.expect(n.KwEndDef),this.expect(n.SemiColon)}parseVariable(e){this.expect(n.KwVar);const s=this.expectValue(n.Identifier);this.expect(n.Colon);const i=this.expectValue(n.Identifier),t=this.doc.createElementNS(f,"variable");if(t.setAttribute("name",s),t.setAttribute("units",i),this.scanner.token===n.LBrace){for(this.scanner.nextToken();this.scanner.token!==n.RBrace&&this.scanner.token!==n.EOF;){const r=this.expectValue(n.Identifier);this.expect(n.Colon);let c="";this.scanner.token===n.OpMinus?(this.scanner.nextToken(),c="-"+this.expectValue(n.Number)):this.scanner.token===n.Number?c=this.expectValue(n.Number):c=this.expectValue(n.Identifier),r==="init"?t.setAttribute("initial_value",c):r==="interface"&&t.setAttribute("interface",c),this.scanner.token===n.OpComma&&this.scanner.nextToken()}this.expect(n.RBrace)}this.expect(n.SemiColon),e.appendChild(t)}parseUnit(e){for(this.expect(n.KwUnit);this.scanner.token!==n.KwEndDef&&this.scanner.token!==n.EOF;)this.scanner.nextToken();this.expect(n.KwEndDef),this.expect(n.SemiColon)}parseMathEquation(e){const s=this.scanner.getLine();let i=e.getElementsByTagNameNS(o,"math")[0];i||(i=this.doc.createElementNS(o,"math"),e.appendChild(i));const t=this.doc.createElementNS(o,"apply"),r=this.doc.createElementNS(o,"eq");t.appendChild(r);const c=this.parseExpression();this.expect(n.OpAss);const h=this.parseExpression(),u=this.scanner.getLine();this.sourceLineAttr&&t.setAttribute(this.sourceLineAttr,`${s.toString()}`+(u!==s?`-${u.toString()}`:"")),t.appendChild(c),t.appendChild(h),i.appendChild(t),this.expect(n.SemiColon)}parseCondition(){let e=this.parseComparison();for(;this.scanner.token===n.OpAnd||this.scanner.token===n.OpOr;){const s=this.scanner.token;this.scanner.nextToken();const i=this.parseComparison(),t=this.doc.createElementNS(o,"apply"),r=this.doc.createElementNS(o,s===n.OpAnd?"and":"or");t.appendChild(r),t.appendChild(e),t.appendChild(i),e=t}return e}isComparisonToken(e){return[n.OpEq,n.OpNe,n.OpLt,n.OpLe,n.OpGt,n.OpGe].includes(e)}parseComparison(){let e=this.parseExpression();if(this.isComparisonToken(this.scanner.token)){const s=this.scanner.token;this.scanner.nextToken();const i=this.parseExpression(),t=this.doc.createElementNS(o,"apply");let r="";switch(s){case n.OpEq:r="eq";break;case n.OpNe:r="neq";break;case n.OpLt:r="lt";break;case n.OpLe:r="leq";break;case n.OpGt:r="gt";break;case n.OpGe:r="geq";break;case n.OpAnd:r="and";break}const c=this.doc.createElementNS(o,r);return t.appendChild(c),t.appendChild(e),t.appendChild(i),t}return e}isMathMLApply(e,s){if(e.localName!=="apply")return!1;const i=e.firstElementChild;return i?i.localName===s:!1}parseExpression(){let e=this.parseTerm();for(;this.scanner.token===n.OpPlus||this.scanner.token===n.OpMinus;){const s=this.scanner.token;this.scanner.nextToken();const i=this.parseTerm();if(s===n.OpPlus&&this.isMathMLApply(e,"plus"))e.appendChild(i);else{const t=this.doc.createElementNS(o,"apply"),r=this.doc.createElementNS(o,s===n.OpPlus?"plus":"minus");t.appendChild(r),t.appendChild(e),t.appendChild(i),e=t}}return e}parseTerm(){let e=this.parseFactor();for(;this.scanner.token===n.OpTimes||this.scanner.token===n.OpDivide;){const s=this.scanner.token;this.scanner.nextToken();const i=this.parseFactor();if(s===n.OpTimes&&this.isMathMLApply(e,"times"))e.appendChild(i);else{const t=this.doc.createElementNS(o,"apply"),r=this.doc.createElementNS(o,s===n.OpTimes?"times":"divide");t.appendChild(r),t.appendChild(e),t.appendChild(i),e=t}}return e}createMathMLConstant(e){const s={pi:"pi",e:"exponentiale",inf:"infinity",infinity:"infinity",NaN:"notanumber",true:"true",false:"false"};return s.hasOwnProperty(e)?this.doc.createElementNS(o,s[e]||""):null}parseFactor(){if(this.scanner.token===n.OpMinus){this.scanner.nextToken();const e=this.parseFactor(),s=this.doc.createElementNS(o,"apply"),i=this.doc.createElementNS(o,"minus");return s.appendChild(i),s.appendChild(e),s}if(this.scanner.token===n.Number){const e=this.scanner.value;this.scanner.nextToken();const s=this.doc.createElementNS(o,"cn");if(s.textContent=e,this.scanner.token===n.LBrace){if(this.scanner.nextToken(),this.scanner.value==="units"){this.scanner.nextToken(),this.expect(n.Colon);const i=this.expectValue(n.Identifier);s.setAttributeNS(f,"cellml:units",i)}for(;this.scanner.token!==n.RBrace&&this.scanner.token!==n.EOF;)this.scanner.nextToken();this.expect(n.RBrace)}return s}else if(this.scanner.token===n.Identifier){const e=this.scanner.value;if(this.scanner.nextToken(),this.scanner.token===n.LParam)return this.parseFunctionCall(e);const s=this.createMathMLConstant(e);if(s)return s;const i=this.doc.createElementNS(o,"ci");return i.textContent=e,i}else if(this.scanner.token===n.LParam){this.scanner.nextToken();const e=this.parseExpression();return this.expect(n.RParam),e}else if(this.scanner.token===n.KwSel)return this.parsePiecewise();throw new Error(`Unexpected token in math: ${this.scanner.value}`)}parsePiecewise(){const e=this.doc.createElementNS(o,"piecewise");for(this.expect(n.KwSel);this.scanner.token===n.KwCase;){this.expect(n.KwCase);const s=this.parseCondition();this.expect(n.Colon);const i=this.parseExpression();this.expect(n.SemiColon);const t=this.doc.createElementNS(o,"piece");t.appendChild(i),t.appendChild(s),e.appendChild(t)}if(this.scanner.token===n.KwOtherwise){this.expect(n.KwOtherwise),this.expect(n.Colon);const s=this.parseExpression();this.expect(n.SemiColon);const i=this.doc.createElementNS(o,"otherwise");i.appendChild(s),e.appendChild(i)}return this.expect(n.KwEndSel),e}parseFunctionCall(e){if(this.expect(n.LParam),e==="ode"){const t=this.parseExpression();this.expect(n.OpComma);const r=this.parseExpression();this.expect(n.RParam);const c=this.doc.createElementNS(o,"apply");c.appendChild(this.doc.createElementNS(o,"diff"));const h=this.doc.createElementNS(o,"bvar");return h.appendChild(r),c.appendChild(h),c.appendChild(t),c}const s=this.doc.createElementNS(o,"apply"),i=this.doc.createElementNS(o,e);if(s.appendChild(i),this.scanner.token!==n.RParam)do this.scanner.token===n.OpComma&&this.scanner.nextToken(),s.appendChild(this.parseExpression());while(this.scanner.token===n.OpComma);return this.expect(n.RParam),s}expect(e){if(this.scanner.token!==e)throw new Error(`Syntax Error: Expected ${n[e]} but found '${this.scanner.value}'`);this.scanner.nextToken()}expectValue(e){if(this.scanner.token!==e)throw new Error(`Expected value of type ${n[e]}, got ${this.scanner.token}`);const s=this.scanner.value;return this.scanner.nextToken(),s}serialize(e,s=0){const i=" ".repeat(s),t=e.tagName,r=e.localName;let c="";r==="model"&&!e.hasAttribute("xmlns")&&(c+=` xmlns="${f}"`),r==="math"&&!e.hasAttribute("xmlns")&&(c+=` xmlns="${o}" xmlns:cellml="${f}"`);for(let d=0;d<e.attributes.length;d++){const w=e.attributes[d];if(w){if(this.sourceLineAttr&&w.name===this.sourceLineAttr)continue;c+=` ${w.name}="${w.value}"`}}const h=Array.from(e.childNodes),u=h.some(d=>d.nodeType===1),l=e.textContent?.trim();if(h.length===0&&!l)return`${i}<${t}${c}/>`;if(!u)return`${i}<${t}${c}>${l}</${t}>`;let p=`${i}<${t}${c}>
5
+ `;return h.forEach(d=>{d.nodeType===1&&(p+=this.serialize(d,s+1)+`
6
+ `)}),p+=`${i}</${t}>`,p}}const C="http://www.cellml.org/cellml/2.0#";class N{output="";indentLevel=0;domParser;standardIndent=" ";constructor(){this.domParser=new DOMParser}indent(){return this.standardIndent.repeat(this.indentLevel)}append(e,s=!0){this.output+=(s?this.indent():"")+e+(s?`
7
+ `:"")}generate(e){this.output="",this.indentLevel=0;try{const s=this.domParser.parseFromString(e,"application/xml");if(s.querySelector("parsererror"))throw new Error("XML Parsing Error");const t=s.getElementsByTagNameNS("http://www.cellml.org/cellml/2.0#","model")[0];if(!t)throw new Error("No CellML 2.0 Model found");this.processModel(t)}catch(s){return`// Error generating text: ${s.message}`}return this.output}processModel(e){const s=e.getAttribute("name")||"unnamed_model";this.append(`def model ${s} as`),this.indentLevel++;const i=e.getElementsByTagName("units");for(let r=0;r<i.length;r++)i[r]?.parentElement===e&&this.processUnits(i[r]);const t=e.getElementsByTagName("component");for(let r=0;r<t.length;r++)this.processComponent(t[r]);this.indentLevel--,this.append("enddef;")}processUnits(e){const s=e?.getAttribute("name")||"unnamed_units";this.append(`def unit ${s} as`),this.indentLevel++;const i=e?.getElementsByTagName("unit")||[];for(let t=0;t<i.length;t++){const r=i[t];if(!r)continue;const c=r.getAttribute("prefix"),h=r.getAttribute("units"),u=r.getAttribute("exponent"),l=r.getAttribute("multiplier");let p=`unit ${h}`;c&&(p+=` {prefix: ${c}}`),u&&(p+=` {exponent: ${u}}`),l&&(p+=` {multiplier: ${l}}`),p+=";",this.append(p)}this.indentLevel--,this.append("enddef;"),this.append("")}processComponent(e){const s=e?.getAttribute("name")||"unnamed_component";this.append(`def comp ${s} as`),this.indentLevel++;const i=e?.getElementsByTagName("variable")||[];for(let r=0;r<i.length;r++)this.processVariable(i[r]);const t=e?.getElementsByTagNameNS("http://www.w3.org/1998/Math/MathML","math")||[];for(let r=0;r<t.length;r++)this.processMath(t[r]);this.indentLevel--,this.append("enddef;"),this.append("")}processVariable(e){const s=e?.getAttribute("name"),i=e?.getAttribute("units"),t=e?.getAttribute("initial_value"),r=e?.getAttribute("interface");let c=`var ${s}: ${i}`,h=[];t&&h.push(`init: ${t}`),r&&h.push(`interface: ${r}`),h.length>0&&(c+=` {${h.join(", ")}}`),c+=";",this.append(c)}processMath(e){const s=Array.from(e?.children||[]);for(const i of s)if(i.localName==="apply"&&i.firstElementChild?.localName==="eq"){const r=Array.from(i.children).slice(1),c=this.parseMathNode(r[0]),h=this.parseMathNode(r[1]);this.append(`${c} = ${h};`)}else{const r=this.parseMathNode(i);r&&this.append(r+";")}}parseMathNode(e){if(!e)return"";const s=e.localName;if(s==="apply")return this.parseApply(e);if(s==="ci")return e.textContent?.trim()||"";if(s==="cn"){const i=e.textContent?.trim()||"0",t=e.getAttributeNS(C,"units");return t?`${i} {units: ${t}}`:i}else{if(s==="piecewise")return this.parsePiecewise(e);if(s==="pi")return"pi";if(s==="bvar")return""}return console.log(`Unsupported MathML node: ${s}`),`/* Unsupported MathML node: ${s} */`}parseApply(e){const s=Array.from(e.children);if(s.length===0)return"";const i=s[0]?.localName,t=s.slice(1).map(r=>this.parseMathNode(r));switch(i){case"plus":return`(${t.join(" + ")})`;case"minus":return t.length===1?`-${t[0]}`:`(${t[0]} - ${t[1]})`;case"times":return`(${t.join(" * ")})`;case"divide":return`(${t[0]} / ${t[1]})`;case"eq":return`${t[0]} == ${t[1]}`;case"neq":return`${t[0]} != ${t[1]}`;case"lt":return`${t[0]} < ${t[1]}`;case"leq":return`${t[0]} <= ${t[1]}`;case"gt":return`${t[0]} > ${t[1]}`;case"geq":return`${t[0]} >= ${t[1]}`;case"and":return`${t.join(" and ")}`;case"or":return`${t.join(" or ")}`;case"diff":const r=s.find(l=>l.localName==="bvar"),c=s.find(l=>l.localName!=="diff"&&l.localName!=="bvar"),h=r?.children[0]?.textContent||"t";return`ode(${c?this.parseMathNode(c):"unknown"}, ${h})`;case"sin":case"cos":case"tan":case"exp":case"ln":case"log":return`${i}(${t[0]})`;case"root":return`sqrt(${t[0]})`;default:return`${i}(${t.join(", ")})`}}parsePiecewise(e){let s=[];return Array.from(e?.children||[]).forEach(t=>{if(t.localName==="piece"){const r=this.parseMathNode(t.children[0]),c=this.parseMathNode(t.children[1]);s.push(`${this.standardIndent}case ${c}: ${r};`)}else if(t.localName==="otherwise"){const r=this.parseMathNode(t.children[0]);s.push(`${this.standardIndent}otherwise: ${r};`)}}),`sel
8
8
  ${this.indent()}${s.join(`
9
9
  ${this.indent()}`)}
10
- ${this.indent()}endsel`}}class E{convert(t){if(!t)return"";if(t.localName==="math")return Array.from(t.children).map(s=>this.convert(s)).join(`
11
- `);if(t.localName==="apply"&&t.firstElementChild?.localName==="eq"){const s=Array.from(t.children),a=this.parseNode(s[1]),e=this.parseNode(s[2]);return`${a} = ${e}`}return this.parseNode(t)}parseNode(t){if(!t)return"";const s=t.localName;return s==="apply"?this.parseApply(t):s==="ci"?this.parseIdentifier(t.textContent||""):s==="cn"?t.textContent||"0":s==="piecewise"?this.parsePiecewise(t):""}escapeGreek(t){return["alpha","beta","gamma","delta","epsilon","zeta","eta","theta","iota","kappa","lambda","mu","nu","xi","omicron","pi","rho","sigma","tau","upsilon","phi","chi","psi","omega"].includes(t.toLowerCase())?`\\${t}`:t}parseIdentifier(t){if(!t.includes("_"))return this.escapeGreek(t);const s=t.split("_"),a=this.escapeGreek(s[0]||""),e=[];s[1]&&e.push(s[1]),s.length>4&&e.push(...s.slice(4));let i="";s.length===3&&(s[2]||[]).length===1?e.push(this.escapeGreek(s[2]||"")):s[2]&&(i=this.escapeGreek(s[2]),s[3]&&(i+=`_{${this.escapeGreek(s[3])}}`)),e.forEach((u,l)=>{e[l]=this.escapeGreek(u)});const c=e.join(",");let o=a;return c&&(o+=`_{${c}}`),i&&(o+=`^{${i}}`),o}parseApply(t){const s=Array.from(t?.children||[]),a=s[0]?.localName,e=s.slice(1).map(i=>this.parseNode(i));switch(a){case"plus":return e.join(" + ");case"minus":return e.length===1?`-${e[0]}`:`${e[0]} - ${e[1]}`;case"times":return e.join(" \\cdot ");case"divide":return`\\frac{${e[0]}}{${e[1]}}`;case"eq":return`${e[0]} == ${e[1]}`;case"neq":return`${e[0]} \\neq ${e[1]}`;case"lt":return`${e[0]} < ${e[1]}`;case"leq":return`${e[0]} \\leq ${e[1]}`;case"gt":return`${e[0]} > ${e[1]}`;case"geq":return`${e[0]} \\geq ${e[1]}`;case"and":return e.join(" \\land ");case"or":return e.join(" \\lor ");case"power":const i=s[1],c=e[0]||"",o=e[1];return i?.localName==="ci"||i?.localName==="cn"&&!c.trim().startsWith("-")?`{${c}}^{${o}}`:`\\left({${c}}\\right)^{${o}}`;case"root":case"sqrt":return`\\sqrt{${e[0]}}`;case"diff":const l=s.find(x=>x.localName==="bvar"),p=s.find(x=>x.localName!=="diff"&&x.localName!=="bvar"),d=l?this.parseNode(l.firstElementChild):"x";return`\\frac{d${p?this.parseNode(p):"y"}}{d${d}}`;case"exp":return`e^{${e[0]}}`;case"abs":return`\\left|${e[0]}\\right|`;case"floor":return`\\lfloor ${e[0]} \\rfloor`;case"ceil":return`\\lceil ${e[0]} \\rceil`;case"cos":case"cosh":case"log10":case"log":case"ln":case"max":case"min":case"sin":case"sinh":case"tan":case"tanh":return`\\${a}\\left(${e[0]}\\right)`;default:return console.log(`Unsupported MathML operator: ${a}`),`\\text{${a}}(${e.join(", ")})`}}parsePiecewise(t){let s="";return Array.from(t.children).forEach(e=>{if(e.localName==="piece"){const i=this.parseNode(e.children[0]),c=this.parseNode(e.children[1]);s+=`${i} & \\text{if } ${c} \\\\ `}else if(e.localName==="otherwise"){const i=this.parseNode(e.children[0]);s+=`${i} & \\text{otherwise}`}}),`\\begin{cases} ${s} \\end{cases}`}}m.CellMLLatexGenerator=E,m.CellMLTextGenerator=N,m.CellMLTextParser=g,Object.defineProperty(m,Symbol.toStringTag,{value:"Module"})}));
10
+ ${this.indent()}endsel`}}class E{convert(e){if(!e)return"";if(e.localName==="math")return Array.from(e.children).map(s=>this.convert(s)).join(`
11
+ `);if(e.localName==="apply"&&e.firstElementChild?.localName==="eq"){const s=Array.from(e.children),i=this.parseNode(s[1]),t=this.parseNode(s[2]);return`${i} = ${t}`}return this.parseNode(e)}parseNode(e){if(!e)return"";const s=e.localName;return s==="apply"?this.parseApply(e):s==="ci"?this.parseIdentifier(e.textContent||""):s==="cn"?e.textContent||"0":s==="piecewise"?this.parsePiecewise(e):""}escapeGreek(e){return["alpha","beta","gamma","delta","epsilon","zeta","eta","theta","iota","kappa","lambda","mu","nu","xi","omicron","pi","rho","sigma","tau","upsilon","phi","chi","psi","omega"].includes(e.toLowerCase())?`\\${e}`:e}parseIdentifier(e){if(!e.includes("_"))return this.escapeGreek(e);const s=e.split("_"),i=this.escapeGreek(s[0]||""),t=[];s[1]&&t.push(s[1]),s.length>4&&t.push(...s.slice(4));let r="";s.length===3&&(s[2]||[]).length===1?t.push(this.escapeGreek(s[2]||"")):s[2]&&(r=this.escapeGreek(s[2]),s[3]&&(r+=`_{${this.escapeGreek(s[3])}}`)),t.forEach((u,l)=>{t[l]=this.escapeGreek(u)});const c=t.join(",");let h=i;return c&&(h+=`_{${c}}`),r&&(h+=`^{${r}}`),h}parseApply(e){const s=Array.from(e?.children||[]),i=s[0]?.localName,t=s.slice(1).map(r=>this.parseNode(r));switch(i){case"plus":return t.join(" + ");case"minus":return t.length===1?`-${t[0]}`:`${t[0]} - ${t[1]}`;case"times":return t.join(" \\cdot ");case"divide":return`\\frac{${t[0]}}{${t[1]}}`;case"eq":return`${t[0]} == ${t[1]}`;case"neq":return`${t[0]} \\neq ${t[1]}`;case"lt":return`${t[0]} < ${t[1]}`;case"leq":return`${t[0]} \\leq ${t[1]}`;case"gt":return`${t[0]} > ${t[1]}`;case"geq":return`${t[0]} \\geq ${t[1]}`;case"and":return t.join(" \\land ");case"or":return t.join(" \\lor ");case"power":const r=s[1],c=t[0]||"",h=t[1];return r?.localName==="ci"||r?.localName==="cn"&&!c.trim().startsWith("-")?`{${c}}^{${h}}`:`\\left({${c}}\\right)^{${h}}`;case"root":case"sqrt":return`\\sqrt{${t[0]}}`;case"diff":const l=s.find(x=>x.localName==="bvar"),p=s.find(x=>x.localName!=="diff"&&x.localName!=="bvar"),d=l?this.parseNode(l.firstElementChild):"x";return`\\frac{d${p?this.parseNode(p):"y"}}{d${d}}`;case"exp":return`e^{${t[0]}}`;case"abs":return`\\left|${t[0]}\\right|`;case"floor":return`\\lfloor ${t[0]} \\rfloor`;case"ceil":return`\\lceil ${t[0]} \\rceil`;case"cos":case"cosh":case"log10":case"log":case"ln":case"max":case"min":case"sin":case"sinh":case"tan":case"tanh":return`\\${i}\\left(${t[0]}\\right)`;default:return console.log(`Unsupported MathML operator: ${i}`),`\\text{${i}}(${t.join(", ")})`}}parsePiecewise(e){let s="";return Array.from(e.children).forEach(t=>{if(t.localName==="piece"){const r=this.parseNode(t.children[0]),c=this.parseNode(t.children[1]);s+=`${r} & \\text{if } ${c} \\\\ `}else if(t.localName==="otherwise"){const r=this.parseNode(t.children[0]);s+=`${r} & \\text{otherwise}`}}),`\\begin{cases} ${s} \\end{cases}`}}m.CellMLLatexGenerator=E,m.CellMLTextGenerator=N,m.CellMLTextParser=g,Object.defineProperty(m,Symbol.toStringTag,{value:"Module"})}));
@@ -28,8 +28,18 @@ export declare class CellMLTextParser {
28
28
  private parseCondition;
29
29
  private isComparisonToken;
30
30
  private parseComparison;
31
+ /**
32
+ * Checks if an element is an <apply> block for a specific operator.
33
+ * e.g. isMathMLApply(node, 'plus') returns true for <apply><plus/>...</apply>
34
+ */
35
+ private isMathMLApply;
31
36
  private parseExpression;
32
37
  private parseTerm;
38
+ /**
39
+ * Checks if the identifier is a reserved MathML constant name
40
+ * and returns the corresponding element, or null if it's a variable.
41
+ */
42
+ private createMathMLConstant;
33
43
  private parseFactor;
34
44
  private parsePiecewise;
35
45
  private parseFunctionCall;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cellml-text-editor",
3
- "version": "0.1.3",
3
+ "version": "0.1.4",
4
4
  "description": "A CellML text editor library for parsing and generating CellML text representations.",
5
5
  "keywords": [
6
6
  "cellml",