@cortex-js/compute-engine 0.12.7 → 0.14.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.
Files changed (90) hide show
  1. package/dist/compute-engine.esm.js +1586 -998
  2. package/dist/compute-engine.js +1586 -998
  3. package/dist/compute-engine.min.esm.js +1586 -998
  4. package/dist/compute-engine.min.js +1586 -998
  5. package/dist/math-json.esm.js +2 -2
  6. package/dist/math-json.js +2 -2
  7. package/dist/math-json.min.esm.js +2 -2
  8. package/dist/math-json.min.js +2 -2
  9. package/dist/types/common/grapheme-splitter.d.ts +1 -1
  10. package/dist/types/common/signals.d.ts +1 -1
  11. package/dist/types/common/utils.d.ts +1 -1
  12. package/dist/types/compute-engine/assume.d.ts +1 -1
  13. package/dist/types/compute-engine/boxed-expression/abstract-boxed-expression.d.ts +4 -1
  14. package/dist/types/compute-engine/boxed-expression/box.d.ts +1 -1
  15. package/dist/types/compute-engine/boxed-expression/boxed-dictionary.d.ts +1 -1
  16. package/dist/types/compute-engine/boxed-expression/boxed-domain.d.ts +1 -1
  17. package/dist/types/compute-engine/boxed-expression/boxed-function-definition.d.ts +1 -1
  18. package/dist/types/compute-engine/boxed-expression/boxed-function.d.ts +1 -1
  19. package/dist/types/compute-engine/boxed-expression/boxed-number.d.ts +1 -1
  20. package/dist/types/compute-engine/boxed-expression/boxed-patterns.d.ts +1 -1
  21. package/dist/types/compute-engine/boxed-expression/boxed-string.d.ts +1 -1
  22. package/dist/types/compute-engine/boxed-expression/boxed-symbol-definition.d.ts +1 -1
  23. package/dist/types/compute-engine/boxed-expression/boxed-symbol.d.ts +1 -1
  24. package/dist/types/compute-engine/boxed-expression/expression-map.d.ts +1 -1
  25. package/dist/types/compute-engine/boxed-expression/order.d.ts +1 -1
  26. package/dist/types/compute-engine/boxed-expression/serialize.d.ts +1 -1
  27. package/dist/types/compute-engine/boxed-expression/utils.d.ts +1 -1
  28. package/dist/types/compute-engine/boxed-expression/validate.d.ts +1 -1
  29. package/dist/types/compute-engine/compile.d.ts +10 -0
  30. package/dist/types/compute-engine/compute-engine.d.ts +9 -8
  31. package/dist/types/compute-engine/cost-function.d.ts +1 -1
  32. package/dist/types/compute-engine/domain-utils.d.ts +1 -1
  33. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-algebra.d.ts +1 -1
  34. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-arithmetic.d.ts +1 -1
  35. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-calculus.d.ts +1 -1
  36. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-core.d.ts +1 -1
  37. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-inequalities.d.ts +1 -1
  38. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-logic.d.ts +1 -1
  39. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-other.d.ts +1 -1
  40. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-sets.d.ts +1 -1
  41. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-symbols.d.ts +1 -1
  42. package/dist/types/compute-engine/latex-syntax/dictionary/definitions-trigonometry.d.ts +1 -1
  43. package/dist/types/compute-engine/latex-syntax/dictionary/definitions.d.ts +32 -17
  44. package/dist/types/compute-engine/latex-syntax/latex-syntax.d.ts +1 -1
  45. package/dist/types/compute-engine/latex-syntax/parse-identifier.d.ts +12 -6
  46. package/dist/types/compute-engine/latex-syntax/parse.d.ts +30 -20
  47. package/dist/types/compute-engine/latex-syntax/public.d.ts +90 -47
  48. package/dist/types/compute-engine/latex-syntax/serialize-number.d.ts +1 -1
  49. package/dist/types/compute-engine/latex-syntax/serializer-style.d.ts +1 -1
  50. package/dist/types/compute-engine/latex-syntax/serializer.d.ts +4 -9
  51. package/dist/types/compute-engine/latex-syntax/tokenizer.d.ts +1 -1
  52. package/dist/types/compute-engine/library/arithmetic-add.d.ts +1 -2
  53. package/dist/types/compute-engine/library/arithmetic-divide.d.ts +1 -1
  54. package/dist/types/compute-engine/library/arithmetic-multiply.d.ts +1 -1
  55. package/dist/types/compute-engine/library/arithmetic-power.d.ts +1 -1
  56. package/dist/types/compute-engine/library/arithmetic.d.ts +1 -1
  57. package/dist/types/compute-engine/library/calculus.d.ts +1 -1
  58. package/dist/types/compute-engine/library/collections.d.ts +1 -1
  59. package/dist/types/compute-engine/library/core.d.ts +1 -1
  60. package/dist/types/compute-engine/library/domains.d.ts +1 -1
  61. package/dist/types/compute-engine/library/library.d.ts +1 -1
  62. package/dist/types/compute-engine/library/logic.d.ts +1 -1
  63. package/dist/types/compute-engine/library/polynomials.d.ts +1 -1
  64. package/dist/types/compute-engine/library/random-expression.d.ts +1 -1
  65. package/dist/types/compute-engine/library/relational-operator.d.ts +1 -1
  66. package/dist/types/compute-engine/library/sets.d.ts +1 -1
  67. package/dist/types/compute-engine/library/trigonometry.d.ts +1 -1
  68. package/dist/types/compute-engine/library/utils.d.ts +2 -1
  69. package/dist/types/compute-engine/numerics/numeric-bigint.d.ts +1 -1
  70. package/dist/types/compute-engine/numerics/numeric-bignum.d.ts +1 -1
  71. package/dist/types/compute-engine/numerics/numeric-complex.d.ts +1 -1
  72. package/dist/types/compute-engine/numerics/numeric.d.ts +1 -1
  73. package/dist/types/compute-engine/numerics/primes.d.ts +1 -1
  74. package/dist/types/compute-engine/numerics/rationals.d.ts +1 -1
  75. package/dist/types/compute-engine/public.d.ts +4 -1
  76. package/dist/types/compute-engine/rules.d.ts +1 -1
  77. package/dist/types/compute-engine/simplify-rules.d.ts +1 -1
  78. package/dist/types/compute-engine/solve.d.ts +1 -1
  79. package/dist/types/compute-engine/symbolic/expand.d.ts +1 -1
  80. package/dist/types/compute-engine/symbolic/flatten.d.ts +1 -1
  81. package/dist/types/compute-engine/symbolic/negate.d.ts +1 -1
  82. package/dist/types/compute-engine/symbolic/polynomials.d.ts +1 -1
  83. package/dist/types/compute-engine/symbolic/product.d.ts +1 -1
  84. package/dist/types/compute-engine/symbolic/sum.d.ts +1 -1
  85. package/dist/types/compute-engine/symbolic/utils.d.ts +1 -1
  86. package/dist/types/compute-engine.d.ts +2 -2
  87. package/dist/types/math-json/math-json-format.d.ts +1 -1
  88. package/dist/types/math-json/utils.d.ts +7 -1
  89. package/dist/types/math-json.d.ts +2 -2
  90. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- /** CortexJS Compute Engine 0.12.7 */
1
+ /** CortexJS Compute Engine 0.14.0 */
2
2
  (function(global,factory){typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'],factory):(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ComputeEngine = {}));})(this, (function (exports) { 'use strict';
3
3
  var ComputeEngine = (() => {
4
4
  var __create = Object.create;
@@ -3766,7 +3766,7 @@ var ComputeEngine = (() => {
3766
3766
  var DEFINITIONS_ALGEBRA = [
3767
3767
  {
3768
3768
  name: "To",
3769
- trigger: ["\\to"],
3769
+ latexTrigger: ["\\to"],
3770
3770
  kind: "infix",
3771
3771
  precedence: 270
3772
3772
  // MathML rightwards arrow
@@ -3971,6 +3971,14 @@ var ComputeEngine = (() => {
3971
3971
  return null;
3972
3972
  return s;
3973
3973
  }
3974
+ function isListLike(expr) {
3975
+ if (expr === null)
3976
+ return false;
3977
+ const h = head(expr);
3978
+ if (!h || typeof h !== "string")
3979
+ return false;
3980
+ return /^(List|Sequence|Tuple|Single|Pair|Triple)$/.test(h);
3981
+ }
3974
3982
  function keyValuePair(expr) {
3975
3983
  const h = head(expr);
3976
3984
  if (h === "KeyValuePair" || h === "Tuple" || h === "Pair") {
@@ -4020,10 +4028,10 @@ var ComputeEngine = (() => {
4020
4028
  return null;
4021
4029
  if (typeof expr === "number")
4022
4030
  return expr;
4023
- if (isNumberObject(expr))
4024
- return machineValueOfString(expr.num);
4025
4031
  if (typeof expr === "string")
4026
4032
  return machineValueOfString(expr);
4033
+ if (isNumberObject(expr))
4034
+ return machineValue(expr.num);
4027
4035
  return null;
4028
4036
  }
4029
4037
  function rationalValue(expr) {
@@ -4548,7 +4556,7 @@ var ComputeEngine = (() => {
4548
4556
  { name: "EulerGamma", serialize: "\\gamma" },
4549
4557
  {
4550
4558
  name: "Degrees",
4551
- trigger: ["\\degree"],
4559
+ latexTrigger: ["\\degree"],
4552
4560
  kind: "postfix",
4553
4561
  precedence: 880,
4554
4562
  parse: (_parser, lhs) => ["Degrees", lhs],
@@ -4557,67 +4565,83 @@ var ComputeEngine = (() => {
4557
4565
  }
4558
4566
  },
4559
4567
  {
4560
- trigger: ["\\degree"],
4568
+ latexTrigger: ["\\degree"],
4561
4569
  kind: "postfix",
4562
4570
  precedence: 880,
4563
4571
  parse: (_parser, lhs) => ["Degrees", lhs]
4564
4572
  },
4565
4573
  {
4566
- trigger: ["^", "<{>", "\\circ", "<}>"],
4574
+ latexTrigger: ["^", "<{>", "\\circ", "<}>"],
4567
4575
  kind: "postfix",
4568
4576
  parse: (_parser, lhs) => ["Degrees", lhs]
4569
4577
  },
4570
4578
  {
4571
- trigger: ["^", "\\circ"],
4579
+ latexTrigger: ["^", "\\circ"],
4572
4580
  kind: "postfix",
4573
4581
  parse: (_parser, lhs) => ["Degrees", lhs]
4574
4582
  },
4575
4583
  {
4576
- trigger: ["\xB0"],
4584
+ latexTrigger: ["\xB0"],
4577
4585
  kind: "postfix",
4578
4586
  precedence: 880,
4579
4587
  parse: (_parser, lhs) => ["Degrees", lhs]
4580
4588
  },
4581
4589
  {
4582
- trigger: ["\\ang"],
4590
+ latexTrigger: ["\\ang"],
4583
4591
  parse: (parser) => {
4584
4592
  const arg = parser.parseGroup();
4585
4593
  return arg === null ? ["Degrees"] : ["Degrees", arg];
4586
4594
  }
4587
4595
  },
4588
4596
  {
4589
- trigger: ["\\infty"],
4597
+ latexTrigger: ["\\infty"],
4590
4598
  parse: { num: "+Infinity" }
4591
4599
  },
4592
4600
  {
4593
4601
  name: "ComplexInfinity",
4594
- trigger: ["\\tilde", "\\infty"],
4602
+ latexTrigger: ["\\tilde", "\\infty"],
4595
4603
  serialize: "\\tilde\\infty"
4596
4604
  },
4597
4605
  {
4598
- trigger: ["\\tilde", "<{>", "\\infty", "<}>"],
4606
+ latexTrigger: ["\\tilde", "<{>", "\\infty", "<}>"],
4599
4607
  parse: "ComplexInfinity"
4600
4608
  },
4601
- { name: "Pi", kind: "symbol", trigger: ["\\pi"] },
4602
- { trigger: ["\u03C0"], parse: "Pi" },
4609
+ { name: "Pi", kind: "symbol", latexTrigger: ["\\pi"] },
4610
+ { latexTrigger: ["\u03C0"], parse: "Pi" },
4603
4611
  {
4604
4612
  name: "ExponentialE",
4605
- trigger: ["\\exponentialE"],
4613
+ latexTrigger: ["\\exponentialE"],
4606
4614
  parse: "ExponentialE",
4607
4615
  serialize: "\\exponentialE"
4608
4616
  },
4617
+ {
4618
+ latexTrigger: "\\operatorname{e}",
4619
+ parse: "ExponentialE"
4620
+ },
4621
+ {
4622
+ latexTrigger: "\\mathrm{e}",
4623
+ parse: "ExponentialE"
4624
+ },
4609
4625
  {
4610
4626
  kind: "function",
4611
- trigger: "exp",
4627
+ identifierTrigger: "exp",
4612
4628
  parse: "Exp"
4613
4629
  },
4614
4630
  {
4615
- trigger: "\\exp",
4631
+ latexTrigger: "\\exp",
4616
4632
  parse: "Exp"
4617
4633
  },
4618
4634
  {
4619
4635
  name: "ImaginaryUnit",
4620
- trigger: ["\\imaginaryI"]
4636
+ latexTrigger: ["\\imaginaryI"]
4637
+ },
4638
+ {
4639
+ latexTrigger: "\\operatorname{i}",
4640
+ parse: "ImaginaryUnit"
4641
+ },
4642
+ {
4643
+ latexTrigger: "\\mathrm{i}",
4644
+ parse: "ImaginaryUnit"
4621
4645
  },
4622
4646
  // Operations
4623
4647
  {
@@ -4627,18 +4651,18 @@ var ComputeEngine = (() => {
4627
4651
  * replaced with bars */
4628
4652
  name: "Abs",
4629
4653
  kind: "matchfix",
4630
- openDelimiter: "|",
4631
- closeDelimiter: "|",
4632
- parse: (_parser, expr) => isEmptySequence(expr) ? null : ["Abs", expr]
4654
+ openTrigger: "|",
4655
+ closeTrigger: "|",
4656
+ parse: (_parser, body) => isEmptySequence(body) ? null : ["Abs", body]
4633
4657
  },
4634
4658
  {
4635
- trigger: "abs",
4659
+ identifierTrigger: "abs",
4636
4660
  kind: "function",
4637
4661
  parse: "Abs"
4638
4662
  },
4639
4663
  {
4640
4664
  name: "Add",
4641
- trigger: ["+"],
4665
+ latexTrigger: ["+"],
4642
4666
  kind: "infix",
4643
4667
  associativity: "both",
4644
4668
  precedence: 275,
@@ -4654,7 +4678,7 @@ var ComputeEngine = (() => {
4654
4678
  },
4655
4679
  {
4656
4680
  kind: "prefix",
4657
- trigger: ["+"],
4681
+ latexTrigger: ["+"],
4658
4682
  precedence: 275,
4659
4683
  parse: (parser, until) => {
4660
4684
  if (until && 275 < until.minPrec)
@@ -4665,20 +4689,22 @@ var ComputeEngine = (() => {
4665
4689
  {
4666
4690
  name: "Ceil",
4667
4691
  kind: "matchfix",
4668
- openDelimiter: "\\lceil",
4669
- closeDelimiter: "\\rceil"
4692
+ openTrigger: "\\lceil",
4693
+ closeTrigger: "\\rceil",
4694
+ parse: (_parser, body) => isEmptySequence(body) ? null : ["Ceil", body]
4670
4695
  },
4671
4696
  {
4672
4697
  kind: "matchfix",
4673
- openDelimiter: ["\u2308"],
4674
- closeDelimiter: ["\u2309"],
4675
- parse: (_, body) => ["Ceil", body]
4698
+ openTrigger: ["\u2308"],
4699
+ closeTrigger: ["\u2309"],
4700
+ parse: (_parser, body) => isEmptySequence(body) ? null : ["Ceil", body]
4676
4701
  },
4677
4702
  {
4678
- trigger: "ceil",
4703
+ identifierTrigger: "ceil",
4679
4704
  kind: "function",
4680
4705
  parse: "Ceil"
4681
4706
  },
4707
+ { name: "Chop", identifierTrigger: "chop", kind: "function", parse: "Chop" },
4682
4708
  {
4683
4709
  name: "Complex",
4684
4710
  precedence: 274,
@@ -4698,7 +4724,7 @@ var ComputeEngine = (() => {
4698
4724
  },
4699
4725
  {
4700
4726
  name: "Divide",
4701
- trigger: "\\frac",
4727
+ latexTrigger: "\\frac",
4702
4728
  precedence: 660,
4703
4729
  // For \frac specifically, not for \div, etc..
4704
4730
  // handles Leibnitz notation for partial derivatives
@@ -4707,12 +4733,12 @@ var ComputeEngine = (() => {
4707
4733
  },
4708
4734
  {
4709
4735
  kind: "infix",
4710
- trigger: "\\over",
4736
+ latexTrigger: "\\over",
4711
4737
  precedence: 660,
4712
4738
  parse: "Divide"
4713
4739
  },
4714
4740
  {
4715
- trigger: ["\\/"],
4741
+ latexTrigger: ["\\/"],
4716
4742
  kind: "infix",
4717
4743
  associativity: "non",
4718
4744
  precedence: 660,
@@ -4722,14 +4748,14 @@ var ComputeEngine = (() => {
4722
4748
  parse: "Divide"
4723
4749
  },
4724
4750
  {
4725
- trigger: ["/"],
4751
+ latexTrigger: ["/"],
4726
4752
  kind: "infix",
4727
4753
  associativity: "non",
4728
4754
  precedence: 660,
4729
4755
  parse: "Divide"
4730
4756
  },
4731
4757
  {
4732
- trigger: ["\\div"],
4758
+ latexTrigger: ["\\div"],
4733
4759
  kind: "infix",
4734
4760
  associativity: "non",
4735
4761
  precedence: 660,
@@ -4747,36 +4773,41 @@ var ComputeEngine = (() => {
4747
4773
  },
4748
4774
  {
4749
4775
  name: "Factorial",
4750
- trigger: ["!"],
4776
+ latexTrigger: ["!"],
4751
4777
  kind: "postfix",
4752
4778
  precedence: 810
4753
4779
  },
4754
4780
  {
4755
4781
  name: "Factorial2",
4756
- trigger: ["!", "!"],
4782
+ latexTrigger: ["!", "!"],
4757
4783
  kind: "postfix",
4758
4784
  precedence: 810
4759
4785
  },
4760
4786
  {
4761
4787
  name: "Floor",
4762
4788
  kind: "matchfix",
4763
- openDelimiter: "\\lfloor",
4764
- closeDelimiter: "\\rfloor"
4789
+ openTrigger: "\\lfloor",
4790
+ closeTrigger: "\\rfloor",
4791
+ parse: (_parser, body) => isEmptySequence(body) ? null : ["Floor", body]
4765
4792
  },
4766
4793
  {
4767
4794
  kind: "matchfix",
4768
- openDelimiter: ["\u230A"],
4769
- closeDelimiter: ["\u230B"],
4770
- parse: (_, body) => ["Floor", body]
4795
+ openTrigger: ["\u230A"],
4796
+ closeTrigger: ["\u230B"],
4797
+ parse: (_parser, body) => isEmptySequence(body) ? null : ["Floor", body]
4771
4798
  },
4772
4799
  {
4773
- trigger: "floor",
4800
+ identifierTrigger: "floor",
4774
4801
  kind: "function",
4775
4802
  parse: "Floor"
4776
4803
  },
4804
+ {
4805
+ latexTrigger: ["\\Gamma"],
4806
+ parse: "Gamma"
4807
+ },
4777
4808
  {
4778
4809
  name: "Gcd",
4779
- trigger: "gcd",
4810
+ identifierTrigger: "gcd",
4780
4811
  kind: "function"
4781
4812
  },
4782
4813
  {
@@ -4785,34 +4816,34 @@ var ComputeEngine = (() => {
4785
4816
  },
4786
4817
  {
4787
4818
  name: "Lg",
4788
- trigger: ["\\lg"],
4819
+ latexTrigger: ["\\lg"],
4789
4820
  serialize: (serializer, expr) => "\\log_{10}" + serializer.wrapArguments(expr),
4790
4821
  parse: (parser) => {
4791
- const arg = parser.parseArguments("implicit");
4792
- if (arg === null)
4822
+ const args = parser.parseArguments("implicit");
4823
+ if (args === null)
4793
4824
  return "Lg";
4794
- return ["Log", ...arg, 10];
4825
+ return ["Log", ...args, 10];
4795
4826
  }
4796
4827
  },
4797
4828
  {
4798
4829
  name: "Lb",
4799
- trigger: "\\lb",
4830
+ latexTrigger: "\\lb",
4800
4831
  parse: (parser) => {
4801
- const arg = parser.parseArguments("implicit");
4802
- if (arg === null)
4832
+ const args = parser.parseArguments("implicit");
4833
+ if (args === null)
4803
4834
  return "Log";
4804
- return ["Log", ...arg, 2];
4835
+ return ["Log", ...args, 2];
4805
4836
  }
4806
4837
  },
4807
4838
  {
4808
4839
  name: "Ln",
4809
- trigger: ["\\ln"],
4840
+ latexTrigger: ["\\ln"],
4810
4841
  serialize: (serializer, expr) => "\\ln" + serializer.wrapArguments(expr),
4811
4842
  parse: (parser) => parseLog("Ln", parser)
4812
4843
  },
4813
4844
  {
4814
4845
  name: "Log",
4815
- trigger: ["\\log"],
4846
+ latexTrigger: ["\\log"],
4816
4847
  parse: (parser) => parseLog("Log", parser),
4817
4848
  serialize: (serializer, expr) => {
4818
4849
  const base = op2(expr);
@@ -4828,32 +4859,32 @@ var ComputeEngine = (() => {
4828
4859
  },
4829
4860
  {
4830
4861
  name: "Lcm",
4831
- trigger: "lcm",
4862
+ identifierTrigger: "lcm",
4832
4863
  kind: "function"
4833
4864
  },
4865
+ { name: "Max", identifierTrigger: "max", kind: "function" },
4866
+ { name: "Min", identifierTrigger: "min", kind: "function" },
4834
4867
  {
4835
4868
  name: "MinusPlus",
4836
- trigger: ["\\mp"],
4869
+ latexTrigger: ["\\mp"],
4837
4870
  kind: "infix",
4838
4871
  associativity: "both",
4839
4872
  precedence: 270
4840
4873
  },
4841
4874
  {
4842
4875
  name: "Multiply",
4843
- trigger: ["\\times"],
4876
+ latexTrigger: ["\\times"],
4844
4877
  kind: "infix",
4845
4878
  associativity: "both",
4846
4879
  precedence: 390,
4847
4880
  serialize: serializeMultiply
4848
4881
  },
4849
4882
  {
4850
- trigger: ["\\cdot"],
4883
+ latexTrigger: ["\\cdot"],
4851
4884
  kind: "infix",
4852
4885
  associativity: "both",
4853
4886
  precedence: 390,
4854
4887
  parse: (parser, lhs, terminator) => {
4855
- if (terminator && 391 < terminator.minPrec)
4856
- return null;
4857
4888
  const rhs = parser.parseExpression({ ...terminator, minPrec: 392 });
4858
4889
  if (rhs === null)
4859
4890
  return ["Multiply", lhs, MISSING];
@@ -4861,13 +4892,11 @@ var ComputeEngine = (() => {
4861
4892
  }
4862
4893
  },
4863
4894
  {
4864
- trigger: ["*"],
4895
+ latexTrigger: ["*"],
4865
4896
  kind: "infix",
4866
4897
  associativity: "both",
4867
4898
  precedence: 390,
4868
4899
  parse: (parser, lhs, terminator) => {
4869
- if (terminator && 391 < terminator.minPrec)
4870
- return null;
4871
4900
  const rhs = parser.parseExpression({ ...terminator, minPrec: 392 });
4872
4901
  if (rhs === null)
4873
4902
  return ["Multiply", lhs, MISSING];
@@ -4876,11 +4905,9 @@ var ComputeEngine = (() => {
4876
4905
  },
4877
4906
  {
4878
4907
  name: "Negate",
4879
- trigger: ["-"],
4908
+ latexTrigger: ["-"],
4880
4909
  kind: "prefix",
4881
4910
  parse: (parser, terminator) => {
4882
- if (terminator && 276 < terminator.minPrec)
4883
- return null;
4884
4911
  const rhs = parser.parseExpression({ ...terminator, minPrec: 400 });
4885
4912
  return ["Negate", missingIfEmpty(rhs)];
4886
4913
  },
@@ -4906,8 +4933,8 @@ var ComputeEngine = (() => {
4906
4933
  // /** If the argument is a vector */
4907
4934
  /** @todo: domain check */
4908
4935
  kind: "matchfix",
4909
- openDelimiter: "||",
4910
- closeDelimiter: "||",
4936
+ openTrigger: "||",
4937
+ closeTrigger: "||",
4911
4938
  parse: (_parser, expr) => isEmptySequence(expr) ? null : ["Norm", expr]
4912
4939
  },
4913
4940
  {
@@ -4915,12 +4942,13 @@ var ComputeEngine = (() => {
4915
4942
  /** @todo: domain check */
4916
4943
  name: "Norm",
4917
4944
  kind: "matchfix",
4918
- openDelimiter: ["\\left", "\\Vert"],
4919
- closeDelimiter: ["\\right", "\\Vert"]
4945
+ openTrigger: ["\\left", "\\Vert"],
4946
+ closeTrigger: ["\\right", "\\Vert"],
4947
+ parse: (_parser, expr) => isEmptySequence(expr) ? null : ["Norm", expr]
4920
4948
  },
4921
4949
  {
4922
4950
  name: "PlusMinus",
4923
- trigger: ["\\pm"],
4951
+ latexTrigger: ["\\pm"],
4924
4952
  kind: "infix",
4925
4953
  associativity: "both",
4926
4954
  precedence: 270,
@@ -4939,47 +4967,41 @@ var ComputeEngine = (() => {
4939
4967
  }
4940
4968
  },
4941
4969
  {
4942
- trigger: ["\\pm"],
4970
+ latexTrigger: ["\\pm"],
4943
4971
  kind: "prefix",
4944
4972
  precedence: 270,
4945
4973
  parse: (parser, terminator) => {
4946
- if (terminator && 270 < terminator.minPrec)
4947
- return null;
4948
4974
  const rhs = parser.parseExpression({ ...terminator, minPrec: 400 });
4949
4975
  return ["PlusMinus", missingIfEmpty(rhs)];
4950
4976
  }
4951
4977
  },
4952
4978
  {
4953
- trigger: ["\\plusmn"],
4979
+ latexTrigger: ["\\plusmn"],
4954
4980
  kind: "infix",
4955
4981
  associativity: "both",
4956
4982
  precedence: 270,
4957
4983
  parse: (parser, lhs, terminator) => {
4958
- if (270 < terminator.minPrec)
4959
- return null;
4960
4984
  const rhs = parser.parseExpression({ ...terminator, minPrec: 400 });
4961
4985
  return ["PlusMinus", lhs, missingIfEmpty(rhs)];
4962
4986
  }
4963
4987
  },
4964
4988
  {
4965
- trigger: ["\\plusmn"],
4989
+ latexTrigger: ["\\plusmn"],
4966
4990
  kind: "prefix",
4967
4991
  precedence: 270,
4968
4992
  parse: (parser, terminator) => {
4969
- if (terminator && 270 < terminator.minPrec)
4970
- return null;
4971
4993
  const rhs = parser.parseExpression({ ...terminator, minPrec: 400 });
4972
4994
  return ["PlusMinus", missingIfEmpty(rhs)];
4973
4995
  }
4974
4996
  },
4975
4997
  {
4976
4998
  name: "Power",
4977
- trigger: ["^"],
4999
+ latexTrigger: ["^"],
4978
5000
  kind: "infix",
4979
5001
  serialize: serializePower
4980
5002
  },
4981
5003
  {
4982
- trigger: "\\prod",
5004
+ latexTrigger: "\\prod",
4983
5005
  precedence: 390,
4984
5006
  name: "Product",
4985
5007
  parse: parseBigOp("Product", 390),
@@ -4996,7 +5018,7 @@ var ComputeEngine = (() => {
4996
5018
  precedence: 660,
4997
5019
  serialize: (serializer, expr) => {
4998
5020
  if (expr && nops(expr) === 1)
4999
- return "\\mathrm{Rational}" + serializer.wrapArguments(expr);
5021
+ return "\\operatorname{Rational}" + serializer.wrapArguments(expr);
5000
5022
  return serializeFraction(serializer, expr);
5001
5023
  }
5002
5024
  },
@@ -5006,7 +5028,7 @@ var ComputeEngine = (() => {
5006
5028
  },
5007
5029
  {
5008
5030
  name: "Round",
5009
- trigger: "round",
5031
+ identifierTrigger: "round",
5010
5032
  kind: "function"
5011
5033
  },
5012
5034
  {
@@ -5015,7 +5037,7 @@ var ComputeEngine = (() => {
5015
5037
  serialize: (serializer, expr) => serializer.wrapShort(op(expr, 1)) + "^2"
5016
5038
  },
5017
5039
  {
5018
- trigger: "\\sum",
5040
+ latexTrigger: ["\\sum"],
5019
5041
  precedence: 275,
5020
5042
  name: "Sum",
5021
5043
  parse: parseBigOp("Sum", 275),
@@ -5024,24 +5046,22 @@ var ComputeEngine = (() => {
5024
5046
  {
5025
5047
  name: "Sign",
5026
5048
  // As per ISO 80000-2, "signum" is 'sgn'
5027
- trigger: "sgn",
5049
+ identifierTrigger: "sgn",
5028
5050
  kind: "function"
5029
5051
  },
5030
5052
  {
5031
5053
  name: "Sqrt",
5032
- trigger: ["\\sqrt"],
5054
+ latexTrigger: ["\\sqrt"],
5033
5055
  parse: parseRoot,
5034
5056
  serialize: serializePower
5035
5057
  },
5036
5058
  {
5037
5059
  name: "Subtract",
5038
- trigger: ["-"],
5060
+ latexTrigger: ["-"],
5039
5061
  kind: "infix",
5040
5062
  associativity: "both",
5041
5063
  precedence: 275,
5042
5064
  parse: (parser, lhs, terminator) => {
5043
- if (276 < terminator.minPrec)
5044
- return null;
5045
5065
  const rhs = parser.parseExpression({ ...terminator, minPrec: 277 });
5046
5066
  return ["Subtract", lhs, missingIfEmpty(rhs)];
5047
5067
  }
@@ -5138,16 +5158,16 @@ var ComputeEngine = (() => {
5138
5158
  sub2 = parser.parseStringGroup()?.trim() ?? parser.nextToken();
5139
5159
  base = Number.parseFloat(sub2 ?? "10");
5140
5160
  }
5141
- const arg = parser.parseArguments("implicit");
5142
- if (arg === null)
5161
+ const args = parser.parseArguments("implicit");
5162
+ if (args === null)
5143
5163
  return [command];
5144
5164
  if (base === 10)
5145
- return ["Log", arg[0]];
5165
+ return ["Log", args[0]];
5146
5166
  if (base === 2)
5147
- return ["Lb", ...arg];
5167
+ return ["Lb", ...args];
5148
5168
  if (sub2 === null)
5149
- return [command, ...arg];
5150
- return ["Log", ...arg, sub2];
5169
+ return [command, ...args];
5170
+ return ["Log", ...args, sub2];
5151
5171
  }
5152
5172
 
5153
5173
  // src/compute-engine/latex-syntax/dictionary/definitions-core.ts
@@ -5178,7 +5198,7 @@ var ComputeEngine = (() => {
5178
5198
  }
5179
5199
  return result;
5180
5200
  }
5181
- function serializeSequence(sep = "") {
5201
+ function serializeOps(sep = "") {
5182
5202
  return (serializer, expr) => (ops(expr) ?? []).map((x) => serializer.serialize(x)).join(sep);
5183
5203
  }
5184
5204
  var DEFINITIONS_CORE = [
@@ -5186,7 +5206,7 @@ var ComputeEngine = (() => {
5186
5206
  // Constants
5187
5207
  //
5188
5208
  {
5189
- trigger: ["\\placeholder"],
5209
+ latexTrigger: ["\\placeholder"],
5190
5210
  kind: "symbol",
5191
5211
  parse: (parser) => {
5192
5212
  while (parser.match("<space>")) {
@@ -5205,6 +5225,27 @@ var ComputeEngine = (() => {
5205
5225
  //
5206
5226
  // Functions
5207
5227
  //
5228
+ {
5229
+ name: "Apply",
5230
+ kind: "function",
5231
+ identifierTrigger: "apply",
5232
+ serialize: (serializer, expr) => serializer.serializeFunction(ops(expr))
5233
+ },
5234
+ {
5235
+ latexTrigger: "\\rhd",
5236
+ kind: "infix",
5237
+ precedence: 20,
5238
+ parse: "Apply"
5239
+ },
5240
+ {
5241
+ latexTrigger: "\\lhd",
5242
+ kind: "infix",
5243
+ precedence: 20,
5244
+ parse: (parser, lhs) => {
5245
+ const rhs = parser.parseExpression({ minPrec: 20 }) ?? "Nothing";
5246
+ return ["Apply", rhs, lhs];
5247
+ }
5248
+ },
5208
5249
  {
5209
5250
  name: "BaseForm",
5210
5251
  serialize: (serializer, expr) => {
@@ -5246,22 +5287,19 @@ var ComputeEngine = (() => {
5246
5287
  return "";
5247
5288
  const style = serializer.options.groupStyle(expr, serializer.level + 1);
5248
5289
  const arg1 = op(expr, 1);
5249
- if (argCount === 1)
5250
- return serializer.wrapString(serializer.serialize(arg1), style);
5251
- let sep = "";
5252
- let open = "";
5253
- let close = "";
5290
+ const h1 = head(arg1);
5291
+ const defaultFence = { List: "[],", Sequence: "" }[typeof h1 === "string" ? h1 : ""] ?? "(),";
5292
+ let open = defaultFence[0] ?? "";
5293
+ let close = defaultFence[1] ?? "";
5294
+ let sep = defaultFence[2] ?? "";
5254
5295
  if (argCount > 1) {
5255
5296
  const op22 = stringValue(op(expr, 2)) ?? "";
5256
- open = op22[0] ?? "(";
5257
- close = op22[1] ?? ")";
5258
- sep = op22[2] ?? ",";
5297
+ open = op22[0] ?? defaultFence[0];
5298
+ close = op22[1] ?? defaultFence[1];
5299
+ sep = op22[2] ?? defaultFence[2];
5259
5300
  }
5260
- const body = head(arg1) === "List" ? serializeSequence(sep)(serializer, arg1) : serializer.serialize(arg1);
5261
- serializer.wrapString(body, style, stringValue(op(expr, 2)) ?? void 0);
5262
- if (!open || !close)
5263
- return serializer.wrapString(body, style);
5264
- return `${open} ${body} ${close}`;
5301
+ const body = isListLike(arg1) ? serializeOps(sep)(serializer, arg1) : serializer.serialize(arg1);
5302
+ return serializer.wrapString(body, style, open + close);
5265
5303
  }
5266
5304
  },
5267
5305
  {
@@ -5273,7 +5311,7 @@ var ComputeEngine = (() => {
5273
5311
  }
5274
5312
  },
5275
5313
  {
5276
- trigger: ["\\mathtip"],
5314
+ latexTrigger: ["\\mathtip"],
5277
5315
  parse: (parser) => {
5278
5316
  const op12 = parser.parseGroup();
5279
5317
  const op22 = parser.parseGroup();
@@ -5281,7 +5319,7 @@ var ComputeEngine = (() => {
5281
5319
  }
5282
5320
  },
5283
5321
  {
5284
- trigger: ["\\texttip"],
5322
+ latexTrigger: ["\\texttip"],
5285
5323
  parse: (parser) => {
5286
5324
  const op12 = parser.parseGroup();
5287
5325
  const op22 = parser.parseGroup();
@@ -5289,8 +5327,8 @@ var ComputeEngine = (() => {
5289
5327
  }
5290
5328
  },
5291
5329
  {
5292
- trigger: ["\\error"],
5293
- parse: (parser) => parser.parseGroup()
5330
+ latexTrigger: ["\\error"],
5331
+ parse: (parser) => ["Error", parser.parseGroup()]
5294
5332
  },
5295
5333
  {
5296
5334
  name: "Error",
@@ -5350,10 +5388,10 @@ var ComputeEngine = (() => {
5350
5388
  {
5351
5389
  name: "List",
5352
5390
  kind: "matchfix",
5353
- openDelimiter: "[",
5354
- closeDelimiter: "]",
5391
+ openTrigger: "[",
5392
+ closeTrigger: "]",
5355
5393
  parse: (_parser, body) => {
5356
- if (body === null)
5394
+ if (body === null || isEmptySequence(body))
5357
5395
  return ["List"];
5358
5396
  if (head(body) !== "Sequence" && head(body) !== "List")
5359
5397
  return ["List", body];
@@ -5362,18 +5400,18 @@ var ComputeEngine = (() => {
5362
5400
  serialize: (serializer, expr) => {
5363
5401
  return joinLatex([
5364
5402
  "\\lbrack",
5365
- serializeSequence(", ")(serializer, expr),
5403
+ serializeOps(", ")(serializer, expr),
5366
5404
  "\\rbrack"
5367
5405
  ]);
5368
5406
  }
5369
5407
  },
5370
5408
  {
5371
5409
  kind: "matchfix",
5372
- openDelimiter: "(",
5373
- closeDelimiter: ")",
5410
+ openTrigger: "(",
5411
+ closeTrigger: ")",
5374
5412
  parse: (_parser, body) => {
5375
- if (body === null)
5376
- return null;
5413
+ if (body === null || isEmptySequence(body))
5414
+ return ["Sequence"];
5377
5415
  if (head(body) === "Sequence" || head(body) === "List") {
5378
5416
  if (nops(body) === 0)
5379
5417
  return ["Delimiter"];
@@ -5383,7 +5421,7 @@ var ComputeEngine = (() => {
5383
5421
  }
5384
5422
  },
5385
5423
  {
5386
- trigger: [","],
5424
+ latexTrigger: [","],
5387
5425
  kind: "infix",
5388
5426
  precedence: 20,
5389
5427
  // Unlike the matchfix version of List,
@@ -5400,10 +5438,10 @@ var ComputeEngine = (() => {
5400
5438
  },
5401
5439
  {
5402
5440
  name: "Sequence",
5403
- serialize: serializeSequence("")
5441
+ serialize: serializeOps("")
5404
5442
  },
5405
5443
  {
5406
- trigger: [";"],
5444
+ latexTrigger: [";"],
5407
5445
  kind: "infix",
5408
5446
  precedence: 19,
5409
5447
  parse: (parser, lhs, terminator) => {
@@ -5420,7 +5458,7 @@ var ComputeEngine = (() => {
5420
5458
  },
5421
5459
  {
5422
5460
  name: "String",
5423
- trigger: ["\\text"],
5461
+ latexTrigger: ["\\text"],
5424
5462
  parse: (scanner) => parseTextRun(scanner),
5425
5463
  serialize: (serializer, expr) => {
5426
5464
  const args = ops(expr);
@@ -5435,7 +5473,7 @@ var ComputeEngine = (() => {
5435
5473
  },
5436
5474
  {
5437
5475
  name: "Subscript",
5438
- trigger: ["_"],
5476
+ latexTrigger: ["_"],
5439
5477
  kind: "infix",
5440
5478
  serialize: (serializer, expr) => {
5441
5479
  if (nops(expr) === 2) {
@@ -5444,53 +5482,121 @@ var ComputeEngine = (() => {
5444
5482
  return "_{" + serializer.serialize(op(expr, 1)) + "}";
5445
5483
  }
5446
5484
  },
5447
- { name: "Superplus", trigger: ["^", "+"], kind: "postfix" },
5448
- { name: "Subplus", trigger: ["_", "+"], kind: "postfix" },
5449
- { name: "Superminus", trigger: ["^", "-"], kind: "postfix" },
5450
- { name: "Subminus", trigger: ["_", "-"], kind: "postfix" },
5485
+ { name: "Superplus", latexTrigger: ["^", "+"], kind: "postfix" },
5486
+ { name: "Subplus", latexTrigger: ["_", "+"], kind: "postfix" },
5487
+ { name: "Superminus", latexTrigger: ["^", "-"], kind: "postfix" },
5488
+ { name: "Subminus", latexTrigger: ["_", "-"], kind: "postfix" },
5451
5489
  {
5452
- trigger: ["^", "*"],
5490
+ latexTrigger: ["^", "*"],
5453
5491
  kind: "postfix",
5454
5492
  parse: (_parser, lhs) => ["Superstar", lhs]
5455
5493
  },
5456
5494
  // @todo: when lhs is a complex number, 'Conjugate'
5457
5495
  // { name: 'Conjugate', trigger: ['\\star'], kind: 'infix' },
5458
- { name: "Superstar", trigger: ["^", "\\star"], kind: "postfix" },
5496
+ { name: "Superstar", latexTrigger: ["^", "\\star"], kind: "postfix" },
5459
5497
  {
5460
- trigger: ["_", "*"],
5498
+ latexTrigger: ["_", "*"],
5461
5499
  kind: "postfix",
5462
5500
  parse: (_parser, lhs) => ["Substar", lhs]
5463
5501
  },
5464
- { name: "Substar", trigger: ["_", "\\star"], kind: "postfix" },
5465
- { name: "Superdagger", trigger: ["^", "\\dagger"], kind: "postfix" },
5502
+ { name: "Substar", latexTrigger: ["_", "\\star"], kind: "postfix" },
5503
+ { name: "Superdagger", latexTrigger: ["^", "\\dagger"], kind: "postfix" },
5466
5504
  {
5467
- trigger: ["^", "\\dag"],
5505
+ latexTrigger: ["^", "\\dag"],
5468
5506
  kind: "postfix",
5469
5507
  parse: (_parser, lhs) => ["Superdagger", lhs]
5470
5508
  },
5471
5509
  {
5472
5510
  name: "Prime",
5473
- trigger: ["^", "\\prime"],
5474
- kind: "postfix"
5511
+ latexTrigger: ["^", "\\prime"],
5512
+ // Note: we don't need a precedence because the trigger is '^'
5513
+ // and '^' (and '_') are treated specially by the parser.
5514
+ kind: "postfix",
5515
+ parse: (parser, lhs) => parsePrime(parser, lhs, 1),
5516
+ serialize: (serializer, expr) => {
5517
+ const n2 = machineValue(op(expr, 2)) ?? 1;
5518
+ const base = serializer.serialize(op(expr, 1));
5519
+ if (n2 === 1)
5520
+ return base + "^\\prime";
5521
+ if (n2 === 2)
5522
+ return base + "^\\doubleprime";
5523
+ if (n2 === 3)
5524
+ return base + "^\\tripleprime";
5525
+ return base + "^{(" + serializer.serialize(op(expr, 2)) + ")}";
5526
+ }
5527
+ },
5528
+ {
5529
+ latexTrigger: "^{\\prime\\prime}",
5530
+ kind: "postfix",
5531
+ parse: (parser, lhs) => parsePrime(parser, lhs, 2)
5532
+ },
5533
+ {
5534
+ latexTrigger: "^{\\prime\\prime\\prime}",
5535
+ kind: "postfix",
5536
+ parse: (parser, lhs) => parsePrime(parser, lhs, 3)
5537
+ },
5538
+ {
5539
+ latexTrigger: ["^", "\\doubleprime"],
5540
+ kind: "postfix",
5541
+ parse: (parser, lhs) => parsePrime(parser, lhs, 2)
5475
5542
  },
5476
5543
  {
5477
- trigger: ["^", "\\doubleprime"],
5544
+ latexTrigger: ["^", "\\tripleprime"],
5478
5545
  kind: "postfix",
5479
- parse: (_parser, lhs) => ["Prime", missingIfEmpty(lhs), 2]
5546
+ parse: (parser, lhs) => parsePrime(parser, lhs, 3)
5480
5547
  },
5481
5548
  {
5482
- trigger: ["^", "\\tripleprime"],
5549
+ latexTrigger: "'",
5483
5550
  kind: "postfix",
5484
- parse: (_parser, lhs) => ["Prime", missingIfEmpty(lhs), 3]
5551
+ precedence: 810,
5552
+ parse: (parser, lhs) => parsePrime(parser, lhs, 1)
5553
+ },
5554
+ {
5555
+ latexTrigger: "\\prime",
5556
+ kind: "postfix",
5557
+ precedence: 810,
5558
+ parse: (parser, lhs) => parsePrime(parser, lhs, 1)
5559
+ },
5560
+ {
5561
+ latexTrigger: "\\doubleprime",
5562
+ kind: "postfix",
5563
+ precedence: 810,
5564
+ parse: (parser, lhs) => parsePrime(parser, lhs, 2)
5565
+ },
5566
+ {
5567
+ latexTrigger: "\\tripleprime",
5568
+ kind: "postfix",
5569
+ precedence: 810,
5570
+ parse: (parser, lhs) => parsePrime(parser, lhs, 3)
5571
+ },
5572
+ {
5573
+ latexTrigger: ["^", "<{>", "("],
5574
+ kind: "postfix",
5575
+ parse: (parser, lhs) => {
5576
+ if (!parser.computeEngine?.box(lhs)?.domain.isFunction)
5577
+ return null;
5578
+ const start = parser.index;
5579
+ parser.addBoundary([")"]);
5580
+ const expr = parser.parseExpression();
5581
+ if (!parser.matchBoundary()) {
5582
+ parser.index = start;
5583
+ return null;
5584
+ }
5585
+ if (!parser.match("<}>")) {
5586
+ parser.index = start;
5587
+ return null;
5588
+ }
5589
+ return ["Derivative", lhs, expr];
5590
+ }
5485
5591
  },
5486
5592
  {
5487
5593
  name: "InverseFunction",
5488
- trigger: "^{-1}",
5594
+ latexTrigger: "^{-1}",
5489
5595
  kind: "postfix",
5490
5596
  parse: (parser, lhs) => {
5491
5597
  if (parser.computeEngine?.box(lhs)?.domain.isFunction)
5492
5598
  return ["InverseFunction", lhs];
5493
- return null;
5599
+ return ["Power", missingIfEmpty(lhs), -1];
5494
5600
  },
5495
5601
  serialize: (serializer, expr) => serializer.serialize(op(expr, 1)) + "^{-1}"
5496
5602
  },
@@ -5505,13 +5611,13 @@ var ComputeEngine = (() => {
5505
5611
  return base + "^{\\doubleprime}";
5506
5612
  if (degree === 3)
5507
5613
  return base + "^{\\tripleprime}";
5508
- return base + "^{(" + Number(degree).toString() + ")}";
5614
+ return base + "^{(" + serializer.serialize(op(expr, 2)) + ")}";
5509
5615
  }
5510
5616
  },
5511
5617
  {
5512
- name: "Which",
5513
- trigger: "cases",
5514
5618
  kind: "environment",
5619
+ name: "Which",
5620
+ identifierTrigger: "cases",
5515
5621
  parse: (parser) => {
5516
5622
  const tabular = parser.parseTabular();
5517
5623
  if (!tabular)
@@ -5530,24 +5636,17 @@ var ComputeEngine = (() => {
5530
5636
  return result;
5531
5637
  },
5532
5638
  serialize: (serialize2, expr) => {
5533
- if (head(op(expr, 1)) !== "List")
5534
- return "";
5535
- const rows = ops(op(expr, 1)) ?? [];
5536
- const body = [];
5537
- let rowSep = "";
5538
- for (const row of rows) {
5539
- if (head(row) === "Tuple" || head(row) === "Pair") {
5540
- body.push(rowSep);
5541
- if (op(row, 2)) {
5542
- body.push(serialize2.serialize(op(row, 2)));
5543
- const condition = op(row, 1);
5544
- if (condition !== null)
5545
- body.push("&", serialize2.serialize(condition));
5546
- }
5639
+ const rows = [];
5640
+ const args = ops(expr);
5641
+ if (args) {
5642
+ for (let i = 0; i <= args.length - 2; i += 2) {
5643
+ const row = [];
5644
+ row.push(serialize2.serialize(args[i + 1]));
5645
+ row.push(serialize2.serialize(args[i]));
5646
+ rows.push(row.join("&"));
5547
5647
  }
5548
- rowSep = "\\\\";
5549
5648
  }
5550
- return joinLatex(["\\begin{cases}", ...body, "\\end{cases}"]);
5649
+ return joinLatex(["\\begin{cases}", rows.join("\\\\"), "\\end{cases}"]);
5551
5650
  }
5552
5651
  }
5553
5652
  ];
@@ -5661,11 +5760,26 @@ var ComputeEngine = (() => {
5661
5760
  return serializer.serialize(op(arg, 1));
5662
5761
  return serializer.serialize(arg);
5663
5762
  }
5763
+ function parsePrime(parser, lhs, order2) {
5764
+ const lhsh = head(lhs);
5765
+ if (lhsh === "Derivative" || lhsh === "Prime") {
5766
+ const n = machineValue(op(lhs, 2)) ?? 1;
5767
+ return [lhsh, missingIfEmpty(op(lhs, 1)), n + order2];
5768
+ }
5769
+ if (parser.computeEngine?.box(lhs)?.domain.isFunction) {
5770
+ if (order2 === 1)
5771
+ return ["Derivative", lhs];
5772
+ return ["Derivative", lhs, order2];
5773
+ }
5774
+ if (order2 === 1)
5775
+ return ["Prime", missingIfEmpty(lhs)];
5776
+ return ["Prime", missingIfEmpty(lhs), order2];
5777
+ }
5664
5778
 
5665
5779
  // src/compute-engine/latex-syntax/dictionary/definitions-inequalities.ts
5666
5780
  var DEFINITIONS_INEQUALITIES = [
5667
5781
  {
5668
- trigger: ["\\not", "<"],
5782
+ latexTrigger: ["\\not", "<"],
5669
5783
  kind: "infix",
5670
5784
  associativity: "right",
5671
5785
  precedence: 246,
@@ -5673,13 +5787,13 @@ var ComputeEngine = (() => {
5673
5787
  },
5674
5788
  {
5675
5789
  name: "NotLess",
5676
- trigger: ["\\nless"],
5790
+ latexTrigger: ["\\nless"],
5677
5791
  kind: "infix",
5678
5792
  associativity: "right",
5679
5793
  precedence: 246
5680
5794
  },
5681
5795
  {
5682
- trigger: ["<"],
5796
+ latexTrigger: ["<"],
5683
5797
  kind: "infix",
5684
5798
  associativity: "right",
5685
5799
  precedence: 245,
@@ -5687,13 +5801,13 @@ var ComputeEngine = (() => {
5687
5801
  },
5688
5802
  {
5689
5803
  name: "Less",
5690
- trigger: ["\\lt"],
5804
+ latexTrigger: ["\\lt"],
5691
5805
  kind: "infix",
5692
5806
  associativity: "right",
5693
5807
  precedence: 245
5694
5808
  },
5695
5809
  {
5696
- trigger: ["<", "="],
5810
+ latexTrigger: ["<", "="],
5697
5811
  kind: "infix",
5698
5812
  associativity: "right",
5699
5813
  precedence: 241,
@@ -5701,20 +5815,20 @@ var ComputeEngine = (() => {
5701
5815
  },
5702
5816
  {
5703
5817
  name: "LessEqual",
5704
- trigger: ["\\le"],
5818
+ latexTrigger: ["\\le"],
5705
5819
  kind: "infix",
5706
5820
  associativity: "right",
5707
5821
  precedence: 241
5708
5822
  },
5709
5823
  {
5710
- trigger: ["\\leq"],
5824
+ latexTrigger: ["\\leq"],
5711
5825
  kind: "infix",
5712
5826
  associativity: "right",
5713
5827
  precedence: 241,
5714
5828
  parse: "LessEqual"
5715
5829
  },
5716
5830
  {
5717
- trigger: ["\\leqslant"],
5831
+ latexTrigger: ["\\leqslant"],
5718
5832
  kind: "infix",
5719
5833
  associativity: "right",
5720
5834
  precedence: 265,
@@ -5723,28 +5837,28 @@ var ComputeEngine = (() => {
5723
5837
  },
5724
5838
  {
5725
5839
  name: "LessNotEqual",
5726
- trigger: ["\\lneqq"],
5840
+ latexTrigger: ["\\lneqq"],
5727
5841
  kind: "infix",
5728
5842
  associativity: "right",
5729
5843
  precedence: 260
5730
5844
  },
5731
5845
  {
5732
5846
  name: "NotLessNotEqual",
5733
- trigger: ["\\nleqq"],
5847
+ latexTrigger: ["\\nleqq"],
5734
5848
  kind: "infix",
5735
5849
  associativity: "right",
5736
5850
  precedence: 260
5737
5851
  },
5738
5852
  {
5739
5853
  name: "LessOverEqual",
5740
- trigger: ["\\leqq"],
5854
+ latexTrigger: ["\\leqq"],
5741
5855
  kind: "infix",
5742
5856
  associativity: "right",
5743
5857
  precedence: 265
5744
5858
  },
5745
5859
  {
5746
5860
  name: "GreaterOverEqual",
5747
- trigger: ["\\geqq"],
5861
+ latexTrigger: ["\\geqq"],
5748
5862
  kind: "infix",
5749
5863
  associativity: "right",
5750
5864
  precedence: 265,
@@ -5752,13 +5866,13 @@ var ComputeEngine = (() => {
5752
5866
  },
5753
5867
  {
5754
5868
  name: "Equal",
5755
- trigger: ["="],
5869
+ latexTrigger: ["="],
5756
5870
  kind: "infix",
5757
5871
  associativity: "right",
5758
5872
  precedence: 260
5759
5873
  },
5760
5874
  {
5761
- trigger: ["*", "="],
5875
+ latexTrigger: ["*", "="],
5762
5876
  kind: "infix",
5763
5877
  associativity: "right",
5764
5878
  precedence: 260,
@@ -5766,42 +5880,42 @@ var ComputeEngine = (() => {
5766
5880
  },
5767
5881
  {
5768
5882
  name: "StarEqual",
5769
- trigger: ["\\star", "="],
5883
+ latexTrigger: ["\\star", "="],
5770
5884
  kind: "infix",
5771
5885
  associativity: "right",
5772
5886
  precedence: 260
5773
5887
  },
5774
5888
  {
5775
5889
  name: "PlusEqual",
5776
- trigger: ["+", "="],
5890
+ latexTrigger: ["+", "="],
5777
5891
  kind: "infix",
5778
5892
  associativity: "right",
5779
5893
  precedence: 260
5780
5894
  },
5781
5895
  {
5782
5896
  name: "MinusEqual",
5783
- trigger: ["-", "="],
5897
+ latexTrigger: ["-", "="],
5784
5898
  kind: "infix",
5785
5899
  associativity: "right",
5786
5900
  precedence: 260
5787
5901
  },
5788
5902
  {
5789
5903
  name: "SlashEqual",
5790
- trigger: ["/", "="],
5904
+ latexTrigger: ["/", "="],
5791
5905
  kind: "infix",
5792
5906
  associativity: "right",
5793
5907
  precedence: 260
5794
5908
  },
5795
5909
  {
5796
5910
  name: "EqualEqual",
5797
- trigger: ["=", "="],
5911
+ latexTrigger: ["=", "="],
5798
5912
  kind: "infix",
5799
5913
  associativity: "right",
5800
5914
  precedence: 260
5801
5915
  },
5802
5916
  {
5803
5917
  name: "EqualEqualEqual",
5804
- trigger: ["=", "=", "="],
5918
+ latexTrigger: ["=", "=", "="],
5805
5919
  kind: "infix",
5806
5920
  associativity: "right",
5807
5921
  precedence: 265
@@ -5809,7 +5923,7 @@ var ComputeEngine = (() => {
5809
5923
  {
5810
5924
  name: "TildeFullEqual",
5811
5925
  // MathML: approximately equal to
5812
- trigger: ["\\cong"],
5926
+ latexTrigger: ["\\cong"],
5813
5927
  kind: "infix",
5814
5928
  associativity: "right",
5815
5929
  precedence: 260
@@ -5817,13 +5931,13 @@ var ComputeEngine = (() => {
5817
5931
  {
5818
5932
  name: "NotTildeFullEqual",
5819
5933
  // MathML: approximately but not actually equal to
5820
- trigger: ["\\ncong"],
5934
+ latexTrigger: ["\\ncong"],
5821
5935
  kind: "infix",
5822
5936
  associativity: "right",
5823
5937
  precedence: 260
5824
5938
  },
5825
5939
  {
5826
- trigger: [":", "="],
5940
+ latexTrigger: [":", "="],
5827
5941
  kind: "infix",
5828
5942
  associativity: "right",
5829
5943
  precedence: 260,
@@ -5831,7 +5945,7 @@ var ComputeEngine = (() => {
5831
5945
  },
5832
5946
  {
5833
5947
  name: "Assign",
5834
- trigger: ["\\coloneq"],
5948
+ latexTrigger: ["\\coloneq"],
5835
5949
  kind: "infix",
5836
5950
  associativity: "right",
5837
5951
  precedence: 260
@@ -5839,7 +5953,7 @@ var ComputeEngine = (() => {
5839
5953
  {
5840
5954
  name: "Approx",
5841
5955
  // Note: Mathematica TildeTilde
5842
- trigger: ["\\approx"],
5956
+ latexTrigger: ["\\approx"],
5843
5957
  kind: "infix",
5844
5958
  associativity: "right",
5845
5959
  precedence: 247
@@ -5847,7 +5961,7 @@ var ComputeEngine = (() => {
5847
5961
  {
5848
5962
  name: "NotApprox",
5849
5963
  // Note: Mathematica TildeTilde
5850
- trigger: ["\\not", "\\approx"],
5964
+ latexTrigger: ["\\not", "\\approx"],
5851
5965
  kind: "infix",
5852
5966
  associativity: "right",
5853
5967
  precedence: 247
@@ -5855,7 +5969,7 @@ var ComputeEngine = (() => {
5855
5969
  {
5856
5970
  name: "ApproxEqual",
5857
5971
  // Note: Mathematica TildeEqual, MathML: `asymptotically equal to`
5858
- trigger: ["\\approxeq"],
5972
+ latexTrigger: ["\\approxeq"],
5859
5973
  kind: "infix",
5860
5974
  associativity: "right",
5861
5975
  precedence: 260
@@ -5863,7 +5977,7 @@ var ComputeEngine = (() => {
5863
5977
  {
5864
5978
  name: "NotApproxEqual",
5865
5979
  // Note: Mathematica NotTildeEqual
5866
- trigger: ["\\not", "\\approxeq"],
5980
+ latexTrigger: ["\\not", "\\approxeq"],
5867
5981
  kind: "infix",
5868
5982
  // Note: no LaTeX symbol for char U+2249
5869
5983
  associativity: "right",
@@ -5871,14 +5985,14 @@ var ComputeEngine = (() => {
5871
5985
  },
5872
5986
  {
5873
5987
  name: "NotEqual",
5874
- trigger: ["\\ne"],
5988
+ latexTrigger: ["\\ne"],
5875
5989
  kind: "infix",
5876
5990
  associativity: "right",
5877
5991
  precedence: 255
5878
5992
  },
5879
5993
  {
5880
5994
  name: "Unequal",
5881
- trigger: ["!", "="],
5995
+ latexTrigger: ["!", "="],
5882
5996
  kind: "infix",
5883
5997
  associativity: "right",
5884
5998
  precedence: 260
@@ -5886,14 +6000,14 @@ var ComputeEngine = (() => {
5886
6000
  },
5887
6001
  {
5888
6002
  name: "GreaterEqual",
5889
- trigger: ["\\ge"],
6003
+ latexTrigger: ["\\ge"],
5890
6004
  kind: "infix",
5891
6005
  associativity: "right",
5892
6006
  precedence: 242
5893
6007
  // Note: different precendence than `>=` as per MathML
5894
6008
  },
5895
6009
  {
5896
- trigger: ["\\geq"],
6010
+ latexTrigger: ["\\geq"],
5897
6011
  kind: "infix",
5898
6012
  associativity: "right",
5899
6013
  precedence: 242,
@@ -5901,14 +6015,14 @@ var ComputeEngine = (() => {
5901
6015
  parse: "GreaterEqual"
5902
6016
  },
5903
6017
  {
5904
- trigger: [">", "="],
6018
+ latexTrigger: [">", "="],
5905
6019
  kind: "infix",
5906
6020
  associativity: "right",
5907
6021
  precedence: 243,
5908
6022
  parse: "GreaterEqual"
5909
6023
  },
5910
6024
  {
5911
- trigger: ["\\geqslant"],
6025
+ latexTrigger: ["\\geqslant"],
5912
6026
  kind: "infix",
5913
6027
  associativity: "right",
5914
6028
  precedence: 265,
@@ -5917,20 +6031,20 @@ var ComputeEngine = (() => {
5917
6031
  },
5918
6032
  {
5919
6033
  name: "GreaterNotEqual",
5920
- trigger: ["\\gneqq"],
6034
+ latexTrigger: ["\\gneqq"],
5921
6035
  kind: "infix",
5922
6036
  associativity: "right",
5923
6037
  precedence: 260
5924
6038
  },
5925
6039
  {
5926
6040
  name: "NotGreaterNotEqual",
5927
- trigger: ["\\ngeqq"],
6041
+ latexTrigger: ["\\ngeqq"],
5928
6042
  kind: "infix",
5929
6043
  associativity: "right",
5930
6044
  precedence: 260
5931
6045
  },
5932
6046
  {
5933
- trigger: [">"],
6047
+ latexTrigger: [">"],
5934
6048
  kind: "infix",
5935
6049
  associativity: "right",
5936
6050
  precedence: 245,
@@ -5938,20 +6052,20 @@ var ComputeEngine = (() => {
5938
6052
  },
5939
6053
  {
5940
6054
  name: "Greater",
5941
- trigger: ["\\gt"],
6055
+ latexTrigger: ["\\gt"],
5942
6056
  kind: "infix",
5943
6057
  associativity: "right",
5944
6058
  precedence: 245
5945
6059
  },
5946
6060
  {
5947
6061
  name: "NotGreater",
5948
- trigger: ["\\ngtr"],
6062
+ latexTrigger: ["\\ngtr"],
5949
6063
  kind: "infix",
5950
6064
  associativity: "right",
5951
6065
  precedence: 244
5952
6066
  },
5953
6067
  {
5954
- trigger: ["\\not", ">"],
6068
+ latexTrigger: ["\\not", ">"],
5955
6069
  kind: "infix",
5956
6070
  associativity: "right",
5957
6071
  precedence: 244,
@@ -5959,7 +6073,7 @@ var ComputeEngine = (() => {
5959
6073
  },
5960
6074
  {
5961
6075
  name: "RingEqual",
5962
- trigger: ["\\circeq"],
6076
+ latexTrigger: ["\\circeq"],
5963
6077
  kind: "infix",
5964
6078
  associativity: "right",
5965
6079
  precedence: 260
@@ -5967,7 +6081,7 @@ var ComputeEngine = (() => {
5967
6081
  {
5968
6082
  name: "TriangleEqual",
5969
6083
  // MathML: delta equal to
5970
- trigger: ["\\triangleq"],
6084
+ latexTrigger: ["\\triangleq"],
5971
6085
  kind: "infix",
5972
6086
  associativity: "right",
5973
6087
  precedence: 260
@@ -5975,7 +6089,7 @@ var ComputeEngine = (() => {
5975
6089
  {
5976
6090
  name: "DotEqual",
5977
6091
  // MathML: approaches the limit
5978
- trigger: ["\\doteq"],
6092
+ latexTrigger: ["\\doteq"],
5979
6093
  kind: "infix",
5980
6094
  associativity: "right",
5981
6095
  precedence: 265
@@ -5983,7 +6097,7 @@ var ComputeEngine = (() => {
5983
6097
  {
5984
6098
  name: "DotEqualDot",
5985
6099
  // MathML: Geometrically equal
5986
- trigger: ["\\doteqdot"],
6100
+ latexTrigger: ["\\doteqdot"],
5987
6101
  kind: "infix",
5988
6102
  associativity: "right",
5989
6103
  precedence: 265
@@ -5991,7 +6105,7 @@ var ComputeEngine = (() => {
5991
6105
  {
5992
6106
  name: "FallingDotEqual",
5993
6107
  // MathML: approximately equal to or the image of
5994
- trigger: ["\\fallingdotseq"],
6108
+ latexTrigger: ["\\fallingdotseq"],
5995
6109
  kind: "infix",
5996
6110
  associativity: "right",
5997
6111
  precedence: 265
@@ -5999,92 +6113,77 @@ var ComputeEngine = (() => {
5999
6113
  {
6000
6114
  name: "RisingDotEqual",
6001
6115
  // MathML: image of or approximately equal to
6002
- trigger: ["\\fallingdotseq"],
6116
+ latexTrigger: ["\\fallingdotseq"],
6003
6117
  kind: "infix",
6004
6118
  associativity: "right",
6005
6119
  precedence: 265
6006
6120
  },
6007
6121
  {
6008
6122
  name: "QuestionEqual",
6009
- trigger: ["\\questeq"],
6010
- kind: "infix",
6011
- associativity: "right",
6012
- precedence: 260
6013
- },
6014
- {
6015
- name: "Equivalent",
6016
- // MathML: identical to, Mathematica: Congruent
6017
- trigger: ["\\equiv"],
6018
- kind: "infix",
6019
- associativity: "right",
6020
- precedence: 260
6021
- },
6022
- {
6023
- trigger: ["\\iff"],
6123
+ latexTrigger: ["\\questeq"],
6024
6124
  kind: "infix",
6025
- parse: "Equivalent",
6026
6125
  associativity: "right",
6027
6126
  precedence: 260
6028
6127
  },
6029
6128
  {
6030
6129
  name: "MuchLess",
6031
- trigger: ["\\ll"],
6130
+ latexTrigger: ["\\ll"],
6032
6131
  kind: "infix",
6033
6132
  associativity: "right",
6034
6133
  precedence: 260
6035
6134
  },
6036
6135
  {
6037
6136
  name: "MuchGreater",
6038
- trigger: ["\\gg"],
6137
+ latexTrigger: ["\\gg"],
6039
6138
  kind: "infix",
6040
6139
  associativity: "right",
6041
6140
  precedence: 260
6042
6141
  },
6043
6142
  {
6044
6143
  name: "Precedes",
6045
- trigger: ["\\prec"],
6144
+ latexTrigger: ["\\prec"],
6046
6145
  kind: "infix",
6047
6146
  associativity: "right",
6048
6147
  precedence: 260
6049
6148
  },
6050
6149
  {
6051
6150
  name: "Succeeds",
6052
- trigger: ["\\succ"],
6151
+ latexTrigger: ["\\succ"],
6053
6152
  kind: "infix",
6054
6153
  associativity: "right",
6055
6154
  precedence: 260
6056
6155
  },
6057
6156
  {
6058
6157
  name: "PrecedesEqual",
6059
- trigger: ["\\preccurlyeq"],
6158
+ latexTrigger: ["\\preccurlyeq"],
6060
6159
  kind: "infix",
6061
6160
  associativity: "right",
6062
6161
  precedence: 260
6063
6162
  },
6064
6163
  {
6065
6164
  name: "SucceedsEqual",
6066
- trigger: ["\\curlyeqprec"],
6165
+ latexTrigger: ["\\curlyeqprec"],
6067
6166
  kind: "infix",
6068
6167
  associativity: "right",
6069
6168
  precedence: 260
6070
6169
  },
6071
6170
  {
6072
6171
  name: "NotPrecedes",
6073
- trigger: ["\\nprec"],
6172
+ latexTrigger: ["\\nprec"],
6074
6173
  kind: "infix",
6075
6174
  associativity: "right",
6076
6175
  precedence: 260
6077
6176
  },
6078
6177
  {
6079
6178
  name: "NotSucceeds",
6080
- trigger: ["\\nsucc"],
6179
+ latexTrigger: ["\\nsucc"],
6081
6180
  kind: "infix",
6082
6181
  associativity: "right",
6083
6182
  precedence: 260
6084
6183
  },
6085
6184
  {
6086
6185
  name: "Between",
6087
- trigger: ["\\between"],
6186
+ latexTrigger: ["\\between"],
6088
6187
  kind: "infix",
6089
6188
  associativity: "right",
6090
6189
  precedence: 265
@@ -6096,18 +6195,187 @@ var ComputeEngine = (() => {
6096
6195
  // Constants
6097
6196
  {
6098
6197
  name: "True",
6099
- trigger: ["\\mathrm", "<{>", "T", "r", "u", "e", "<}>"],
6100
- serialize: "\\mathrm{True}"
6198
+ kind: "symbol",
6199
+ latexTrigger: ["\\top"]
6200
+ // ⊤ U+22A4
6201
+ },
6202
+ {
6203
+ kind: "symbol",
6204
+ latexTrigger: "\\mathrm{True}",
6205
+ parse: "True"
6206
+ },
6207
+ {
6208
+ kind: "symbol",
6209
+ latexTrigger: "\\operator{True}",
6210
+ parse: "True"
6211
+ },
6212
+ {
6213
+ kind: "symbol",
6214
+ latexTrigger: "\\mathsf{T}",
6215
+ parse: "True"
6101
6216
  },
6102
6217
  {
6103
6218
  name: "False",
6104
- trigger: ["\\mathrm", "<{>", "F", "a", "l", "s", "e", "<}>"],
6105
- serialize: "\\mathrm{False}"
6219
+ kind: "symbol",
6220
+ latexTrigger: ["\\bot"]
6221
+ // ⊥ U+22A5
6222
+ },
6223
+ {
6224
+ kind: "symbol",
6225
+ latexTrigger: "\\operator{False}",
6226
+ parse: "True"
6227
+ },
6228
+ {
6229
+ kind: "symbol",
6230
+ latexTrigger: "\\mathsf{F}",
6231
+ parse: "True"
6106
6232
  },
6107
6233
  {
6108
6234
  name: "Maybe",
6109
- trigger: ["\\mathrm", "<{>", "M", "a", "y", "b", "e", "<}>"],
6110
- serialize: "\\mathrm{Maybe}"
6235
+ kind: "symbol",
6236
+ latexTrigger: "\\operatorname{Maybe}",
6237
+ serialize: "\\operatorname{Maybe}"
6238
+ },
6239
+ {
6240
+ kind: "symbol",
6241
+ latexTrigger: "\\mathrm{Maybe}",
6242
+ parse: "Maybe"
6243
+ },
6244
+ // Operators
6245
+ {
6246
+ name: "And",
6247
+ kind: "infix",
6248
+ latexTrigger: ["\\land"],
6249
+ precedence: 317
6250
+ // serialize: '\\land',
6251
+ },
6252
+ { kind: "infix", latexTrigger: ["\\wedge"], parse: "And", precedence: 317 },
6253
+ { kind: "infix", latexTrigger: "\\&", parse: "And", precedence: 317 },
6254
+ {
6255
+ kind: "infix",
6256
+ latexTrigger: "\\operatorname{and}",
6257
+ parse: "And",
6258
+ precedence: 317
6259
+ },
6260
+ {
6261
+ name: "Or",
6262
+ kind: "infix",
6263
+ latexTrigger: ["\\lor"],
6264
+ precedence: 310
6265
+ },
6266
+ { kind: "infix", latexTrigger: ["\\vee"], parse: "Or", precedence: 310 },
6267
+ { kind: "infix", latexTrigger: "\\parallel", parse: "Or", precedence: 310 },
6268
+ {
6269
+ kind: "infix",
6270
+ latexTrigger: "\\operatorname{or}",
6271
+ parse: "And",
6272
+ precedence: 310
6273
+ },
6274
+ {
6275
+ name: "Xor",
6276
+ kind: "infix",
6277
+ latexTrigger: ["\\veebar"],
6278
+ precedence: 315
6279
+ },
6280
+ // Possible alt: \oplus ⊕ U+2295
6281
+ {
6282
+ name: "Not",
6283
+ kind: "prefix",
6284
+ latexTrigger: ["\\lnot"],
6285
+ precedence: 880
6286
+ },
6287
+ {
6288
+ name: "Nand",
6289
+ kind: "infix",
6290
+ latexTrigger: ["\\barwedge"],
6291
+ precedence: 315
6292
+ // serialize: '\\mid',
6293
+ },
6294
+ {
6295
+ name: "Nor",
6296
+ kind: "infix",
6297
+ latexTrigger: ["\u22BD"],
6298
+ // bar vee
6299
+ precedence: 315
6300
+ // serialize: '\\downarrow',
6301
+ },
6302
+ // Functions
6303
+ {
6304
+ kind: "function",
6305
+ identifierTrigger: "and",
6306
+ parse: "And"
6307
+ },
6308
+ {
6309
+ kind: "function",
6310
+ identifierTrigger: "or",
6311
+ parse: "Or"
6312
+ },
6313
+ {
6314
+ kind: "function",
6315
+ identifierTrigger: "not",
6316
+ parse: "Not"
6317
+ },
6318
+ // Relations
6319
+ {
6320
+ name: "Implies",
6321
+ kind: "infix",
6322
+ precedence: 220,
6323
+ associativity: "right",
6324
+ latexTrigger: ["\\implies"],
6325
+ serialize: "\\implies"
6326
+ },
6327
+ {
6328
+ latexTrigger: ["\\Rightarrow"],
6329
+ kind: "infix",
6330
+ precedence: 220,
6331
+ associativity: "right",
6332
+ parse: "Implies"
6333
+ },
6334
+ {
6335
+ name: "Equivalent",
6336
+ // MathML: identical to, Mathematica: Congruent
6337
+ latexTrigger: ["\\iff"],
6338
+ kind: "infix",
6339
+ associativity: "right",
6340
+ precedence: 219
6341
+ },
6342
+ {
6343
+ latexTrigger: ["\\Leftrightarrow"],
6344
+ kind: "infix",
6345
+ associativity: "right",
6346
+ precedence: 219,
6347
+ parse: "Equivalent"
6348
+ },
6349
+ {
6350
+ latexTrigger: ["\\equiv"],
6351
+ kind: "infix",
6352
+ associativity: "right",
6353
+ precedence: 219,
6354
+ parse: "Equivalent"
6355
+ },
6356
+ {
6357
+ name: "Proves",
6358
+ kind: "infix",
6359
+ latexTrigger: ["\\vdash"],
6360
+ precedence: 220,
6361
+ associativity: "right",
6362
+ serialize: "\\vdash"
6363
+ },
6364
+ {
6365
+ name: "Entails",
6366
+ kind: "infix",
6367
+ latexTrigger: ["\\vDash"],
6368
+ precedence: 220,
6369
+ associativity: "right",
6370
+ serialize: "\\vDash"
6371
+ },
6372
+ {
6373
+ name: "Satisfies",
6374
+ kind: "infix",
6375
+ latexTrigger: ["\\models"],
6376
+ precedence: 220,
6377
+ associativity: "right",
6378
+ serialize: "\\models"
6111
6379
  }
6112
6380
  ];
6113
6381
 
@@ -6121,72 +6389,73 @@ var ComputeEngine = (() => {
6121
6389
  var DEFINITIONS_OTHERS = [
6122
6390
  {
6123
6391
  name: "Overscript",
6124
- trigger: ["\\overset"],
6392
+ latexTrigger: ["\\overset"],
6125
6393
  kind: "infix",
6126
6394
  precedence: 700
6127
6395
  // @todo: not in MathML
6128
6396
  },
6129
6397
  {
6130
6398
  name: "Underscript",
6131
- trigger: ["\\underset"],
6399
+ latexTrigger: ["\\underset"],
6132
6400
  kind: "infix",
6133
6401
  precedence: 700
6134
6402
  // @todo: not in MathML
6135
6403
  },
6136
6404
  {
6137
6405
  name: "Increment",
6138
- trigger: ["+", "+"],
6406
+ latexTrigger: ["+", "+"],
6139
6407
  kind: "postfix",
6140
6408
  precedence: 880
6141
6409
  },
6142
6410
  {
6143
6411
  name: "Decrement",
6144
- trigger: ["-", "-"],
6412
+ latexTrigger: ["-", "-"],
6145
6413
  kind: "postfix",
6146
6414
  precedence: 880
6147
6415
  },
6148
6416
  {
6149
6417
  name: "PreIncrement",
6150
- trigger: ["+", "+"],
6418
+ latexTrigger: ["+", "+"],
6151
6419
  kind: "prefix",
6152
6420
  precedence: 880
6153
6421
  },
6154
6422
  {
6155
6423
  name: "PreDecrement",
6156
- trigger: ["-", "-"],
6424
+ latexTrigger: ["-", "-"],
6157
6425
  kind: "prefix",
6158
6426
  precedence: 880
6159
6427
  },
6160
6428
  {
6161
6429
  name: "Ring",
6162
6430
  // Aka 'Composition', i.e. function composition
6163
- trigger: ["\\circ"],
6431
+ latexTrigger: ["\\circ"],
6164
6432
  kind: "infix",
6165
6433
  precedence: 265
6434
+ // @todo: MathML is 950
6166
6435
  // @todo: check lhs and rhs are functions
6167
6436
  },
6168
6437
  {
6169
6438
  name: "Transpose",
6170
- trigger: ["^", "T"],
6439
+ latexTrigger: ["^", "T"],
6171
6440
  kind: "postfix"
6172
6441
  // @todo: if lhs is a list/tensor
6173
6442
  },
6174
6443
  {
6175
6444
  // @todo: if lhs is a list/tensor
6176
6445
  name: "ConjugateTranspose",
6177
- trigger: ["^", "H"],
6446
+ latexTrigger: ["^", "H"],
6178
6447
  kind: "postfix"
6179
6448
  },
6180
6449
  {
6181
6450
  name: "StringJoin",
6182
6451
  // @todo From Mathematica...?
6183
- trigger: ["\\lt", "\\gt"],
6452
+ latexTrigger: ["\\lt", "\\gt"],
6184
6453
  kind: "infix",
6185
6454
  precedence: 780
6186
6455
  },
6187
6456
  {
6188
6457
  name: "Starstar",
6189
- trigger: ["\\star", "\\star"],
6458
+ latexTrigger: ["\\star", "\\star"],
6190
6459
  kind: "infix",
6191
6460
  precedence: 780
6192
6461
  },
@@ -6196,7 +6465,7 @@ var ComputeEngine = (() => {
6196
6465
  // For the Leibniz notation see 'Divide' that handles `∂f/∂x`
6197
6466
  name: "PartialDerivative",
6198
6467
  // PartialDerivative(expr, {lists of vars}, degree)
6199
- trigger: ["\\partial"],
6468
+ latexTrigger: ["\\partial"],
6200
6469
  kind: "prefix",
6201
6470
  parse: (parser) => {
6202
6471
  let done = false;
@@ -6219,8 +6488,8 @@ var ComputeEngine = (() => {
6219
6488
  return null;
6220
6489
  let rhs = parser.parseGroup() ?? "Nothing";
6221
6490
  if (rhs !== "Nothing" && !isEmptySequence(rhs)) {
6222
- const arg = parser.parseArguments() ?? ["Nothing"];
6223
- rhs = [rhs, ...arg];
6491
+ const args = parser.parseArguments() ?? ["Nothing"];
6492
+ rhs = [rhs, ...args];
6224
6493
  }
6225
6494
  return ["PartialDerivative", rhs, sub2, sup];
6226
6495
  },
@@ -6246,128 +6515,128 @@ var ComputeEngine = (() => {
6246
6515
  },
6247
6516
  {
6248
6517
  name: "OverBar",
6249
- trigger: ["\\overline"],
6518
+ latexTrigger: ["\\overline"],
6250
6519
  parse: parseSingleArg("OverBar")
6251
6520
  },
6252
6521
  {
6253
6522
  name: "UnderBar",
6254
- trigger: ["\\underline"],
6523
+ latexTrigger: ["\\underline"],
6255
6524
  parse: parseSingleArg("UnderBar")
6256
6525
  },
6257
6526
  {
6258
6527
  name: "OverVector",
6259
- trigger: ["\\vec"],
6528
+ latexTrigger: ["\\vec"],
6260
6529
  parse: parseSingleArg("OverVector")
6261
6530
  },
6262
6531
  {
6263
6532
  name: "OverTilde",
6264
- trigger: ["\\tilde"],
6533
+ latexTrigger: ["\\tilde"],
6265
6534
  parse: parseSingleArg("OverTilde")
6266
6535
  },
6267
6536
  {
6268
6537
  name: "OverHat",
6269
- trigger: ["\\hat"],
6538
+ latexTrigger: ["\\hat"],
6270
6539
  parse: parseSingleArg("OverHat")
6271
6540
  },
6272
6541
  {
6273
6542
  name: "OverRightArrow",
6274
- trigger: ["\\overrightarrow"],
6543
+ latexTrigger: ["\\overrightarrow"],
6275
6544
  parse: parseSingleArg("OverRightArrow")
6276
6545
  },
6277
6546
  {
6278
6547
  name: "OverLeftArrow",
6279
- trigger: ["\\overleftarrow"],
6548
+ latexTrigger: ["\\overleftarrow"],
6280
6549
  parse: parseSingleArg("OverLeftArrow")
6281
6550
  },
6282
6551
  {
6283
6552
  name: "OverRightDoubleArrow",
6284
- trigger: ["\\Overrightarrow"],
6553
+ latexTrigger: ["\\Overrightarrow"],
6285
6554
  parse: parseSingleArg("OverRightDoubleArrow")
6286
6555
  },
6287
6556
  {
6288
6557
  name: "OverLeftHarpoon",
6289
- trigger: ["\\overleftharpoon"],
6558
+ latexTrigger: ["\\overleftharpoon"],
6290
6559
  parse: parseSingleArg("OverLeftHarpoon")
6291
6560
  },
6292
6561
  {
6293
6562
  name: "OverRightHarpoon",
6294
- trigger: ["\\overrightharpoon"],
6563
+ latexTrigger: ["\\overrightharpoon"],
6295
6564
  parse: parseSingleArg("OverRightHarpoon")
6296
6565
  },
6297
6566
  {
6298
6567
  name: "OverLeftRightArrow",
6299
- trigger: ["\\overleftrightarrow"],
6568
+ latexTrigger: ["\\overleftrightarrow"],
6300
6569
  parse: parseSingleArg("OverLeftRightArrow")
6301
6570
  },
6302
6571
  {
6303
6572
  name: "OverBrace",
6304
- trigger: ["\\overbrace"],
6573
+ latexTrigger: ["\\overbrace"],
6305
6574
  parse: parseSingleArg("OverBrace")
6306
6575
  },
6307
6576
  {
6308
6577
  name: "OverLineSegment",
6309
- trigger: ["\\overlinesegment"],
6578
+ latexTrigger: ["\\overlinesegment"],
6310
6579
  parse: parseSingleArg("OverLineSegment")
6311
6580
  },
6312
6581
  {
6313
6582
  name: "OverGroup",
6314
- trigger: ["\\overgroup"],
6583
+ latexTrigger: ["\\overgroup"],
6315
6584
  parse: parseSingleArg("OverGroup")
6316
6585
  },
6317
6586
  {
6318
- trigger: ["\\displaystyle"],
6587
+ latexTrigger: ["\\displaystyle"],
6319
6588
  parse: () => ["Sequence"]
6320
6589
  },
6321
6590
  {
6322
- trigger: ["\\textstyle"],
6591
+ latexTrigger: ["\\textstyle"],
6323
6592
  parse: () => ["Sequence"]
6324
6593
  },
6325
6594
  {
6326
- trigger: ["\\scriptstyle"],
6595
+ latexTrigger: ["\\scriptstyle"],
6327
6596
  parse: () => ["Sequence"]
6328
6597
  },
6329
6598
  {
6330
- trigger: ["\\scriptscriptstyle"],
6599
+ latexTrigger: ["\\scriptscriptstyle"],
6331
6600
  parse: () => ["Sequence"]
6332
6601
  },
6333
6602
  {
6334
- trigger: ["\\tiny"],
6603
+ latexTrigger: ["\\tiny"],
6335
6604
  parse: () => ["Sequence"]
6336
6605
  },
6337
6606
  {
6338
- trigger: ["\\scriptsize"],
6607
+ latexTrigger: ["\\scriptsize"],
6339
6608
  parse: () => ["Sequence"]
6340
6609
  },
6341
6610
  {
6342
- trigger: ["\\footnotesize"],
6611
+ latexTrigger: ["\\footnotesize"],
6343
6612
  parse: () => ["Sequence"]
6344
6613
  },
6345
6614
  {
6346
- trigger: ["\\small"],
6615
+ latexTrigger: ["\\small"],
6347
6616
  parse: () => ["Sequence"]
6348
6617
  },
6349
6618
  {
6350
- trigger: ["\\normalsize"],
6619
+ latexTrigger: ["\\normalsize"],
6351
6620
  parse: () => ["Sequence"]
6352
6621
  },
6353
6622
  {
6354
- trigger: ["\\large"],
6623
+ latexTrigger: ["\\large"],
6355
6624
  parse: () => ["Sequence"]
6356
6625
  },
6357
6626
  {
6358
- trigger: ["\\Large"],
6627
+ latexTrigger: ["\\Large"],
6359
6628
  parse: () => ["Sequence"]
6360
6629
  },
6361
6630
  {
6362
- trigger: ["\\LARGE"],
6631
+ latexTrigger: ["\\LARGE"],
6363
6632
  parse: () => ["Sequence"]
6364
6633
  },
6365
6634
  {
6366
- trigger: ["\\huge"],
6635
+ latexTrigger: ["\\huge"],
6367
6636
  parse: () => ["Sequence"]
6368
6637
  },
6369
6638
  {
6370
- trigger: ["\\Huge"],
6639
+ latexTrigger: ["\\Huge"],
6371
6640
  parse: () => ["Sequence"]
6372
6641
  },
6373
6642
  {
@@ -6409,39 +6678,39 @@ var ComputeEngine = (() => {
6409
6678
  }
6410
6679
  },
6411
6680
  {
6412
- trigger: ["\\!"],
6681
+ latexTrigger: ["\\!"],
6413
6682
  parse: () => ["HorizontalSpacing", -3]
6414
6683
  },
6415
6684
  {
6416
- trigger: ["\\ "],
6685
+ latexTrigger: ["\\ "],
6417
6686
  parse: () => ["HorizontalSpacing", 6]
6418
6687
  },
6419
6688
  {
6420
- trigger: ["\\:"],
6689
+ latexTrigger: ["\\:"],
6421
6690
  parse: () => ["HorizontalSpacing", 4]
6422
6691
  },
6423
6692
  {
6424
- trigger: ["\\enskip"],
6693
+ latexTrigger: ["\\enskip"],
6425
6694
  parse: () => ["HorizontalSpacing", 9]
6426
6695
  },
6427
6696
  {
6428
- trigger: ["\\quad"],
6697
+ latexTrigger: ["\\quad"],
6429
6698
  parse: () => ["HorizontalSpacing", 18]
6430
6699
  },
6431
6700
  {
6432
- trigger: ["\\qquad"],
6701
+ latexTrigger: ["\\qquad"],
6433
6702
  parse: () => ["HorizontalSpacing", 36]
6434
6703
  },
6435
6704
  {
6436
- trigger: ["\\,"],
6705
+ latexTrigger: ["\\,"],
6437
6706
  parse: () => ["HorizontalSpacing", 3]
6438
6707
  },
6439
6708
  {
6440
- trigger: ["\\;"],
6709
+ latexTrigger: ["\\;"],
6441
6710
  parse: () => ["HorizontalSpacing", 5]
6442
6711
  },
6443
6712
  {
6444
- trigger: ["\\enspace"],
6713
+ latexTrigger: ["\\enspace"],
6445
6714
  parse: () => ["HorizontalSpacing", 9]
6446
6715
  },
6447
6716
  {
@@ -6541,146 +6810,146 @@ var ComputeEngine = (() => {
6541
6810
  var DEFINITIONS_TRIGONOMETRY = [
6542
6811
  {
6543
6812
  name: "Arcsin",
6544
- trigger: ["\\arcsin"],
6813
+ latexTrigger: ["\\arcsin"],
6545
6814
  parse: parseTrig("Arcsin")
6546
6815
  },
6547
6816
  {
6548
6817
  name: "Arccos",
6549
- trigger: ["\\arccos"],
6818
+ latexTrigger: ["\\arccos"],
6550
6819
  parse: parseTrig("Arccos")
6551
6820
  },
6552
6821
  {
6553
6822
  name: "Arctan",
6554
- trigger: ["\\arctan"],
6823
+ latexTrigger: ["\\arctan"],
6555
6824
  parse: parseTrig("Arctan")
6556
6825
  },
6557
6826
  {
6558
- trigger: ["\\arctg"],
6827
+ latexTrigger: ["\\arctg"],
6559
6828
  parse: parseTrig("Arctan")
6560
6829
  },
6561
6830
  {
6562
6831
  name: "Arccot",
6563
- trigger: ["\\arcctg"],
6832
+ latexTrigger: ["\\arcctg"],
6564
6833
  parse: parseTrig("Arccot")
6565
6834
  },
6566
6835
  {
6567
6836
  name: "Arcsec",
6568
- trigger: "arcsec",
6837
+ latexTrigger: "arcsec",
6569
6838
  parse: parseTrig("Arcsec")
6570
6839
  },
6571
6840
  {
6572
6841
  name: "Arccsc",
6573
- trigger: ["\\arccsc"],
6842
+ latexTrigger: ["\\arccsc"],
6574
6843
  parse: parseTrig("Arccsc")
6575
6844
  },
6576
6845
  {
6577
6846
  name: "Arsinh",
6578
- trigger: ["\\arsinh"],
6847
+ latexTrigger: ["\\arsinh"],
6579
6848
  parse: parseTrig("Arsinh")
6580
6849
  },
6581
6850
  {
6582
6851
  name: "Arcosh",
6583
- trigger: ["\\arcosh"],
6852
+ latexTrigger: ["\\arcosh"],
6584
6853
  parse: parseTrig("Arcosh")
6585
6854
  },
6586
6855
  {
6587
6856
  name: "Artanh",
6588
- trigger: ["\\artanh"],
6857
+ latexTrigger: ["\\artanh"],
6589
6858
  parse: parseTrig("Artanh")
6590
6859
  },
6591
6860
  {
6592
6861
  name: "Arsech",
6593
- trigger: ["\\arsech"],
6862
+ latexTrigger: ["\\arsech"],
6594
6863
  parse: parseTrig("Arsech")
6595
6864
  },
6596
6865
  {
6597
6866
  name: "Arcsch",
6598
- trigger: ["\\arcsch"],
6867
+ latexTrigger: ["\\arcsch"],
6599
6868
  parse: parseTrig("Arcsch")
6600
6869
  },
6601
6870
  {
6602
6871
  // Rusian hyperbolic cosine
6603
- trigger: ["\\ch"],
6872
+ latexTrigger: ["\\ch"],
6604
6873
  parse: parseTrig("Cosh")
6605
6874
  },
6606
6875
  {
6607
6876
  name: "Cosec",
6608
- trigger: ["\\cosec"],
6877
+ latexTrigger: ["\\cosec"],
6609
6878
  parse: parseTrig("Cosec")
6610
6879
  },
6611
6880
  {
6612
6881
  name: "Cosh",
6613
- trigger: ["\\cosh"],
6882
+ latexTrigger: ["\\cosh"],
6614
6883
  parse: parseTrig("Cosh")
6615
6884
  },
6616
6885
  {
6617
6886
  name: "Cot",
6618
- trigger: ["\\cot"],
6887
+ latexTrigger: ["\\cot"],
6619
6888
  parse: parseTrig("Cot")
6620
6889
  },
6621
6890
  {
6622
- trigger: ["\\cotg"],
6891
+ latexTrigger: ["\\cotg"],
6623
6892
  parse: parseTrig("Cot")
6624
6893
  },
6625
6894
  {
6626
6895
  name: "Coth",
6627
- trigger: ["\\coth"],
6896
+ latexTrigger: ["\\coth"],
6628
6897
  parse: parseTrig("Coth")
6629
6898
  },
6630
6899
  {
6631
6900
  name: "Csc",
6632
- trigger: ["\\csc"],
6901
+ latexTrigger: ["\\csc"],
6633
6902
  parse: parseTrig("Csc")
6634
6903
  },
6635
6904
  {
6636
6905
  // Rusian cotangent
6637
- trigger: ["\\ctg"],
6906
+ latexTrigger: ["\\ctg"],
6638
6907
  parse: parseTrig("Cot")
6639
6908
  },
6640
6909
  {
6641
- trigger: ["\\cth"],
6910
+ latexTrigger: ["\\cth"],
6642
6911
  parse: parseTrig("Cotanh")
6643
6912
  },
6644
6913
  {
6645
6914
  name: "Sec",
6646
- trigger: ["\\sec"],
6915
+ latexTrigger: ["\\sec"],
6647
6916
  parse: parseTrig("Sec")
6648
6917
  },
6649
6918
  {
6650
6919
  name: "Sinh",
6651
- trigger: ["\\sinh"],
6920
+ latexTrigger: ["\\sinh"],
6652
6921
  parse: parseTrig("Sinh")
6653
6922
  },
6654
6923
  {
6655
- trigger: ["\\sh"],
6924
+ latexTrigger: ["\\sh"],
6656
6925
  parse: parseTrig("Sinh")
6657
6926
  },
6658
6927
  {
6659
6928
  name: "Tan",
6660
- trigger: ["\\tan"],
6929
+ latexTrigger: ["\\tan"],
6661
6930
  parse: parseTrig("Tan")
6662
6931
  },
6663
6932
  {
6664
- trigger: ["\\tg"],
6933
+ latexTrigger: ["\\tg"],
6665
6934
  parse: parseTrig("Tan")
6666
6935
  },
6667
6936
  {
6668
6937
  name: "Tanh",
6669
- trigger: ["\\tanh"],
6938
+ latexTrigger: ["\\tanh"],
6670
6939
  parse: parseTrig("Tanh")
6671
6940
  },
6672
6941
  {
6673
- trigger: ["\\th"],
6942
+ latexTrigger: ["\\th"],
6674
6943
  parse: parseTrig("Tanh")
6675
6944
  },
6676
6945
  {
6677
6946
  name: "Cos",
6678
- trigger: ["\\cos"],
6947
+ latexTrigger: ["\\cos"],
6679
6948
  parse: parseTrig("Cos")
6680
6949
  },
6681
6950
  {
6682
6951
  name: "Sin",
6683
- trigger: ["\\sin"],
6952
+ latexTrigger: ["\\sin"],
6684
6953
  parse: parseTrig("Sin")
6685
6954
  }
6686
6955
  ];
@@ -6688,77 +6957,77 @@ var ComputeEngine = (() => {
6688
6957
  // src/compute-engine/latex-syntax/dictionary/definitions-sets.ts
6689
6958
  var DEFINITIONS_SETS = [
6690
6959
  // Constants
6691
- { name: "AlgebraicNumber", trigger: "\\bar\\Q" },
6692
- { name: "ComplexNumber", trigger: ["\\C"] },
6693
- { trigger: "\\mathbb{C}", parse: "ComplexNumber" },
6694
- { name: "ImaginaryNumber", trigger: ["\\imaginaryI\\R"] },
6695
- { name: "ExtendedComplexNumber", trigger: ["\\bar\\C"] },
6696
- { name: "EmptySet", trigger: ["\\emptyset"] },
6697
- { trigger: ["\\varnothing"], parse: "EmptySet" },
6960
+ { name: "AlgebraicNumber", latexTrigger: "\\bar\\Q" },
6961
+ { name: "ComplexNumber", latexTrigger: ["\\C"] },
6962
+ { latexTrigger: "\\mathbb{C}", parse: "ComplexNumber" },
6963
+ { name: "ImaginaryNumber", latexTrigger: ["\\imaginaryI", "\\R"] },
6964
+ { name: "ExtendedComplexNumber", latexTrigger: ["\\bar", "\\C"] },
6965
+ { name: "EmptySet", latexTrigger: ["\\emptyset"] },
6966
+ { latexTrigger: ["\\varnothing"], parse: "EmptySet" },
6698
6967
  // Parsing only
6699
- { name: "Integer", trigger: ["\\Z"] },
6700
- { trigger: "\\mathbb{Z}", parse: "Integer" },
6701
- { name: "RationalNumber", trigger: ["\\Q"] },
6702
- { name: "RealNumber", trigger: ["\\R"] },
6703
- { trigger: "\\mathbb{R}", parse: "RealNumber" },
6704
- { name: "ExtendedRealNumber", trigger: ["\\bar\\R"] },
6705
- { name: "TranscendentalNumber", trigger: "\\R-\\bar\\Q" },
6706
- { trigger: "\\R\\backslash\\bar\\Q", parse: "TranscendentalNumber" },
6968
+ { name: "Integer", latexTrigger: ["\\Z"] },
6969
+ { latexTrigger: "\\mathbb{Z}", parse: "Integer" },
6970
+ { name: "RationalNumber", latexTrigger: ["\\Q"] },
6971
+ { name: "RealNumber", latexTrigger: ["\\R"] },
6972
+ { latexTrigger: "\\mathbb{R}", parse: "RealNumber" },
6973
+ { name: "ExtendedRealNumber", latexTrigger: ["\\bar", "\\R"] },
6974
+ { name: "TranscendentalNumber", latexTrigger: "\\R-\\bar\\Q" },
6975
+ { latexTrigger: "\\R\\backslash\\bar\\Q", parse: "TranscendentalNumber" },
6707
6976
  // Real numbers < 0
6708
- { name: "NegativeNumber", trigger: "\\R^-" },
6709
- { trigger: "\\R^{-}", parse: "NegativeNumber" },
6710
- { trigger: "\\R_-", parse: "NegativeNumber" },
6711
- { trigger: "\\R_{-}", parse: "NegativeNumber" },
6712
- { trigger: "\\R^{\\lt}", parse: "NegativeNumber" },
6977
+ { name: "NegativeNumber", latexTrigger: "\\R^-" },
6978
+ { latexTrigger: "\\R^{-}", parse: "NegativeNumber" },
6979
+ { latexTrigger: "\\R_-", parse: "NegativeNumber" },
6980
+ { latexTrigger: "\\R_{-}", parse: "NegativeNumber" },
6981
+ { latexTrigger: "\\R^{\\lt}", parse: "NegativeNumber" },
6713
6982
  // Real numbers > 0
6714
- { name: "PositiveNumber", trigger: "\\R^+" },
6715
- { trigger: "\\R^{+}", parse: "PositiveNumber" },
6716
- { trigger: "\\R_+", parse: "PositiveNumber" },
6717
- { trigger: "\\R_{+}", parse: "PositiveNumber" },
6718
- { trigger: "\\R^{\\gt}", parse: "PositiveNumber" },
6983
+ { name: "PositiveNumber", latexTrigger: "\\R^+" },
6984
+ { latexTrigger: "\\R^{+}", parse: "PositiveNumber" },
6985
+ { latexTrigger: "\\R_+", parse: "PositiveNumber" },
6986
+ { latexTrigger: "\\R_{+}", parse: "PositiveNumber" },
6987
+ { latexTrigger: "\\R^{\\gt}", parse: "PositiveNumber" },
6719
6988
  // Real numbers <= 0
6720
- { name: "NonPositiveNumber", trigger: "\\R^{0-}" },
6721
- { trigger: "\\R^{-0}", parse: "NonPositiveNumber" },
6722
- { trigger: "\\R^{\\leq}", parse: "NonPositiveNumber" },
6989
+ { name: "NonPositiveNumber", latexTrigger: "\\R^{0-}" },
6990
+ { latexTrigger: "\\R^{-0}", parse: "NonPositiveNumber" },
6991
+ { latexTrigger: "\\R^{\\leq}", parse: "NonPositiveNumber" },
6723
6992
  // Integers < 0
6724
- { name: "NegativeInteger", trigger: "\\Z^-" },
6725
- { trigger: "\\Z^-", parse: "NegativeInteger" },
6726
- { trigger: "\\Z^{-}", parse: "NegativeInteger" },
6727
- { trigger: "\\Z_-", parse: "NegativeInteger" },
6728
- { trigger: "\\Z_{-}", parse: "NegativeInteger" },
6729
- { trigger: "\\Z^{\\lt}", parse: "NegativeInteger" },
6993
+ { name: "NegativeInteger", latexTrigger: "\\Z^-" },
6994
+ { latexTrigger: "\\Z^-", parse: "NegativeInteger" },
6995
+ { latexTrigger: "\\Z^{-}", parse: "NegativeInteger" },
6996
+ { latexTrigger: "\\Z_-", parse: "NegativeInteger" },
6997
+ { latexTrigger: "\\Z_{-}", parse: "NegativeInteger" },
6998
+ { latexTrigger: "\\Z^{\\lt}", parse: "NegativeInteger" },
6730
6999
  // Integers > 0
6731
- { name: "PositiveInteger", trigger: "\\Z^+" },
6732
- { trigger: "\\Z^{+}", parse: "PositiveInteger" },
6733
- { trigger: "\\Z_+", parse: "PositiveInteger" },
6734
- { trigger: "\\Z_{+}", parse: "PositiveInteger" },
6735
- { trigger: "\\Z^{\\gt}", parse: "PositiveInteger" },
6736
- { trigger: "\\Z^{\\gt0}", parse: "PositiveInteger" },
6737
- { trigger: "\\N^+", parse: "PositiveInteger" },
6738
- { trigger: "\\N^{+}", parse: "PositiveInteger" },
6739
- { trigger: "\\N^*", parse: "PositiveInteger" },
6740
- { trigger: "\\N^{*}", parse: "PositiveInteger" },
6741
- { trigger: "\\N^\\star", parse: "PositiveInteger" },
6742
- { trigger: "\\N^{\\star}", parse: "PositiveInteger" },
6743
- { trigger: "\\N_1", parse: "PositiveInteger" },
6744
- { trigger: "\\N_{1}", parse: "PositiveInteger" },
7000
+ { name: "PositiveInteger", latexTrigger: "\\Z^+" },
7001
+ { latexTrigger: "\\Z^{+}", parse: "PositiveInteger" },
7002
+ { latexTrigger: "\\Z_+", parse: "PositiveInteger" },
7003
+ { latexTrigger: "\\Z_{+}", parse: "PositiveInteger" },
7004
+ { latexTrigger: "\\Z^{\\gt}", parse: "PositiveInteger" },
7005
+ { latexTrigger: "\\Z^{\\gt0}", parse: "PositiveInteger" },
7006
+ { latexTrigger: "\\N^+", parse: "PositiveInteger" },
7007
+ { latexTrigger: "\\N^{+}", parse: "PositiveInteger" },
7008
+ { latexTrigger: "\\N^*", parse: "PositiveInteger" },
7009
+ { latexTrigger: "\\N^{*}", parse: "PositiveInteger" },
7010
+ { latexTrigger: "\\N^\\star", parse: "PositiveInteger" },
7011
+ { latexTrigger: "\\N^{\\star}", parse: "PositiveInteger" },
7012
+ { latexTrigger: "\\N_1", parse: "PositiveInteger" },
7013
+ { latexTrigger: "\\N_{1}", parse: "PositiveInteger" },
6745
7014
  // https://mathvault.ca/hub/higher-math/math-symbols/algebra-symbols/
6746
7015
  // Integers >= 0
6747
- { name: "NonNegativeInteger", trigger: ["\\N"] },
6748
- { trigger: "\\Z^{+0}", parse: "NonNegativeInteger" },
6749
- { trigger: "\\Z^{\\geq}", parse: "NonNegativeInteger" },
6750
- { trigger: "\\Z^{\\geq0}", parse: "NonNegativeInteger" },
6751
- { trigger: "\\Z^{0+}", parse: "NonNegativeInteger" },
6752
- { trigger: "\\mathbb{N}", parse: "NonNegativeInteger" },
6753
- { trigger: "\\N_0", parse: "NonNegativeInteger" },
6754
- { trigger: "\\N_{0}", parse: "NonNegativeInteger" },
7016
+ { name: "NonNegativeInteger", latexTrigger: ["\\N"] },
7017
+ { latexTrigger: "\\Z^{+0}", parse: "NonNegativeInteger" },
7018
+ { latexTrigger: "\\Z^{\\geq}", parse: "NonNegativeInteger" },
7019
+ { latexTrigger: "\\Z^{\\geq0}", parse: "NonNegativeInteger" },
7020
+ { latexTrigger: "\\Z^{0+}", parse: "NonNegativeInteger" },
7021
+ { latexTrigger: "\\mathbb{N}", parse: "NonNegativeInteger" },
7022
+ { latexTrigger: "\\N_0", parse: "NonNegativeInteger" },
7023
+ { latexTrigger: "\\N_{0}", parse: "NonNegativeInteger" },
6755
7024
  //
6756
7025
  // Set Expressions
6757
7026
  //
6758
7027
  // @todo: could also have a `CartesianPower` function with a number `rhs`
6759
7028
  {
6760
7029
  name: "CartesianProduct",
6761
- trigger: ["\\times"],
7030
+ latexTrigger: ["\\times"],
6762
7031
  kind: "infix",
6763
7032
  associativity: "right",
6764
7033
  // Caution: cartesian product is not associative
@@ -6780,7 +7049,7 @@ var ComputeEngine = (() => {
6780
7049
  }
6781
7050
  },
6782
7051
  {
6783
- trigger: ["^", "\\complement"],
7052
+ latexTrigger: ["^", "\\complement"],
6784
7053
  kind: "postfix",
6785
7054
  parse: (_parser, lhs) => {
6786
7055
  return ["Complement", lhs];
@@ -6790,14 +7059,14 @@ var ComputeEngine = (() => {
6790
7059
  },
6791
7060
  {
6792
7061
  name: "Complement",
6793
- trigger: ["^", "<{>", "\\complement", "<}>"],
7062
+ latexTrigger: ["^", "<{>", "\\complement", "<}>"],
6794
7063
  kind: "postfix"
6795
7064
  // precedence: 240,
6796
7065
  // @todo: serialize for the multiple argument case
6797
7066
  },
6798
7067
  {
6799
7068
  name: "Intersection",
6800
- trigger: ["\\cap"],
7069
+ latexTrigger: ["\\cap"],
6801
7070
  kind: "infix",
6802
7071
  precedence: 350
6803
7072
  },
@@ -6813,7 +7082,7 @@ var ComputeEngine = (() => {
6813
7082
  },
6814
7083
  {
6815
7084
  name: "Union",
6816
- trigger: ["\\cup"],
7085
+ latexTrigger: ["\\cup"],
6817
7086
  kind: "infix",
6818
7087
  precedence: 350
6819
7088
  },
@@ -6832,13 +7101,13 @@ var ComputeEngine = (() => {
6832
7101
  // },
6833
7102
  {
6834
7103
  name: "SetMinus",
6835
- trigger: ["\\setminus"],
7104
+ latexTrigger: ["\\setminus"],
6836
7105
  kind: "infix",
6837
7106
  precedence: 650
6838
7107
  },
6839
7108
  {
6840
7109
  name: "SymmetricDifference",
6841
- trigger: ["\\triangle"],
7110
+ latexTrigger: ["\\triangle"],
6842
7111
  // or \\ominus
6843
7112
  kind: "infix",
6844
7113
  // @todo: parser could check that lhs and rhs are sets
@@ -6846,7 +7115,7 @@ var ComputeEngine = (() => {
6846
7115
  },
6847
7116
  // Predicates/Relations
6848
7117
  {
6849
- trigger: ["\\ni"],
7118
+ latexTrigger: ["\\ni"],
6850
7119
  kind: "infix",
6851
7120
  associativity: "right",
6852
7121
  precedence: 160,
@@ -6858,40 +7127,40 @@ var ComputeEngine = (() => {
6858
7127
  },
6859
7128
  {
6860
7129
  name: "Element",
6861
- trigger: ["\\in"],
7130
+ latexTrigger: ["\\in"],
6862
7131
  kind: "infix",
6863
7132
  precedence: 240
6864
7133
  },
6865
7134
  {
6866
7135
  name: "NotElement",
6867
- trigger: ["\\notin"],
7136
+ latexTrigger: ["\\notin"],
6868
7137
  kind: "infix",
6869
7138
  precedence: 240
6870
7139
  },
6871
7140
  {
6872
7141
  name: "NotSubset",
6873
- trigger: ["\\nsubset"],
7142
+ latexTrigger: ["\\nsubset"],
6874
7143
  kind: "infix",
6875
7144
  associativity: "right",
6876
7145
  precedence: 240
6877
7146
  },
6878
7147
  {
6879
7148
  name: "NotSuperset",
6880
- trigger: ["\\nsupset"],
7149
+ latexTrigger: ["\\nsupset"],
6881
7150
  kind: "infix",
6882
7151
  associativity: "right",
6883
7152
  precedence: 240
6884
7153
  },
6885
7154
  {
6886
7155
  name: "NotSubsetNotEqual",
6887
- trigger: ["\\nsubseteq"],
7156
+ latexTrigger: ["\\nsubseteq"],
6888
7157
  kind: "infix",
6889
7158
  associativity: "right",
6890
7159
  precedence: 240
6891
7160
  },
6892
7161
  {
6893
7162
  name: "NotSupersetNotEqual",
6894
- trigger: ["\\nsupseteq"],
7163
+ latexTrigger: ["\\nsupseteq"],
6895
7164
  kind: "infix",
6896
7165
  associativity: "right",
6897
7166
  precedence: 240
@@ -6899,7 +7168,7 @@ var ComputeEngine = (() => {
6899
7168
  {
6900
7169
  name: "SquareSubset",
6901
7170
  // MathML: square image of
6902
- trigger: ["\\sqsubset"],
7171
+ latexTrigger: ["\\sqsubset"],
6903
7172
  kind: "infix",
6904
7173
  associativity: "right",
6905
7174
  precedence: 265
@@ -6907,7 +7176,7 @@ var ComputeEngine = (() => {
6907
7176
  {
6908
7177
  name: "SquareSubsetEqual",
6909
7178
  // MathML: square image of or equal to
6910
- trigger: ["\\sqsubseteq"],
7179
+ latexTrigger: ["\\sqsubseteq"],
6911
7180
  kind: "infix",
6912
7181
  associativity: "right",
6913
7182
  precedence: 265
@@ -6915,7 +7184,7 @@ var ComputeEngine = (() => {
6915
7184
  {
6916
7185
  name: "SquareSuperset",
6917
7186
  // MathML: square original of
6918
- trigger: ["\\sqsupset"],
7187
+ latexTrigger: ["\\sqsupset"],
6919
7188
  kind: "infix",
6920
7189
  associativity: "right",
6921
7190
  precedence: 265
@@ -6923,27 +7192,27 @@ var ComputeEngine = (() => {
6923
7192
  {
6924
7193
  name: "SquareSupersetEqual",
6925
7194
  // MathML: square original of or equal
6926
- trigger: ["\\sqsupseteq"],
7195
+ latexTrigger: ["\\sqsupseteq"],
6927
7196
  kind: "infix",
6928
7197
  associativity: "right",
6929
7198
  precedence: 265
6930
7199
  },
6931
7200
  {
6932
7201
  name: "Subset",
6933
- trigger: ["\\subset"],
7202
+ latexTrigger: ["\\subset"],
6934
7203
  kind: "infix",
6935
7204
  associativity: "right",
6936
7205
  precedence: 240
6937
7206
  },
6938
7207
  {
6939
- trigger: ["\\subsetneq"],
7208
+ latexTrigger: ["\\subsetneq"],
6940
7209
  kind: "infix",
6941
7210
  associativity: "right",
6942
7211
  precedence: 240,
6943
7212
  parse: "Subset"
6944
7213
  },
6945
7214
  {
6946
- trigger: ["\\varsubsetneqq"],
7215
+ latexTrigger: ["\\varsubsetneqq"],
6947
7216
  kind: "infix",
6948
7217
  associativity: "right",
6949
7218
  precedence: 240,
@@ -6951,26 +7220,26 @@ var ComputeEngine = (() => {
6951
7220
  },
6952
7221
  {
6953
7222
  name: "SubsetEqual",
6954
- trigger: ["\\subseteq"],
7223
+ latexTrigger: ["\\subseteq"],
6955
7224
  kind: "infix",
6956
7225
  precedence: 240
6957
7226
  },
6958
7227
  {
6959
7228
  name: "Superset",
6960
- trigger: ["\\supset"],
7229
+ latexTrigger: ["\\supset"],
6961
7230
  kind: "infix",
6962
7231
  associativity: "right",
6963
7232
  precedence: 240
6964
7233
  },
6965
7234
  {
6966
- trigger: ["\\supsetneq"],
7235
+ latexTrigger: ["\\supsetneq"],
6967
7236
  kind: "infix",
6968
7237
  associativity: "right",
6969
7238
  precedence: 240,
6970
7239
  parse: "Superset"
6971
7240
  },
6972
7241
  {
6973
- trigger: ["\\varsupsetneq"],
7242
+ latexTrigger: ["\\varsupsetneq"],
6974
7243
  kind: "infix",
6975
7244
  associativity: "right",
6976
7245
  precedence: 240,
@@ -6978,7 +7247,7 @@ var ComputeEngine = (() => {
6978
7247
  },
6979
7248
  {
6980
7249
  name: "SupersetEqual",
6981
- trigger: ["\\supseteq"],
7250
+ latexTrigger: ["\\supseteq"],
6982
7251
  kind: "infix",
6983
7252
  associativity: "right",
6984
7253
  precedence: 240
@@ -7141,6 +7410,8 @@ var ComputeEngine = (() => {
7141
7410
  condition: () => {
7142
7411
  if (parser.matchAll(["\\mathrm", "<{>", "d", "<}>"]))
7143
7412
  found = true;
7413
+ else if (parser.matchAll(["\\operatorname", "<{>", "d", "<}>"]))
7414
+ found = true;
7144
7415
  return found;
7145
7416
  }
7146
7417
  });
@@ -7258,7 +7529,7 @@ var ComputeEngine = (() => {
7258
7529
  command,
7259
7530
  "\\!",
7260
7531
  serializer.serialize(fn),
7261
- "\\,\\mathrm{d}",
7532
+ "\\,\\operatorname{d}",
7262
7533
  serializer.serialize(index)
7263
7534
  ]);
7264
7535
  }
@@ -7276,7 +7547,7 @@ var ComputeEngine = (() => {
7276
7547
  sub2,
7277
7548
  "\\!",
7278
7549
  serializer.serialize(fn),
7279
- ...index && symbol(index) !== "Nothing" ? ["\\,\\mathrm{d}", serializer.serialize(index)] : []
7550
+ ...index && symbol(index) !== "Nothing" ? ["\\,\\operatorname{d}", serializer.serialize(index)] : []
7280
7551
  ]);
7281
7552
  };
7282
7553
  }
@@ -7284,35 +7555,35 @@ var ComputeEngine = (() => {
7284
7555
  {
7285
7556
  kind: "expression",
7286
7557
  name: "Integrate",
7287
- trigger: ["\\int"],
7558
+ latexTrigger: ["\\int"],
7288
7559
  parse: parseIntegral("Integrate"),
7289
7560
  serialize: serializeIntegral("\\int")
7290
7561
  },
7291
7562
  {
7292
7563
  kind: "expression",
7293
- trigger: ["\\iint"],
7564
+ latexTrigger: ["\\iint"],
7294
7565
  parse: parseIntegral("Integrate", 2)
7295
7566
  },
7296
7567
  {
7297
7568
  kind: "expression",
7298
- trigger: ["\\iiint"],
7569
+ latexTrigger: ["\\iiint"],
7299
7570
  parse: parseIntegral("Integrate", 3)
7300
7571
  },
7301
7572
  {
7302
7573
  kind: "expression",
7303
7574
  name: "CircularIntegrate",
7304
- trigger: ["\\oint"],
7575
+ latexTrigger: ["\\oint"],
7305
7576
  parse: parseIntegral("CircularIntegrate"),
7306
7577
  serialize: serializeIntegral("\\oint")
7307
7578
  },
7308
7579
  {
7309
7580
  kind: "expression",
7310
- trigger: ["\\oiint"],
7581
+ latexTrigger: ["\\oiint"],
7311
7582
  parse: parseIntegral("CircularIntegrate", 2)
7312
7583
  },
7313
7584
  {
7314
7585
  kind: "expression",
7315
- trigger: ["\\oiiint"],
7586
+ latexTrigger: ["\\oiiint"],
7316
7587
  parse: parseIntegral("CircularIntegrate", 3)
7317
7588
  }
7318
7589
  ];
@@ -7419,14 +7690,14 @@ var ComputeEngine = (() => {
7419
7690
  return {
7420
7691
  kind: "symbol",
7421
7692
  name: symbol2,
7422
- trigger: [latex],
7693
+ latexTrigger: [latex],
7423
7694
  parse: symbol2
7424
7695
  };
7425
7696
  }),
7426
7697
  ...SYMBOLS.map(([symbol2, _latex, codepoint]) => {
7427
7698
  return {
7428
7699
  kind: "symbol",
7429
- trigger: [String.fromCodePoint(codepoint)],
7700
+ latexTrigger: [String.fromCodePoint(codepoint)],
7430
7701
  parse: symbol2
7431
7702
  };
7432
7703
  })
@@ -7449,293 +7720,350 @@ var ComputeEngine = (() => {
7449
7720
  "\\rceil": "\\rceil",
7450
7721
  "\\rfloor": "\\rfloor"
7451
7722
  };
7452
- function triggerLength(trigger) {
7453
- if (Array.isArray(trigger))
7454
- return trigger.length;
7455
- return 1;
7456
- }
7457
7723
  function addEntry(result, entry, onError) {
7458
- const [trigger, indexedEntry] = makeIndexedEntry(entry, onError);
7724
+ const indexedEntry = makeIndexedEntry(entry, onError);
7459
7725
  if (indexedEntry === null)
7460
7726
  return;
7461
7727
  const kind = "kind" in entry ? entry.kind : "expression";
7462
- if (trigger && trigger.length === 2 && /[_^]/.test(trigger[0]) && trigger[1] !== "<{>" && kind !== "function" && entry.name) {
7728
+ const latexTrigger = indexedEntry.latexTrigger;
7729
+ if (typeof latexTrigger === "string")
7730
+ result.lookahead = Math.max(result.lookahead, countTokens(latexTrigger));
7731
+ const tokensTrigger = tokenize(latexTrigger ?? "", []);
7732
+ if (latexTrigger?.[1] === "\\prime")
7733
+ ;
7734
+ if (tokensTrigger.length === 2 && /[_^]/.test(tokensTrigger[0]) && tokensTrigger[1] !== "<{>" && kind !== "function" && kind !== "environment" && kind !== "matchfix") {
7463
7735
  let parse = entry.parse;
7464
- if (parse === void 0) {
7465
- if (kind === "symbol")
7466
- parse = entry.name;
7736
+ if (!parse && entry.name) {
7467
7737
  if (kind === "postfix" || kind === "prefix")
7468
7738
  parse = (_parser, expr) => [entry.name, expr];
7739
+ else
7740
+ parse = entry.name;
7469
7741
  }
7470
7742
  addEntry(
7471
7743
  result,
7472
7744
  {
7473
7745
  ...entry,
7474
7746
  kind,
7475
- parse,
7476
7747
  name: void 0,
7477
- trigger: [trigger[0], "<{>", trigger[1], "<}>"]
7748
+ serialize: void 0,
7749
+ parse,
7750
+ latexTrigger: [tokensTrigger[0], "<{>", tokensTrigger[1], "<}>"]
7478
7751
  },
7479
7752
  onError
7480
7753
  );
7481
7754
  }
7755
+ result.defs.push(indexedEntry);
7482
7756
  if (indexedEntry.name !== void 0) {
7483
- if (result.name.has(indexedEntry.name)) {
7757
+ if (result.ids.has(indexedEntry.name)) {
7484
7758
  onError({
7485
7759
  severity: "warning",
7486
7760
  message: [
7487
7761
  "invalid-dictionary-entry",
7488
7762
  indexedEntry.name,
7489
- "Duplicate definition. The name must be unique, but a trigger can be used by multiple definitions."
7490
- ]
7491
- });
7492
- }
7493
- result.name.set(indexedEntry.name, indexedEntry);
7494
- }
7495
- if (indexedEntry.kind === "matchfix") {
7496
- result.matchfix.push(indexedEntry);
7497
- } else if (indexedEntry.kind === "environment") {
7498
- const triggerString = tokensToString(entry.trigger ?? "");
7499
- if (result.environment.has(triggerString)) {
7500
- onError({
7501
- severity: "warning",
7502
- message: [
7503
- "invalid-dictionary-entry",
7504
- triggerString,
7505
- "Duplicate environment definition"
7763
+ "Duplicate definition. The name (MathJSON identifier) must be unique, but triggers can be shared by multiple definitions."
7506
7764
  ]
7507
7765
  });
7508
7766
  }
7509
- result.environment.set(triggerString, indexedEntry);
7510
- } else if (trigger) {
7511
- /* @__PURE__ */ console.assert(entry.trigger);
7512
- const triggerString = tokensToString(entry.trigger ?? "");
7513
- const n = triggerLength(trigger);
7514
- result.lookahead = Math.max(result.lookahead, n);
7515
- if (indexedEntry.kind === "function") {
7516
- if (!result.function.has(triggerString))
7517
- result.function.set(triggerString, [indexedEntry]);
7518
- else
7519
- result.function.set(triggerString, [
7520
- ...result.function.get(triggerString),
7521
- indexedEntry
7522
- ]);
7523
- } else {
7524
- const kind2 = indexedEntry.kind;
7525
- if (result[kind2][n] === void 0)
7526
- result[kind2][n] = /* @__PURE__ */ new Map();
7527
- const list = result[kind2][n];
7528
- if (list.has(triggerString))
7529
- list.get(triggerString).push(indexedEntry);
7530
- else
7531
- list.set(triggerString, [indexedEntry]);
7532
- }
7767
+ result.ids.set(indexedEntry.name, indexedEntry);
7533
7768
  }
7534
7769
  }
7535
7770
  function indexLatexDictionary(dic, onError) {
7536
7771
  const result = {
7537
7772
  lookahead: 1,
7538
- name: /* @__PURE__ */ new Map(),
7539
- expression: [],
7540
- symbol: [],
7541
- infix: [],
7542
- prefix: [],
7543
- postfix: [],
7544
- function: /* @__PURE__ */ new Map(),
7545
- environment: /* @__PURE__ */ new Map(),
7546
- matchfix: []
7773
+ ids: /* @__PURE__ */ new Map(),
7774
+ defs: []
7547
7775
  };
7548
7776
  for (const entry of dic)
7549
7777
  addEntry(result, entry, onError);
7550
7778
  return result;
7551
7779
  }
7552
7780
  function makeIndexedEntry(entry, onError) {
7553
- if (!entryIsValid(entry, onError))
7554
- return [null, null];
7781
+ if (!isValidEntry(entry, onError))
7782
+ return null;
7555
7783
  const result = {
7556
- name: entry.name,
7557
7784
  kind: "kind" in entry ? entry.kind : "expression"
7558
7785
  };
7786
+ let tokensTrigger = null;
7787
+ if ("latexTrigger" in entry) {
7788
+ if (typeof entry.latexTrigger === "string")
7789
+ tokensTrigger = tokenize(entry.latexTrigger, []);
7790
+ else
7791
+ tokensTrigger = entry.latexTrigger;
7792
+ }
7793
+ let idTrigger = null;
7794
+ if ("identifierTrigger" in entry) {
7795
+ idTrigger = entry.identifierTrigger;
7796
+ }
7797
+ if (tokensTrigger !== null)
7798
+ result.latexTrigger = tokensToString(tokensTrigger);
7799
+ if (idTrigger !== null)
7800
+ result.identifierTrigger = idTrigger;
7801
+ if (entry.name) {
7802
+ result.name = entry.name;
7803
+ result.serialize = makeSerializeHandler(entry, tokensTrigger, idTrigger);
7804
+ }
7559
7805
  if (result.kind === "matchfix" && isMatchfixEntry(entry)) {
7560
- result.openDelimiter = entry.openDelimiter;
7561
- result.closeDelimiter = entry.closeDelimiter;
7562
- if (typeof entry.serialize === "function")
7563
- result.serialize = entry.serialize;
7564
- else {
7565
- const openDelim = typeof result.openDelimiter === "string" ? DEFAULT_DELIMITER[result.openDelimiter] : tokensToString(result.openDelimiter);
7566
- const closeDelim = typeof result.closeDelimiter === "string" ? DEFAULT_DELIMITER[result.closeDelimiter] : tokensToString(result.closeDelimiter);
7567
- result.serialize = (serializer, expr) => joinLatex([openDelim, serializer.serialize(op(expr, 1)), closeDelim]);
7568
- }
7569
- if (typeof entry.parse === "function")
7570
- result.parse = entry.parse;
7571
- else {
7572
- /* @__PURE__ */ console.assert(entry.parse || entry.name);
7573
- const head2 = entry.parse ?? entry.name;
7574
- result.parse = (_parser, expr) => [head2, expr];
7575
- }
7576
- return [null, result];
7577
- }
7578
- if (result.kind === "environment" && isEnvironmentEntry(entry)) {
7579
- const envName = entry.trigger;
7580
- result.serialize = entry.serialize ?? ((serializer, expr) => `\\begin{${envName}}${serializer.serialize(
7581
- op(expr, 1)
7582
- )}\\end{${envName}}`);
7583
- result.parse = entry.parse ?? (() => null);
7584
- return [envName, result];
7585
- }
7586
- const trigger = typeof entry.trigger === "string" ? tokenize(entry.trigger, []) : entry.trigger;
7587
- const triggerString = trigger ? tokensToString(trigger) : "";
7588
- if (result.kind === "function" && isFunctionEntry(entry)) {
7589
- result.serialize = entry.serialize;
7590
- if (triggerString && !entry.serialize) {
7591
- if (triggerString.startsWith("\\")) {
7592
- result.serialize = (serializer, expr) => `${triggerString}${serializer.wrapArguments(expr)}`;
7593
- } else
7594
- result.serialize = (serializer, expr) => `\\mathrm{${triggerString}}${serializer.wrapArguments(expr)}`;
7595
- }
7596
- if (typeof entry.parse === "function")
7597
- result.parse = entry.parse;
7598
- else if (typeof entry.parse === "string")
7599
- result.parse = () => entry.parse;
7600
- else if (entry.name)
7601
- result.parse = () => entry.name;
7602
- return [triggerString, result];
7603
- }
7604
- if (result.kind === "expression" && isExpressionEntry(entry)) {
7605
- result.serialize = entry.serialize ?? triggerString;
7606
- if (typeof result.serialize === "string") {
7607
- const serializeExpr = result.serialize;
7608
- result.serialize = (serializer, expr) => {
7609
- if (!head(expr))
7610
- return serializer.serialize(serializeExpr);
7611
- return `${serializer.serialize(
7612
- serializeExpr
7613
- )}${serializer.wrapArguments(expr)}`;
7614
- };
7615
- }
7616
- {
7617
- if (typeof entry.parse === "function") {
7618
- result.parse = entry.parse;
7619
- } else {
7620
- const parseResult = entry.parse ?? entry.name;
7621
- result.parse = () => parseResult;
7622
- }
7623
- }
7624
- return [triggerString, result];
7806
+ result.openDelimiter = entry.openTrigger;
7807
+ result.closeDelimiter = entry.closeTrigger;
7625
7808
  }
7626
- /* @__PURE__ */ console.assert(
7627
- typeof entry.trigger !== "string" || entry.parse || trigger.length > 1 || "kind" in entry && entry.kind === "function",
7628
- `Trigger shortcuts should produce more than one token. Otherwise, not worth using them. (${triggerString})`
7629
- );
7630
7809
  if (result.kind === "symbol" && isSymbolEntry(entry)) {
7631
7810
  result.precedence = entry.precedence ?? 1e4;
7632
7811
  }
7633
- if ((result.kind === "infix" || result.kind === "prefix" || result.kind === "postfix") && (isInfixEntry(entry) || isPrefixEntry(entry) || isPostfixEntry(entry))) {
7634
- if (trigger && (trigger[0] === "^" || trigger[0] === "_")) {
7812
+ if ((result.kind === "prefix" || result.kind === "postfix") && (isPrefixEntry(entry) || isPostfixEntry(entry))) {
7813
+ if (tokensTrigger && (tokensTrigger[0] === "^" || tokensTrigger[0] === "_")) {
7635
7814
  result.precedence = 720;
7636
7815
  /* @__PURE__ */ console.assert(
7637
7816
  entry.precedence === void 0,
7638
- "'precedence' not allowed with ^ and _ triggers"
7817
+ "'precedence' is fixed and cannot be modified with ^ and _ triggers"
7639
7818
  );
7640
7819
  } else
7641
7820
  result.precedence = entry.precedence ?? 1e4;
7642
7821
  }
7643
7822
  if (result.kind === "infix" && isInfixEntry(entry)) {
7644
7823
  /* @__PURE__ */ console.assert(
7645
- !trigger || trigger[0] !== "^" && trigger[0] !== "_" || !entry.associativity || entry.associativity === "non"
7824
+ !tokensTrigger || tokensTrigger[0] !== "^" && tokensTrigger[0] !== "_" || !entry.associativity || entry.associativity === "non"
7646
7825
  );
7647
7826
  result.associativity = entry.associativity ?? "non";
7648
- if (typeof entry.parse === "function") {
7649
- result.parse = entry.parse;
7650
- } else if (trigger && (trigger[0] === "^" || trigger[0] === "_")) {
7651
- /* @__PURE__ */ console.assert(!entry.parse);
7652
- const name = entry.parse ?? entry.name;
7653
- result.parse = (_scanner, arg, _terminator) => [
7654
- name,
7827
+ result.precedence = entry.precedence ?? 1e4;
7828
+ }
7829
+ const parse = makeParseHandler(entry, tokensTrigger, idTrigger);
7830
+ if (parse)
7831
+ result.parse = parse;
7832
+ return result;
7833
+ }
7834
+ function makeSerializeHandler(entry, latexTrigger, idTrigger) {
7835
+ if (typeof entry.serialize === "function")
7836
+ return entry.serialize;
7837
+ const kind = entry["kind"] ?? "expression";
7838
+ if (kind === "environment") {
7839
+ const envName = entry["identifierTrigger"] ?? entry.name ?? "unknown";
7840
+ return (serializer, expr) => joinLatex([
7841
+ `\\begin{${envName}}`,
7842
+ serializer.serialize(op(expr, 1)),
7843
+ `\\end{${envName}}`
7844
+ ]);
7845
+ }
7846
+ if (isMatchfixEntry(entry)) {
7847
+ const openDelim = typeof entry.openTrigger === "string" ? DEFAULT_DELIMITER[entry.openTrigger] : tokensToString(entry["openDelimiter"]);
7848
+ const closeDelim = typeof entry.closeTrigger === "string" ? DEFAULT_DELIMITER[entry.closeTrigger] : tokensToString(entry["closeDelimiter"]);
7849
+ return (serializer, expr) => joinLatex([openDelim, serializer.serialize(op(expr, 1)), closeDelim]);
7850
+ }
7851
+ let latex = entry.serialize;
7852
+ if (latex === void 0 && latexTrigger)
7853
+ latex = tokensToString(latexTrigger);
7854
+ if (latex) {
7855
+ if (kind === "postfix")
7856
+ return (serializer, expr) => joinLatex([serializer.serialize(op(expr, 1)), latex]);
7857
+ if (kind === "prefix")
7858
+ return (serializer, expr) => joinLatex([latex, serializer.serialize(op(expr, 1))]);
7859
+ if (kind === "infix") {
7860
+ return (serializer, expr) => joinLatex(
7861
+ (ops(expr) ?? []).flatMap(
7862
+ (val, i) => i < nops(expr) - 1 ? [serializer.serialize(val), latex] : [serializer.serialize(val)]
7863
+ )
7864
+ );
7865
+ }
7866
+ return (serializer, expr) => head(expr) ? joinLatex([latex, serializer.wrapArguments(expr)]) : latex;
7867
+ }
7868
+ const id = idTrigger ?? entry.name ?? "unknown";
7869
+ if (kind === "postfix")
7870
+ return (serializer, expr) => joinLatex([
7871
+ serializer.serialize(op(expr, 1)),
7872
+ serializer.serializeSymbol(id)
7873
+ ]);
7874
+ if (kind === "prefix")
7875
+ return (serializer, expr) => joinLatex([
7876
+ serializer.serializeSymbol(id),
7877
+ serializer.serialize(op(expr, 1))
7878
+ ]);
7879
+ if (kind === "infix")
7880
+ return (serializer, expr) => joinLatex([
7881
+ serializer.serialize(op(expr, 1)),
7882
+ serializer.serializeSymbol(id),
7883
+ serializer.serialize(op(expr, 2))
7884
+ ]);
7885
+ return (serializer, expr) => head(expr) ? joinLatex([
7886
+ serializer.serializeSymbol(id),
7887
+ serializer.wrapArguments(expr)
7888
+ ]) : serializer.serializeSymbol(id);
7889
+ }
7890
+ function makeParseHandler(entry, latexTrigger, idTrigger) {
7891
+ if ("parse" in entry && typeof entry.parse === "function")
7892
+ return entry.parse;
7893
+ const kind = "kind" in entry ? entry.kind : "expression";
7894
+ if (kind === "environment") {
7895
+ const envName = entry.parse ?? idTrigger ?? entry.name;
7896
+ if (envName)
7897
+ return (parser, _until) => {
7898
+ const array = parser.parseTabular();
7899
+ if (array === null)
7900
+ return null;
7901
+ return [envName, ["List", array.map((row) => ["List", ...row])]];
7902
+ };
7903
+ }
7904
+ if (kind === "function") {
7905
+ const fnName = entry.parse ?? idTrigger ?? entry.name;
7906
+ if (fnName)
7907
+ return (parser, until) => {
7908
+ const args = parser.parseArguments("enclosure", until);
7909
+ return args === null ? fnName : [fnName, ...args];
7910
+ };
7911
+ }
7912
+ if (kind === "symbol") {
7913
+ const symName = entry.parse ?? idTrigger ?? entry.name;
7914
+ if (symName)
7915
+ return (_parser, _terminator) => symName;
7916
+ }
7917
+ if (kind === "prefix") {
7918
+ const h = entry.parse ?? idTrigger ?? entry.name;
7919
+ if (h) {
7920
+ const prec = entry["precedence"] ?? 1e4;
7921
+ return (parser, until) => {
7922
+ const rhs = parser.parseExpression({
7923
+ ...until ?? [],
7924
+ minPrec: prec
7925
+ });
7926
+ return rhs === null ? null : [h, rhs];
7927
+ };
7928
+ }
7929
+ }
7930
+ if (kind === "postfix") {
7931
+ const h = entry.parse ?? entry.name;
7932
+ if (h)
7933
+ return (_parser, lhs) => lhs === null ? null : [h, lhs];
7934
+ }
7935
+ if (kind === "infix") {
7936
+ if (/[_^]/.test(latexTrigger?.[0] ?? "")) {
7937
+ const h2 = entry.name ?? entry.parse;
7938
+ return (_parser, arg) => [
7939
+ h2,
7655
7940
  missingIfEmpty(op(arg, 1)),
7656
7941
  missingIfEmpty(op(arg, 2))
7657
7942
  ];
7658
- } else {
7659
- const head2 = entry.parse ?? entry.name;
7660
- const prec = result.precedence;
7661
- const associativity = result.associativity;
7662
- result.parse = (scanner, lhs, terminator) => {
7663
- if (prec < terminator.minPrec)
7943
+ }
7944
+ const h = entry.parse ?? idTrigger ?? entry.name;
7945
+ const prec = entry["precedence"] ?? 1e4;
7946
+ const associativity = entry["associativity"] ?? "non";
7947
+ if (h)
7948
+ return (parser, lhs, until) => {
7949
+ if (lhs === null)
7950
+ return null;
7951
+ if (prec < until.minPrec)
7664
7952
  return null;
7665
7953
  const rhs = missingIfEmpty(
7666
- scanner.parseExpression({
7667
- ...terminator,
7668
- minPrec: prec
7669
- })
7954
+ parser.parseExpression({ ...until, minPrec: prec })
7670
7955
  );
7671
- return typeof head2 === "string" ? applyAssociativeOperator(head2, lhs, rhs, associativity) : [head2, lhs, rhs];
7956
+ return typeof h === "string" ? applyAssociativeOperator(h, lhs, rhs, associativity) : [h, lhs, rhs];
7672
7957
  };
7673
- }
7674
- } else {
7675
- if (typeof entry.parse === "function") {
7676
- result.parse = entry.parse;
7677
- } else if (entry.parse !== void 0) {
7678
- /* @__PURE__ */ console.assert(result.kind === "symbol" || result.kind === "expression");
7679
- result.parse = () => entry.parse;
7680
- } else if (entry.parse === void 0 && entry.name !== void 0) {
7681
- if (result.kind === "postfix") {
7682
- result.parse = (_parser, lhs) => lhs ? [entry.name, lhs] : null;
7683
- } else if (result.kind === "prefix") {
7684
- const prec = result.precedence;
7685
- /* @__PURE__ */ console.assert(entry.name);
7686
- const head2 = entry.name;
7687
- result.parse = (parser, terminator) => {
7688
- if (terminator && prec < terminator.minPrec)
7689
- return null;
7690
- const rhs = parser.parseExpression({ ...terminator, minPrec: prec });
7691
- return rhs === null ? null : [head2, rhs];
7692
- };
7693
- }
7694
- }
7695
- }
7696
- if (typeof entry.serialize === "function" || typeof entry.serialize === "string") {
7697
- result.serialize = entry.serialize;
7698
- } else if (trigger) {
7699
- if (result.kind === "postfix") {
7700
- result.serialize = "#1" + triggerString;
7701
- } else if (result.kind === "prefix") {
7702
- result.serialize = triggerString + "#1";
7703
- } else if (result.kind === "infix") {
7704
- result.serialize = "#1" + triggerString + "#2";
7705
- } else if (result.kind === "symbol") {
7706
- result.serialize = triggerString;
7707
- } else {
7708
- result.serialize = "";
7709
- }
7710
7958
  }
7711
- return [trigger ?? null, result];
7959
+ if (kind === "matchfix") {
7960
+ const h = entry.parse ?? entry.name;
7961
+ if (h)
7962
+ return (_parser, body) => {
7963
+ if (body === null || isEmptySequence(body))
7964
+ return null;
7965
+ return [h, body];
7966
+ };
7967
+ }
7968
+ if (kind === "expression") {
7969
+ const parseResult = entry.parse ?? idTrigger ?? entry.name;
7970
+ if (parseResult)
7971
+ return () => parseResult;
7972
+ }
7973
+ if ("parse" in entry) {
7974
+ const parseResult = entry.parse;
7975
+ return () => parseResult;
7976
+ }
7977
+ return void 0;
7712
7978
  }
7713
- function entryIsValid(entry, onError) {
7714
- const subject = entry.name ?? entry.trigger ?? entry["openDelimiter"];
7979
+ function isValidEntry(entry, onError) {
7980
+ let subject = entry.name ?? entry["latexTrigger"] ?? entry["identifierTrigger"] ?? entry["openDelimiter"];
7981
+ if (!subject) {
7982
+ try {
7983
+ subject = JSON.stringify(entry);
7984
+ } catch (e) {
7985
+ subject = "???";
7986
+ }
7987
+ }
7988
+ if (Array.isArray(subject))
7989
+ subject = tokensToString(subject);
7990
+ if ("kind" in entry && ![
7991
+ "expression",
7992
+ "symbol",
7993
+ "function",
7994
+ "infix",
7995
+ "postfix",
7996
+ "prefix",
7997
+ "matchfix",
7998
+ "environment"
7999
+ ].includes(entry.kind)) {
8000
+ onError({
8001
+ severity: "warning",
8002
+ message: [
8003
+ "invalid-dictionary-entry",
8004
+ subject,
8005
+ `The 'kind' property must be one of 'expression', 'symbol', 'function', 'infix', 'postfix', 'prefix', 'matchfix', 'environment'`
8006
+ ]
8007
+ });
8008
+ }
7715
8009
  if (entry.serialize !== void 0 && !entry.name) {
7716
8010
  onError({
7717
8011
  severity: "warning",
7718
8012
  message: [
7719
8013
  "invalid-dictionary-entry",
7720
8014
  subject,
7721
- `Unexpected serialize property without a name property`
8015
+ `A 'name' property must be provided if a 'serialize' handler is provided`
7722
8016
  ]
7723
8017
  });
7724
8018
  return false;
7725
8019
  }
8020
+ if ("identifierTrigger" in entry) {
8021
+ if (typeof entry.identifierTrigger !== "string" || !isValidIdentifier(entry.identifierTrigger)) {
8022
+ onError({
8023
+ severity: "warning",
8024
+ message: [
8025
+ "invalid-dictionary-entry",
8026
+ subject,
8027
+ `The 'identifierTrigger' property must be a valid identifier`
8028
+ ]
8029
+ });
8030
+ }
8031
+ }
8032
+ if ("name" in entry) {
8033
+ if (typeof entry.name !== "string") {
8034
+ if (entry.name !== void 0)
8035
+ onError({
8036
+ severity: "warning",
8037
+ message: [
8038
+ "invalid-dictionary-entry",
8039
+ subject,
8040
+ `The 'name' property must be a string`
8041
+ ]
8042
+ });
8043
+ } else if (!isValidIdentifier(entry.name)) {
8044
+ onError({
8045
+ severity: "warning",
8046
+ message: [
8047
+ "invalid-dictionary-entry",
8048
+ entry.name,
8049
+ `The 'name' property must be a valid identifier`
8050
+ ]
8051
+ });
8052
+ }
8053
+ }
7726
8054
  if (isMatchfixEntry(entry)) {
7727
- if (entry.trigger) {
8055
+ if ("latexTrigger" in entry || "identifierTrigger" in isPrefixEntry) {
7728
8056
  onError({
7729
8057
  severity: "warning",
7730
8058
  message: [
7731
8059
  "invalid-dictionary-entry",
7732
8060
  subject,
7733
- `Unexpected 'trigger' "${entry.trigger}". 'matchfix' operators use a 'openDelimiter' and 'closeDelimiter' instead of a trigger. `
8061
+ `'matchfix' operators use a 'openDelimiter' and 'closeDelimiter' instead of a 'latexTrigger' or 'identifierTrigger'. `
7734
8062
  ]
7735
8063
  });
7736
8064
  return false;
7737
8065
  }
7738
- if (!entry.openDelimiter || !entry.closeDelimiter) {
8066
+ if (!entry.openTrigger || !entry.closeTrigger) {
7739
8067
  onError({
7740
8068
  severity: "warning",
7741
8069
  message: [
@@ -7746,7 +8074,7 @@ var ComputeEngine = (() => {
7746
8074
  });
7747
8075
  return false;
7748
8076
  }
7749
- if (typeof entry.openDelimiter !== typeof entry.closeDelimiter) {
8077
+ if (typeof entry.openTrigger !== typeof entry.closeTrigger) {
7750
8078
  onError({
7751
8079
  severity: "warning",
7752
8080
  message: [
@@ -7759,7 +8087,7 @@ var ComputeEngine = (() => {
7759
8087
  }
7760
8088
  }
7761
8089
  if (isInfixEntry(entry) || isPostfixEntry(entry) || isPrefixEntry(entry)) {
7762
- if (Array.isArray(entry.trigger) && (entry.trigger[0] === "_" || entry.trigger[0] === "^") || typeof entry.trigger === "string" && (entry.trigger.startsWith("^") || entry.trigger.startsWith("_"))) {
8090
+ if (Array.isArray(entry.latexTrigger) && (entry.latexTrigger[0] === "_" || entry.latexTrigger[0] === "^") || typeof entry.latexTrigger === "string" && (entry.latexTrigger.startsWith("^") || entry.latexTrigger.startsWith("_"))) {
7763
8091
  if (entry.precedence !== void 0 || entry["associativity"] !== void 0) {
7764
8092
  onError({
7765
8093
  severity: "warning",
@@ -7795,14 +8123,14 @@ var ComputeEngine = (() => {
7795
8123
  return false;
7796
8124
  }
7797
8125
  }
7798
- if (!isMatchfixEntry(entry)) {
7799
- if (!entry.trigger && !entry.name) {
8126
+ if (!isMatchfixEntry(entry) && !isEnvironmentEntry(entry)) {
8127
+ if (!entry.latexTrigger && !entry.identifierTrigger && !entry.name) {
7800
8128
  onError({
7801
8129
  severity: "warning",
7802
8130
  message: [
7803
8131
  "invalid-dictionary-entry",
7804
8132
  subject,
7805
- `Expected at least a 'trigger' or a 'name'`
8133
+ `Expected a 'name', a 'latexTrigger' or a 'identifierTrigger'`
7806
8134
  ]
7807
8135
  });
7808
8136
  return false;
@@ -7833,7 +8161,7 @@ var ComputeEngine = (() => {
7833
8161
  {
7834
8162
  name: "mu0",
7835
8163
  kind: "symbol",
7836
- trigger: "\\mu_0"
8164
+ latexTrigger: "\\mu_0"
7837
8165
  }
7838
8166
  ],
7839
8167
  sets: DEFINITIONS_SETS,
@@ -7843,7 +8171,24 @@ var ComputeEngine = (() => {
7843
8171
 
7844
8172
  // src/compute-engine/latex-syntax/parse-identifier.ts
7845
8173
  var IDENTIFIER_PREFIX = {
7846
- "\\operatorname": "_operator",
8174
+ // Those are "grouping" prefix that also specify spacing
8175
+ // around the symbol. We ignore the spacing, though.
8176
+ "\\mathord": "",
8177
+ "\\mathop": "",
8178
+ "\\mathbin": "",
8179
+ "\\mathrel": "",
8180
+ "\\mathopen": "",
8181
+ "\\mathclose": "",
8182
+ "\\mathpunct": "",
8183
+ "\\mathinner": "",
8184
+ // This is the preferred way to specify an identifier
8185
+ // it defines both spacing and font. By default, identifiers
8186
+ // are wrapper with `\\operatorname{}`.
8187
+ "\\operatorname": "",
8188
+ // These styling commands are used to change the font of an identifier
8189
+ // They may be problematic, as adjacent identifiers may be merged
8190
+ // into a single identifier when used in editors, such a MathLive.
8191
+ // For example `\mathrm{speed}\mathrm{sound}` can be confused with `\mathrm{speedsound}`
7847
8192
  "\\mathrm": "_upright",
7848
8193
  "\\mathit": "_italic",
7849
8194
  "\\mathbf": "_bold",
@@ -7870,7 +8215,7 @@ var ComputeEngine = (() => {
7870
8215
  "\\breve": "_breve",
7871
8216
  "\\check": "_check"
7872
8217
  };
7873
- function matchIdentifierToken(parser, options) {
8218
+ function parseIdentifierToken(parser, options) {
7874
8219
  if (parser.atEnd)
7875
8220
  return null;
7876
8221
  const token = parser.peek;
@@ -7908,7 +8253,7 @@ var ComputeEngine = (() => {
7908
8253
  }
7909
8254
  return parser.matchChar() ?? parser.nextToken();
7910
8255
  }
7911
- function matchIdentifierBody(parser) {
8256
+ function parseIdentifierBody(parser) {
7912
8257
  let id = matchPrefixedIdentifier(parser);
7913
8258
  const start = parser.index;
7914
8259
  const prefix = IDENTIFIER_MODIFIER[parser.peek] ?? null;
@@ -7918,7 +8263,7 @@ var ComputeEngine = (() => {
7918
8263
  parser.index = start;
7919
8264
  return null;
7920
8265
  }
7921
- const body = matchIdentifierBody(parser);
8266
+ const body = parseIdentifierBody(parser);
7922
8267
  if (body === null || !parser.match("<}>")) {
7923
8268
  parser.index = start;
7924
8269
  return null;
@@ -7931,7 +8276,7 @@ var ComputeEngine = (() => {
7931
8276
  const token = parser.peek;
7932
8277
  if (token === "<}>" || token === "_" || token === "^")
7933
8278
  break;
7934
- const next = matchIdentifierToken(parser, { toplevel: false });
8279
+ const next = parseIdentifierToken(parser, { toplevel: false });
7935
8280
  if (next === null) {
7936
8281
  parser.index = start;
7937
8282
  return null;
@@ -7960,7 +8305,7 @@ var ComputeEngine = (() => {
7960
8305
  while (!parser.atEnd) {
7961
8306
  if (parser.match("_")) {
7962
8307
  const hasBrace = parser.match("<{>");
7963
- const sub2 = matchIdentifierBody(parser);
8308
+ const sub2 = parseIdentifierBody(parser);
7964
8309
  if (hasBrace && !parser.match("<}>") || sub2 === null) {
7965
8310
  parser.index = start;
7966
8311
  return null;
@@ -7968,7 +8313,7 @@ var ComputeEngine = (() => {
7968
8313
  subs2.push(sub2);
7969
8314
  } else if (parser.match("^")) {
7970
8315
  const hasBrace = parser.match("<{>");
7971
- const sup = matchIdentifierBody(parser);
8316
+ const sup = parseIdentifierBody(parser);
7972
8317
  if (hasBrace && !parser.match("<}>") || sup === null) {
7973
8318
  parser.index = start;
7974
8319
  return null;
@@ -8007,7 +8352,7 @@ var ComputeEngine = (() => {
8007
8352
  body = digit;
8008
8353
  parser.nextToken();
8009
8354
  }
8010
- body += matchIdentifierBody(parser);
8355
+ body += parseIdentifierBody(parser);
8011
8356
  if (body === null || !parser.match("<}>")) {
8012
8357
  parser.index = start;
8013
8358
  return null;
@@ -8031,7 +8376,7 @@ var ComputeEngine = (() => {
8031
8376
  start
8032
8377
  );
8033
8378
  }
8034
- function matchIdentifier(parser) {
8379
+ function parseIdentifier(parser) {
8035
8380
  if (/^[a-zA-Z]$/.test(parser.peek) || /^\p{XIDS}$/u.test(parser.peek))
8036
8381
  return parser.nextToken();
8037
8382
  const start = parser.index;
@@ -8040,19 +8385,14 @@ var ComputeEngine = (() => {
8040
8385
  id = "";
8041
8386
  while (!parser.atEnd && ONLY_EMOJIS.test(id + parser.peek))
8042
8387
  id += parser.nextToken();
8388
+ if (!id)
8389
+ id = null;
8043
8390
  }
8391
+ id ?? (id = parseIdentifierToken(parser, { toplevel: true }));
8044
8392
  if (id) {
8045
8393
  id = id.normalize();
8046
8394
  if (isValidIdentifier(id))
8047
8395
  return id;
8048
- parser.index = start;
8049
- return null;
8050
- }
8051
- let next = matchIdentifierToken(parser, { toplevel: true });
8052
- if (next) {
8053
- next = next.normalize();
8054
- if (isValidIdentifier(next))
8055
- return next;
8056
8396
  }
8057
8397
  parser.index = start;
8058
8398
  return null;
@@ -8121,7 +8461,7 @@ var ComputeEngine = (() => {
8121
8461
  // with machine numbers, up to 15 assuming 2^53 bits floating points
8122
8462
  positiveInfinity: "\\infty",
8123
8463
  negativeInfinity: "-\\infty",
8124
- notANumber: "\\mathrm{NaN}",
8464
+ notANumber: "\\operatorname{NaN}",
8125
8465
  decimalMarker: ".",
8126
8466
  // Use `{,}` for comma as a decimal marker
8127
8467
  groupSeparator: "\\,",
@@ -8261,13 +8601,12 @@ var ComputeEngine = (() => {
8261
8601
  * Note: the `minPrec` condition is not checked. It should be checked separately.
8262
8602
  */
8263
8603
  atTerminator(t) {
8264
- if (this.atBoundary)
8265
- return true;
8266
- if (t?.condition && t.condition(this))
8267
- return true;
8268
- return false;
8604
+ return this.atBoundary || ((t?.condition && t.condition(this)) ?? false);
8269
8605
  }
8270
- /** True if the current token matches any of the boundaries we are waiting for */
8606
+ /**
8607
+ * True if the current token matches any of the boundaries we are
8608
+ * waiting for.
8609
+ */
8271
8610
  get atBoundary() {
8272
8611
  if (this.atEnd)
8273
8612
  return true;
@@ -8329,42 +8668,32 @@ var ComputeEngine = (() => {
8329
8668
  this._dictionary.lookahead,
8330
8669
  this._tokens.length - this.index
8331
8670
  );
8332
- if (n < 0)
8671
+ if (n <= 0)
8333
8672
  return [];
8334
- const result = Array(n + 1);
8673
+ const result = [];
8335
8674
  while (n > 0)
8336
- result[n] = this.latexAhead(n--);
8675
+ result.push([n, this.latexAhead(n--)]);
8337
8676
  return result;
8338
8677
  }
8339
8678
  peekDefinitions(kind) {
8340
- let defs;
8341
- if (kind === "function") {
8342
- const start = this.index;
8343
- if (this.match("\\operatorname") || this.match("\\mathrm") || this.match("\\mathit")) {
8344
- const fn = this.parseStringGroup()?.trim();
8345
- const n = this.index - start;
8346
- this.index = start;
8347
- if (!fn || !this._dictionary.function.has(fn))
8348
- return null;
8349
- return this._dictionary.function.get(fn).map((x) => [x, n]);
8350
- }
8351
- return null;
8352
- } else if (kind === "operator") {
8353
- defs = this.lookAhead().map(
8354
- (x, n) => this._dictionary.infix[n]?.get(x) ?? this._dictionary.postfix[n]?.get(x) ?? this._dictionary.prefix[n]?.get(x)
8355
- );
8356
- } else {
8357
- defs = this.lookAhead().map((x, n) => this._dictionary[kind][n]?.get(x));
8358
- }
8359
8679
  const result = [];
8360
- for (let i = defs.length; i > 0; i--) {
8361
- if (defs[i] !== void 0) {
8362
- /* @__PURE__ */ console.assert(Array.isArray(defs[i]));
8363
- for (const def of defs[i])
8364
- result.push([def, i]);
8680
+ const defs = [...this.getDefs(kind)];
8681
+ for (const def of defs)
8682
+ if (def.latexTrigger === "")
8683
+ result.push([def, 0]);
8684
+ for (const [n, tokens] of this.lookAhead()) {
8685
+ for (const def of defs)
8686
+ if (def.latexTrigger === tokens)
8687
+ result.push([def, n]);
8688
+ }
8689
+ for (const def of defs) {
8690
+ if (def.identifierTrigger) {
8691
+ const n = peekComplexId(this, def.identifierTrigger);
8692
+ if (n > 0)
8693
+ result.push([def, n]);
8365
8694
  }
8366
8695
  }
8367
- return result.length === 0 ? null : result;
8696
+ return result;
8368
8697
  }
8369
8698
  /** Skip strictly `<space>` tokens.
8370
8699
  * To also skip `{}` see `skipSpace()`.
@@ -8478,9 +8807,8 @@ var ComputeEngine = (() => {
8478
8807
  digits += digit;
8479
8808
  n += 1;
8480
8809
  }
8481
- if (digits.length === caretCount) {
8810
+ if (digits.length === caretCount)
8482
8811
  return String.fromCodePoint(Number.parseInt(digits, 16));
8483
- }
8484
8812
  } else if (this.match("\\char")) {
8485
8813
  let codepoint = Math.floor(this.matchLatexNumber() ?? Number.NaN);
8486
8814
  if (!Number.isFinite(codepoint) || codepoint < 0 || codepoint > 1114111) {
@@ -8489,17 +8817,15 @@ var ComputeEngine = (() => {
8489
8817
  return String.fromCodePoint(codepoint);
8490
8818
  } else if (this.match("\\unicode")) {
8491
8819
  this.skipSpaceTokens();
8492
- if (this.peek === "<{>") {
8493
- this.nextToken();
8820
+ if (this.match("<{>")) {
8494
8821
  const codepoint = this.matchLatexNumber();
8495
8822
  if (this.match("<}>") && codepoint !== null && codepoint >= 0 && codepoint <= 1114111) {
8496
8823
  return String.fromCodePoint(codepoint);
8497
8824
  }
8498
8825
  } else {
8499
8826
  const codepoint = this.matchLatexNumber();
8500
- if (codepoint !== null && codepoint >= 0 && codepoint <= 1114111) {
8827
+ if (codepoint !== null && codepoint >= 0 && codepoint <= 1114111)
8501
8828
  return String.fromCodePoint(codepoint);
8502
- }
8503
8829
  }
8504
8830
  }
8505
8831
  this.index = index;
@@ -8526,7 +8852,7 @@ var ComputeEngine = (() => {
8526
8852
  // Some LaTeX commands (but not all) can accept an argument without braces,
8527
8853
  // for example `^` , `\sqrt` or `\frac`.
8528
8854
  // This argument will usually be a single token, but can be a sequence of
8529
- // tokens (e.g. `\sqrt\frac12` or `\sqrt\mathrm{speed}`).
8855
+ // tokens (e.g. `\sqrt\frac12` or `\sqrt\operatorname{speed}`).
8530
8856
  parseToken() {
8531
8857
  const excluding = [
8532
8858
  ...'!"#$%&(),/;:?@[]\\`|~'.split(""),
@@ -8585,6 +8911,7 @@ var ComputeEngine = (() => {
8585
8911
  let peek = this.peek;
8586
8912
  while (peek !== "&" && peek !== "\\\\" && peek !== "\\cr" && !this.atBoundary) {
8587
8913
  expr = this.parseExpression({
8914
+ minPrec: 0,
8588
8915
  condition: (p) => {
8589
8916
  const peek2 = p.peek;
8590
8917
  return peek2 === "&" || peek2 === "\\\\" || peek2 === "\\cr";
@@ -8628,7 +8955,7 @@ var ComputeEngine = (() => {
8628
8955
  }
8629
8956
  /** Parse an environment: `\begin{env}...\end{end}`
8630
8957
  */
8631
- parseEnvironment() {
8958
+ parseEnvironment(until) {
8632
8959
  const index = this.index;
8633
8960
  if (!this.match("\\begin"))
8634
8961
  return null;
@@ -8636,22 +8963,22 @@ var ComputeEngine = (() => {
8636
8963
  if (!name)
8637
8964
  return this.error("expected-environment-name", index);
8638
8965
  this.addBoundary(["\\end", "<{>", ...name.split(""), "<}>"]);
8639
- const def = this._dictionary.environment.get(name);
8640
- if (!def) {
8641
- this.parseTabular();
8642
- this.skipSpace();
8643
- if (!this.matchBoundary())
8644
- return this.boundaryError("unbalanced-environment");
8645
- return this.error(["unknown-environment", { str: name }], index);
8646
- }
8647
- const expr = def.parse(this, [], []);
8966
+ for (const def of this.getDefs("environment"))
8967
+ if (def.identifierTrigger === name) {
8968
+ const expr = def.parse(this, until);
8969
+ this.skipSpace();
8970
+ if (!this.matchBoundary())
8971
+ return this.boundaryError("unbalanced-environment");
8972
+ if (expr !== null)
8973
+ return this.decorate(expr, index);
8974
+ this.index = index;
8975
+ return null;
8976
+ }
8977
+ this.parseTabular();
8648
8978
  this.skipSpace();
8649
8979
  if (!this.matchBoundary())
8650
8980
  return this.boundaryError("unbalanced-environment");
8651
- if (expr !== null)
8652
- return this.decorate(expr, index);
8653
- this.index = index;
8654
- return null;
8981
+ return this.error(["unknown-environment", { str: name }], index);
8655
8982
  }
8656
8983
  /** If the next token matches a `+` or `-` sign, return it and advance the index.
8657
8984
  * Otherwise return `''` and do not advance */
@@ -8895,11 +9222,8 @@ var ComputeEngine = (() => {
8895
9222
  until = { minPrec: 0 };
8896
9223
  if (!until.minPrec)
8897
9224
  until = { ...until, minPrec: 0 };
8898
- const defs = this.peekDefinitions("prefix");
8899
- if (defs === null)
8900
- return null;
8901
9225
  const start = this.index;
8902
- for (const [def, n] of defs) {
9226
+ for (const [def, n] of this.peekDefinitions("prefix")) {
8903
9227
  this.index = start + n;
8904
9228
  const rhs = def.parse(this, until);
8905
9229
  if (rhs)
@@ -8910,13 +9234,11 @@ var ComputeEngine = (() => {
8910
9234
  }
8911
9235
  parseInfixOperator(lhs, until) {
8912
9236
  until ?? (until = { minPrec: 0 });
9237
+ /* @__PURE__ */ console.assert(until.minPrec !== void 0);
8913
9238
  if (until.minPrec === void 0)
8914
9239
  until = { ...until, minPrec: 0 };
8915
- const defs = this.peekDefinitions("infix");
8916
- if (defs === null)
8917
- return null;
8918
9240
  const start = this.index;
8919
- for (const [def, n] of defs) {
9241
+ for (const [def, n] of this.peekDefinitions("infix")) {
8920
9242
  if (def.precedence >= until.minPrec) {
8921
9243
  this.index = start + n;
8922
9244
  const rhs = def.parse(this, lhs, until);
@@ -8958,44 +9280,6 @@ var ComputeEngine = (() => {
8958
9280
  this.index = savedIndex;
8959
9281
  return null;
8960
9282
  }
8961
- /** A prime suffix is a sequence of `'`, `\prime` or `\doubleprime`
8962
- * after a function or in a superscript.
8963
- */
8964
- // matchPrimeSuffix(): number {
8965
- // this.skipSpace();
8966
- // const start = this.index;
8967
- // let count = 0;
8968
- // if (this.match('^')) {
8969
- // if (this.match('<{>')) {
8970
- // if (this.match('(')) {
8971
- // const n = this.parseNumber();
8972
- // if (n && this.match(')')) return parseInt(n);
8973
- // this.index = start;
8974
- // return 0;
8975
- // }
8976
- // do {
8977
- // const c = countPrimeLevel(this);
8978
- // if (c === 0) break;
8979
- // count += c;
8980
- // } while (true);
8981
- // if (count !== 0 && this.match('<}>')) return count;
8982
- // this.index = start;
8983
- // return 0;
8984
- // }
8985
- // count = countPrimeLevel(this);
8986
- // if (count !== 0) return count;
8987
- // this.index = start;
8988
- // return 0;
8989
- // }
8990
- // do {
8991
- // const c = countPrimeLevel(this);
8992
- // if (c === 0) break;
8993
- // count += c;
8994
- // } while (true);
8995
- // if (count !== 0) return count;
8996
- // this.index = start;
8997
- // return 0;
8998
- // }
8999
9283
  /** If matches the normalized open delimiter, return the
9000
9284
  * expected closing delimiter.
9001
9285
  *
@@ -9051,9 +9335,7 @@ var ComputeEngine = (() => {
9051
9335
  * @internal
9052
9336
  */
9053
9337
  matchEnclosureOpen() {
9054
- const defs = this._dictionary.matchfix;
9055
- if (defs.length === 0)
9056
- return null;
9338
+ const defs = this.getDefs("matchfix");
9057
9339
  const start = this.index;
9058
9340
  for (const def of defs) {
9059
9341
  this.index = start;
@@ -9076,9 +9358,7 @@ var ComputeEngine = (() => {
9076
9358
  * Used for error handling
9077
9359
  * @internal */
9078
9360
  matchEnclosureClose() {
9079
- const defs = this._dictionary.matchfix;
9080
- if (defs.length === 0)
9081
- return null;
9361
+ const defs = this.getDefs("matchfix");
9082
9362
  const start = this.index;
9083
9363
  for (const def of defs) {
9084
9364
  this.index = start;
@@ -9117,9 +9397,7 @@ var ComputeEngine = (() => {
9117
9397
  * and finally a closing matching operator.
9118
9398
  */
9119
9399
  parseEnclosure() {
9120
- const defs = this._dictionary.matchfix;
9121
- if (defs.length === 0)
9122
- return null;
9400
+ const defs = this.getDefs("matchfix");
9123
9401
  const start = this.index;
9124
9402
  for (const def of defs) {
9125
9403
  this.index = start;
@@ -9206,8 +9484,7 @@ var ComputeEngine = (() => {
9206
9484
  return null;
9207
9485
  const start = this.index;
9208
9486
  let fn = null;
9209
- const fnDefs = this.peekDefinitions("function") ?? [];
9210
- for (const [def, tokenCount] of fnDefs) {
9487
+ for (const [def, tokenCount] of this.peekDefinitions("function")) {
9211
9488
  this.index = start + tokenCount;
9212
9489
  if (typeof def.parse === "function") {
9213
9490
  fn = def.parse(this, until);
@@ -9220,7 +9497,7 @@ var ComputeEngine = (() => {
9220
9497
  }
9221
9498
  if (fn === null) {
9222
9499
  this.index = start;
9223
- fn = matchIdentifier(this);
9500
+ fn = parseIdentifier(this);
9224
9501
  if (!this.isFunctionHead(fn)) {
9225
9502
  this.index = start;
9226
9503
  return null;
@@ -9239,20 +9516,17 @@ var ComputeEngine = (() => {
9239
9516
  if (this.atTerminator(until))
9240
9517
  return null;
9241
9518
  const start = this.index;
9242
- const defs = this.peekDefinitions("symbol");
9243
- if (defs) {
9244
- for (const [def, tokenCount] of defs) {
9245
- this.index = start + tokenCount;
9246
- if (typeof def.parse === "function") {
9247
- const result = def.parse(this, until);
9248
- if (result)
9249
- return result;
9250
- } else
9251
- return def.name;
9252
- }
9519
+ for (const [def, tokenCount] of this.peekDefinitions("symbol")) {
9520
+ this.index = start + tokenCount;
9521
+ if (typeof def.parse === "function") {
9522
+ const result = def.parse(this, until);
9523
+ if (result)
9524
+ return result;
9525
+ } else
9526
+ return def.name;
9253
9527
  }
9254
9528
  this.index = start;
9255
- const id = matchIdentifier(this);
9529
+ const id = parseIdentifier(this);
9256
9530
  if (id === null)
9257
9531
  return null;
9258
9532
  if (this.options.parseUnknownIdentifier?.(id, this) === "symbol")
@@ -9309,7 +9583,9 @@ var ComputeEngine = (() => {
9309
9583
  }
9310
9584
  let result = lhs;
9311
9585
  if (subscripts.length > 0) {
9312
- const defs = this._dictionary.infix[1]?.get("_");
9586
+ const defs = [...this.getDefs("infix")].filter(
9587
+ (x) => x.latexTrigger === "_"
9588
+ );
9313
9589
  if (defs) {
9314
9590
  const arg = [
9315
9591
  "Subscript",
@@ -9327,7 +9603,9 @@ var ComputeEngine = (() => {
9327
9603
  }
9328
9604
  }
9329
9605
  if (superscripts.length > 0) {
9330
- const defs = this._dictionary.infix[1]?.get("^");
9606
+ const defs = [...this.getDefs("infix")].filter(
9607
+ (x) => x.latexTrigger === "^"
9608
+ );
9331
9609
  if (defs) {
9332
9610
  const arg = [
9333
9611
  "Superscript",
@@ -9352,11 +9630,8 @@ var ComputeEngine = (() => {
9352
9630
  /* @__PURE__ */ console.assert(lhs !== null);
9353
9631
  if (lhs === null)
9354
9632
  return null;
9355
- const defs = this.peekDefinitions("postfix");
9356
- if (defs === null)
9357
- return null;
9358
9633
  const start = this.index;
9359
- for (const [def, n] of defs) {
9634
+ for (const [def, n] of this.peekDefinitions("postfix")) {
9360
9635
  this.index = start + n;
9361
9636
  const result = def.parse(this, lhs, until);
9362
9637
  if (result !== null)
@@ -9420,14 +9695,14 @@ var ComputeEngine = (() => {
9420
9695
  applyInvisibleOperator(until, lhs) {
9421
9696
  if (lhs === null || this.options.applyInvisibleOperator === null || head(lhs) === "Error" || symbol(lhs) === "Nothing" || isEmptySequence(lhs) || this.atTerminator(until))
9422
9697
  return null;
9698
+ if (this.peekDefinitions("operator").length > 0)
9699
+ return null;
9423
9700
  if (this.isFunctionHead(lhs)) {
9424
- const args = this.parseArguments("enclosure", until);
9701
+ const args = this.parseArguments("enclosure", { ...until, minPrec: 0 });
9425
9702
  if (args === null)
9426
9703
  return null;
9427
9704
  return [lhs, ...args];
9428
9705
  }
9429
- if (this.peekDefinitions("operator") !== null)
9430
- return null;
9431
9706
  const start = this.index;
9432
9707
  const rhs = this.parseExpression({ ...until, minPrec: 390 });
9433
9708
  if (rhs === null || symbol(rhs) === "Nothing" || isEmptySequence(rhs)) {
@@ -9474,9 +9749,9 @@ var ComputeEngine = (() => {
9474
9749
  parseUnexpectedLatexCommand() {
9475
9750
  const start = this.index;
9476
9751
  let opDefs = this.peekDefinitions("operator");
9477
- if (opDefs) {
9752
+ if (opDefs.length > 0) {
9478
9753
  opDefs = this.peekDefinitions("postfix");
9479
- if (opDefs) {
9754
+ if (opDefs.length > 0) {
9480
9755
  const [def, n] = opDefs[0];
9481
9756
  this.index += n;
9482
9757
  if (typeof def.parse === "function") {
@@ -9489,7 +9764,7 @@ var ComputeEngine = (() => {
9489
9764
  return this.error("unexpected-operator", start);
9490
9765
  }
9491
9766
  opDefs = this.peekDefinitions("prefix");
9492
- if (opDefs) {
9767
+ if (opDefs.length > 0) {
9493
9768
  const [def, n] = opDefs[0];
9494
9769
  this.index += n;
9495
9770
  if (typeof def.parse === "function") {
@@ -9500,12 +9775,13 @@ var ComputeEngine = (() => {
9500
9775
  if (def.name)
9501
9776
  return [
9502
9777
  def.name,
9778
+ // @todo: pass a precedence?
9503
9779
  this.parseExpression() ?? this.error("missing", start)
9504
9780
  ];
9505
9781
  return this.error("unexpected-operator", start);
9506
9782
  }
9507
9783
  opDefs = this.peekDefinitions("infix");
9508
- if (opDefs) {
9784
+ if (opDefs.length > 0) {
9509
9785
  const [def, n] = opDefs[0];
9510
9786
  this.index += n;
9511
9787
  if (typeof def.parse === "function") {
@@ -9599,7 +9875,10 @@ var ComputeEngine = (() => {
9599
9875
  if (this.match("<}>"))
9600
9876
  return this.error("unexpected-closing-delimiter", start);
9601
9877
  if (this.match("<{>")) {
9602
- result = this.parseExpression({ condition: (p) => p.peek === "<}>" });
9878
+ result = this.parseExpression({
9879
+ minPrec: 0,
9880
+ condition: (p) => p.peek === "<}>"
9881
+ });
9603
9882
  if (result === null)
9604
9883
  return this.error("expected-expression", start);
9605
9884
  if (!this.match("<}>")) {
@@ -9615,7 +9894,7 @@ var ComputeEngine = (() => {
9615
9894
  result = { num };
9616
9895
  }
9617
9896
  result ?? (result = this.parseEnclosure());
9618
- result ?? (result = this.parseEnvironment());
9897
+ result ?? (result = this.parseEnvironment(until));
9619
9898
  if (result === null && this.matchAll(this._positiveInfinityTokens))
9620
9899
  result = { num: "+Infinity" };
9621
9900
  if (result === null && this.matchAll(this._negativeInfinityTokens))
@@ -9660,8 +9939,9 @@ var ComputeEngine = (() => {
9660
9939
  return null;
9661
9940
  }
9662
9941
  until ?? (until = { minPrec: 0 });
9942
+ /* @__PURE__ */ console.assert(until.minPrec !== void 0);
9663
9943
  if (until.minPrec === void 0)
9664
- until.minPrec = 0;
9944
+ until = { ...until, minPrec: 0 };
9665
9945
  let lhs = this.parsePrefixOperator({ ...until, minPrec: 0 });
9666
9946
  if (lhs === null) {
9667
9947
  lhs = this.parsePrimary(until);
@@ -9730,7 +10010,28 @@ var ComputeEngine = (() => {
9730
10010
  return true;
9731
10011
  return false;
9732
10012
  }
10013
+ /** Return all defs of the specified kind */
10014
+ *getDefs(kind) {
10015
+ if (kind === "operator") {
10016
+ for (const def of this._dictionary.defs)
10017
+ if (/^prefix|infix|postfix/.test(def.kind))
10018
+ yield def;
10019
+ } else {
10020
+ for (const def of this._dictionary.defs)
10021
+ if (def.kind === kind)
10022
+ yield def;
10023
+ }
10024
+ }
9733
10025
  };
10026
+ function peekComplexId(parser, id) {
10027
+ const start = parser.index;
10028
+ const candidate = parseIdentifier(parser)?.trim();
10029
+ if (candidate === null)
10030
+ return 0;
10031
+ const result = candidate !== id ? 0 : parser.index - start;
10032
+ parser.index = start;
10033
+ return result;
10034
+ }
9734
10035
 
9735
10036
  // src/compute-engine/latex-syntax/serialize-number.ts
9736
10037
  function formatFractionalPart(m, options) {
@@ -9970,68 +10271,11 @@ var ComputeEngine = (() => {
9970
10271
  // Unicode uses 'double-struck' for 'blackboard'
9971
10272
  // Supplemental
9972
10273
  blackboard: (s) => `\\mathbb{${s}}`,
9973
- // boldItalic: (s) => `\\mathbf{\\mathit{${s}}}`,
9974
10274
  calligraphic: (s) => `\\mathcal{${s}}`,
9975
- // scriptBold: (s) => `\\mathbf{\\mathscr{${s}}}`,
9976
- // calligraphicBold: (s) => `\\mathbf{\\mathcal{${s}}}`,
9977
10275
  gothic: (s) => `\\mathfrak{${s}}`,
9978
- // gothicBold: (s) => `\\mathbf{\\mathfrak{${s}}}`,
9979
- // frakturBold: (s) => `\\mathbf{\\mathfrak{${s}}}`,
9980
- sansSerif: (s) => `\\mathsf{${s}}`,
9981
- // sansSerifBold: (s) => `\\mathbf{\\mathsf{${s}}}`,
9982
- // sansSerifItalic: (s) => `\\mathit{\\mathsf{${s}}}`,
10276
+ sansserif: (s) => `\\mathsf{${s}}`,
9983
10277
  monospace: (s) => `\\mathtt{${s}}`
9984
10278
  };
9985
- function serializeOperator(serializer, expr, def) {
9986
- let result = "";
9987
- const count = nops(expr);
9988
- const name = headName(expr);
9989
- if (def.kind === "postfix") {
9990
- if (count !== 1) {
9991
- serializer.onError([
9992
- {
9993
- severity: "warning",
9994
- message: [
9995
- "postfix-operator-requires-one-operand",
9996
- serializer.serializeSymbol(name)
9997
- ]
9998
- }
9999
- ]);
10000
- }
10001
- return replaceLatex(def.serialize, [
10002
- serializer.wrap(op(expr, 1), def.precedence)
10003
- ]);
10004
- }
10005
- if (def.kind === "prefix") {
10006
- if (count !== 1) {
10007
- serializer.onError([
10008
- {
10009
- severity: "warning",
10010
- message: [
10011
- "prefix-operator-requires-one-operand",
10012
- serializer.serializeSymbol(name)
10013
- ]
10014
- }
10015
- ]);
10016
- }
10017
- return replaceLatex(def.serialize, [
10018
- serializer.wrap(op(expr, 1), def.precedence + 1)
10019
- ]);
10020
- }
10021
- if (def.kind === "infix") {
10022
- result = serializer.wrap(op(expr, 1), def.precedence);
10023
- for (let i = 2; i < count + 1; i++) {
10024
- const arg = op(expr, i);
10025
- if (arg !== null) {
10026
- result = replaceLatex(def.serialize, [
10027
- result,
10028
- serializer.wrap(arg, def.precedence)
10029
- ]);
10030
- }
10031
- }
10032
- }
10033
- return result;
10034
- }
10035
10279
  var Serializer = class {
10036
10280
  constructor(options, dictionary2, onError) {
10037
10281
  this.level = -1;
@@ -10073,7 +10317,7 @@ var ComputeEngine = (() => {
10073
10317
  }
10074
10318
  const name = head(expr);
10075
10319
  if (typeof name === "string" && name !== "Delimiter" && name !== "Subscript") {
10076
- const def = this.dictionary.name.get(name);
10320
+ const def = this.dictionary.ids.get(name);
10077
10321
  if (def && (def.kind === "symbol" || def.kind === "prefix" || def.kind === "infix" || def.kind === "postfix") && def.precedence < prec)
10078
10322
  return this.wrapString(
10079
10323
  this.serialize(expr),
@@ -10111,14 +10355,16 @@ var ComputeEngine = (() => {
10111
10355
  wrapString(s, style, fence) {
10112
10356
  if (style === "none")
10113
10357
  return s;
10114
- const openFence = fence?.[0] ?? "(";
10115
- const closeFence = fence?.[1] ?? ")";
10358
+ if (fence === void 0)
10359
+ fence = "()";
10360
+ const openFence = fence?.[0] ?? ".";
10361
+ const closeFence = fence?.[1] ?? ".";
10116
10362
  if ((openFence === "." || closeFence === ".") && style === "paren")
10117
10363
  style = "leftright";
10118
10364
  if (style === "leftright")
10119
- return `${openFence === "." ? "" : `\\left(${openFence}`}${s}${closeFence === "." ? "" : `\\right(${closeFence}`})`;
10365
+ return `\\left${openFence}${s}\\right${closeFence}}`;
10120
10366
  if (style === "big")
10121
- return `${openFence === "." ? "" : `\\Bigl(${openFence}`}${s}${closeFence === "." ? "" : `\\Bigr(${closeFence}`})`;
10367
+ return `${openFence === "." ? "" : `\\Bigl${openFence}`}${s}${closeFence === "." ? "" : `\\Bigr${closeFence}`})`;
10122
10368
  return openFence + s + closeFence;
10123
10369
  }
10124
10370
  wrapArguments(expr) {
@@ -10128,42 +10374,37 @@ var ComputeEngine = (() => {
10128
10374
  );
10129
10375
  }
10130
10376
  serializeSymbol(expr, def) {
10131
- const h = head(expr);
10132
- if (h)
10133
- return this.serializeFunction(expr, def);
10134
10377
  /* @__PURE__ */ console.assert(typeof expr === "string" || isSymbolObject(expr));
10135
- if (typeof def?.serialize === "string")
10136
- return def.serialize;
10137
- else if (typeof def?.serialize === "function")
10138
- return def.serialize(this, expr);
10139
- return serializeIdentifier(symbol(expr)) ?? "";
10378
+ if (def?.kind === "function") {
10379
+ return serializeIdentifier(symbol(expr) ?? "") ?? "";
10380
+ }
10381
+ return def?.serialize?.(this, expr) ?? serializeIdentifier(symbol(expr)) ?? "";
10140
10382
  }
10141
10383
  serializeFunction(expr, def) {
10384
+ if (def?.serialize)
10385
+ return def.serialize(this, expr);
10142
10386
  const h = head(expr);
10143
- if (!h)
10144
- return this.serializeSymbol(expr, def);
10387
+ if (typeof h === "string")
10388
+ return serializeIdentifier(h, "auto") + this.wrapArguments(expr);
10145
10389
  const args = ops(expr) ?? [];
10146
- if (def) {
10147
- if (typeof def.serialize === "function")
10148
- return def.serialize(this, expr);
10390
+ if (args.length === 1) {
10149
10391
  return joinLatex([
10150
- def.serialize ?? h,
10151
- this.wrapArguments(expr)
10392
+ this.serialize(args[0]),
10393
+ "\\rhd",
10394
+ this.wrapString(
10395
+ this.serialize(h),
10396
+ this.options.applyFunctionStyle(expr, this.level)
10397
+ )
10152
10398
  ]);
10153
10399
  }
10154
- if (typeof h === "string" && h.length > 0 && h[0] === "\\") {
10155
- return joinLatex([h, ...args.map((x) => `{${this.serialize(x)}}`)]);
10156
- }
10157
- if (typeof h === "string") {
10158
- if (h.length === 1)
10159
- return serializeIdentifier(h) + this.wrapArguments(expr);
10160
- return serializeIdentifier(h, "upright") + this.wrapArguments(expr);
10161
- }
10162
10400
  const style = this.options.applyFunctionStyle(expr, this.level);
10163
- return "\\mathrm{Apply}" + this.wrapString(
10164
- this.serialize(h) + ", " + this.serialize(["List", ...args]),
10165
- style
10166
- );
10401
+ return joinLatex([
10402
+ "\\operatorname{apply}",
10403
+ this.wrapString(
10404
+ this.serialize(h) + ", " + this.serialize(["List", ...args]),
10405
+ style
10406
+ )
10407
+ ]);
10167
10408
  }
10168
10409
  serializeDictionary(dict) {
10169
10410
  return `\\left\\lbrack\\begin{array}{lll}${Object.keys(dict).map((x) => {
@@ -10182,37 +10423,22 @@ var ComputeEngine = (() => {
10182
10423
  const s = stringValue(expr);
10183
10424
  if (s !== null)
10184
10425
  return `\\text{${s}}`;
10185
- const symbolName = symbol(expr);
10186
- if (symbolName !== null) {
10187
- const def = this.dictionary.name.get(symbolName);
10188
- if (def?.kind === "symbol")
10189
- return this.serializeSymbol(expr, def);
10190
- if (def?.kind === "function")
10191
- return this.serializeFunction(expr, def);
10192
- if (typeof def?.serialize === "function")
10193
- return def.serialize(this, expr);
10194
- }
10195
10426
  const dict = dictionary(expr);
10196
10427
  if (dict !== null)
10197
10428
  return this.serializeDictionary(dict);
10429
+ const symbolName = symbol(expr);
10430
+ if (symbolName !== null) {
10431
+ return this.serializeSymbol(
10432
+ expr,
10433
+ this.dictionary.ids.get(symbolName)
10434
+ );
10435
+ }
10198
10436
  const fnName = headName(expr);
10199
10437
  if (fnName) {
10200
- const def = this.dictionary.name.get(fnName);
10201
- if (def) {
10202
- if (typeof def.serialize === "function")
10203
- return def.serialize(this, expr);
10204
- if (def.kind === "infix" || def.kind === "postfix" || def.kind === "prefix")
10205
- return serializeOperator(this, expr, def);
10206
- if (def.kind === "symbol")
10207
- return this.serializeSymbol(expr, def);
10208
- if (def.kind === "function")
10209
- return this.serializeFunction(expr, def);
10210
- return "";
10211
- }
10212
- }
10213
- if (symbolName !== null || Array.isArray(expr) || isFunctionObject(expr)) {
10214
- return this.serializeSymbol(expr);
10438
+ return this.serializeFunction(expr, this.dictionary.ids.get(fnName));
10215
10439
  }
10440
+ if (head(expr) !== null)
10441
+ return this.serializeFunction(expr);
10216
10442
  this.onError([
10217
10443
  {
10218
10444
  severity: "warning",
@@ -10252,22 +10478,6 @@ var ComputeEngine = (() => {
10252
10478
  return this.options.numericSetStyle(expr, level);
10253
10479
  }
10254
10480
  };
10255
- function replaceLatex(template, replacement) {
10256
- /* @__PURE__ */ console.assert(typeof template === "string");
10257
- /* @__PURE__ */ console.assert(template.length > 0);
10258
- let result = template;
10259
- for (let i = 0; i < replacement.length; i++) {
10260
- let s = replacement[i] ?? "";
10261
- if (/[a-zA-Z*]/.test(s[0])) {
10262
- const m = result.match(new RegExp("(.*)#" + Number(i + 1).toString()));
10263
- if (m && /\\[a-zA-Z*]+/.test(m[1])) {
10264
- s = " " + s;
10265
- }
10266
- }
10267
- result = result.replace("#" + Number(i + 1).toString(), s);
10268
- }
10269
- return result;
10270
- }
10271
10481
  function specialName(s) {
10272
10482
  const prefix = s.match(/^([^_]+)/)?.[1] ?? "";
10273
10483
  let i = SYMBOLS.findIndex((x) => prefix === x[0]);
@@ -10343,7 +10553,7 @@ var ComputeEngine = (() => {
10343
10553
  }
10344
10554
  return [body, accent, styles, rest];
10345
10555
  }
10346
- function parseIdentifierBody(s, topLevel = true, style = "auto") {
10556
+ function parseIdentifierBody2(s, topLevel = true, style = "auto") {
10347
10557
  let [body, accents, styles, rest] = parseModifiers(s);
10348
10558
  for (const accent of accents) {
10349
10559
  if (ACCENT_MODIFIERS[accent])
@@ -10359,7 +10569,7 @@ var ComputeEngine = (() => {
10359
10569
  }
10360
10570
  while (rest.length > 0) {
10361
10571
  if (rest.startsWith("__")) {
10362
- const [sup, rest2] = parseIdentifierBody(
10572
+ const [sup, rest2] = parseIdentifierBody2(
10363
10573
  rest.substring(2),
10364
10574
  false,
10365
10575
  "none"
@@ -10367,7 +10577,7 @@ var ComputeEngine = (() => {
10367
10577
  sups.push(sup);
10368
10578
  rest = rest2;
10369
10579
  } else if (rest.startsWith("_")) {
10370
- const [sub2, rest2] = parseIdentifierBody(
10580
+ const [sub2, rest2] = parseIdentifierBody2(
10371
10581
  rest.substring(1),
10372
10582
  false,
10373
10583
  "none"
@@ -10406,19 +10616,19 @@ var ComputeEngine = (() => {
10406
10616
  }
10407
10617
  return [body, rest];
10408
10618
  }
10409
- function serializeIdentifier(s, defaultMulticharStyle = "auto") {
10619
+ function serializeIdentifier(s, style = "auto") {
10410
10620
  if (s === null)
10411
10621
  return null;
10412
10622
  if (ONLY_EMOJIS.test(s))
10413
10623
  return s;
10414
10624
  const m = s.match(/^(_+)(.*)/);
10415
10625
  if (m) {
10416
- const [body2, rest2] = parseIdentifierBody(m[2], true, "none");
10417
- return `\\mathrm{${"\\_".repeat(m[1].length) + body2 + rest2}}`;
10626
+ const [body2, rest2] = parseIdentifierBody2(m[2], true, "none");
10627
+ return `\\operatorname{${"\\_".repeat(m[1].length) + body2 + rest2}}`;
10418
10628
  }
10419
- const [body, rest] = parseIdentifierBody(s, true, defaultMulticharStyle);
10629
+ const [body, rest] = parseIdentifierBody2(s, true, style);
10420
10630
  if (rest.length > 0)
10421
- return `\\mathrm{${s}}`;
10631
+ return `\\operatorname{${s}}`;
10422
10632
  return body;
10423
10633
  }
10424
10634
 
@@ -10508,7 +10718,7 @@ var ComputeEngine = (() => {
10508
10718
  let expr = parser.parseExpression();
10509
10719
  if (!parser.atEnd) {
10510
10720
  const opDefs = parser.peekDefinitions("infix");
10511
- if (opDefs) {
10721
+ if (opDefs.length > 0) {
10512
10722
  const start = parser.index;
10513
10723
  const [def, n] = opDefs[0];
10514
10724
  parser.index += n;
@@ -10529,20 +10739,23 @@ var ComputeEngine = (() => {
10529
10739
  parser.index = start;
10530
10740
  }
10531
10741
  const index = parser.index;
10532
- const id = matchIdentifier(parser);
10742
+ const id = parseIdentifier(parser);
10533
10743
  if (id) {
10534
10744
  const idError = parser.error(["unexpected-identifier", id], index);
10535
10745
  return expr ? ["Sequence", expr, idError] : idError;
10536
10746
  }
10747
+ let openDelimiter = parser.peek;
10537
10748
  const closeDelimiter = parser.matchEnclosureOpen();
10538
10749
  if (closeDelimiter) {
10750
+ parser.parseExpression();
10751
+ parser.match(closeDelimiter);
10539
10752
  const enclosureError = parser.error(
10540
- ["expected-close-delimiter", { str: closeDelimiter }],
10753
+ ["unexpected-open-delimiter", { str: openDelimiter }],
10541
10754
  index
10542
10755
  );
10543
10756
  return expr ? ["Sequence", expr, enclosureError] : enclosureError;
10544
10757
  }
10545
- const openDelimiter = parser.matchEnclosureClose();
10758
+ openDelimiter = parser.matchEnclosureClose();
10546
10759
  if (openDelimiter) {
10547
10760
  const enclosureError = parser.error(
10548
10761
  ["expected-open-delimiter", { str: openDelimiter }],
@@ -11690,6 +11903,9 @@ var ComputeEngine = (() => {
11690
11903
  [a, b] = [b, a % b];
11691
11904
  return a < 0 ? -a : a;
11692
11905
  }
11906
+ function lcm(a, b) {
11907
+ return a * b / gcd(a, b);
11908
+ }
11693
11909
  function factorial(n) {
11694
11910
  if (!Number.isInteger(n) || n < 0)
11695
11911
  return NaN;
@@ -13170,6 +13386,362 @@ var ComputeEngine = (() => {
13170
13386
 
13171
13387
  // src/compute-engine/boxed-expression/abstract-boxed-expression.ts
13172
13388
  var import_complex6 = __toESM(require_complex());
13389
+
13390
+ // src/compute-engine/library/utils.ts
13391
+ function isSymbolDefinition(def) {
13392
+ return !!def && typeof def === "object" && ("domain" in def || "value" in def || "constant" in def);
13393
+ }
13394
+ function isFunctionDefinition(def) {
13395
+ if (def === void 0 || def === null)
13396
+ return false;
13397
+ if (typeof def !== "object")
13398
+ return false;
13399
+ if ("complexity" in def || "numeric" in def || "signature" in def)
13400
+ return true;
13401
+ if (!("domain" in def))
13402
+ return false;
13403
+ if (def.domain === void 0)
13404
+ return false;
13405
+ if (typeof def.domain === "string")
13406
+ return def.domain === "Function";
13407
+ return def.domain.isFunction;
13408
+ }
13409
+ function normalizeLimits(range) {
13410
+ let lower = 1;
13411
+ let upper = lower + MAX_ITERATION;
13412
+ let index = "Nothing";
13413
+ let isFinite2 = true;
13414
+ if (range.head === "Tuple" || range.head === "Triple" || range.head === "Pair" || range.head === "Single") {
13415
+ index = (range.op1.head === "Hold" ? range.op1.op1.symbol : range.op1.symbol) ?? "Nothing";
13416
+ lower = asSmallInteger(range.op2) ?? 1;
13417
+ if (!Number.isFinite(lower))
13418
+ isFinite2 = false;
13419
+ if (range.op3.isNothing || range.op3.isInfinity) {
13420
+ isFinite2 = false;
13421
+ } else {
13422
+ const u = asSmallInteger(range.op3);
13423
+ if (u === null)
13424
+ isFinite2 = false;
13425
+ else {
13426
+ upper = u;
13427
+ if (!Number.isFinite(upper))
13428
+ isFinite2 = false;
13429
+ }
13430
+ }
13431
+ if (!isFinite2 && Number.isFinite(lower))
13432
+ upper = lower + MAX_ITERATION;
13433
+ }
13434
+ return [index, lower, upper, isFinite2];
13435
+ }
13436
+
13437
+ // src/compute-engine/compile.ts
13438
+ var ComputeEngineFunction = class extends Function {
13439
+ constructor(body) {
13440
+ super("_SYS", "_", `return ${body}`);
13441
+ this.sys = {
13442
+ factorial,
13443
+ gamma,
13444
+ lngamma,
13445
+ gcd,
13446
+ lcm,
13447
+ chop
13448
+ };
13449
+ return new Proxy(this, {
13450
+ apply: (target, thisArg, argumentsList) => super.apply(thisArg, [this.sys, ...argumentsList]),
13451
+ get: (target, prop) => {
13452
+ if (prop === "toString")
13453
+ return () => body;
13454
+ return target[prop];
13455
+ }
13456
+ });
13457
+ }
13458
+ };
13459
+ function compileToJavascript(expr) {
13460
+ const js = compile(expr, expr.freeVars);
13461
+ try {
13462
+ return new ComputeEngineFunction(js);
13463
+ } catch (e) {
13464
+ console.error(`${e}
13465
+ ${expr.latex}
13466
+ ${js}`);
13467
+ }
13468
+ return void 0;
13469
+ }
13470
+ function compile(expr, freeVars = [], prec = 0) {
13471
+ const f = asFloat(expr);
13472
+ if (f !== null)
13473
+ return f.toString();
13474
+ const s = expr.symbol;
13475
+ if (s !== null) {
13476
+ const result = {
13477
+ True: "true",
13478
+ False: "false",
13479
+ Pi: "Math.PI",
13480
+ ExponentialE: "Math.E",
13481
+ I: "Math.I",
13482
+ NaN: "Number.NaN",
13483
+ ImaginaryUnit: "NaN",
13484
+ Half: "0.5",
13485
+ MachineEpsilon: "Number.EPSILON",
13486
+ GoldenRatio: "((1 + Math.sqrt(5)) / 2)",
13487
+ CatalanConstant: "0.91596559417721901",
13488
+ EulerGamma: "0.57721566490153286"
13489
+ }[s];
13490
+ if (result !== void 0)
13491
+ return result;
13492
+ if (freeVars.includes(s))
13493
+ return `_.${s}`;
13494
+ return s;
13495
+ }
13496
+ const str = expr.string;
13497
+ if (str !== null)
13498
+ return JSON.stringify(str);
13499
+ const keys = expr.keys;
13500
+ if (keys !== null) {
13501
+ const result = [];
13502
+ for (const key of keys) {
13503
+ const value = expr.getKey(key);
13504
+ if (value)
13505
+ result.push(`${key}: ${compile(value, freeVars, 0)}`);
13506
+ }
13507
+ return `{${result.join(", ")}}`;
13508
+ }
13509
+ const h = expr.head;
13510
+ if (typeof h === "string") {
13511
+ if (h === "Negate") {
13512
+ const arg = expr.op1;
13513
+ if (arg === null)
13514
+ return "";
13515
+ return `-${compile(arg, freeVars, 3)}`;
13516
+ }
13517
+ if (h === "Error")
13518
+ throw new Error("Error");
13519
+ if (h === "Sum")
13520
+ return compileLoop(expr, "+");
13521
+ if (h === "Product")
13522
+ return compileLoop(expr, "*");
13523
+ if (h === "Root") {
13524
+ const arg = expr.op1;
13525
+ if (arg === null)
13526
+ throw new Error("Root: no argument");
13527
+ const exp2 = expr.op2;
13528
+ if (exp2 === null)
13529
+ return `Math.sqrt(${compile(arg, freeVars, 0)})`;
13530
+ return `Math.pow(${compile(arg, freeVars)}, 1/${compile(exp2, freeVars)}`;
13531
+ }
13532
+ if (h === "Factorial") {
13533
+ const arg = expr.op1;
13534
+ if (arg === null)
13535
+ throw new Error("Factorial: no argument");
13536
+ return `_SYS.factorial(${compile(arg, freeVars)})`;
13537
+ }
13538
+ if (h === "Power") {
13539
+ const arg = expr.op1;
13540
+ if (arg === null)
13541
+ throw new Error("Power: no argument");
13542
+ const exp2 = asFloat(expr.op2);
13543
+ if (exp2 === 0.5)
13544
+ return `Math.sqrt(${compile(arg, freeVars)})`;
13545
+ if (exp2 === 1 / 3)
13546
+ return `Math.cbrt(${compile(arg, freeVars)})`;
13547
+ if (exp2 === 1)
13548
+ return compile(arg, freeVars);
13549
+ if (exp2 === -1)
13550
+ return `1 / ${compile(arg, freeVars)}`;
13551
+ if (exp2 === -0.5)
13552
+ return `1 / Math.sqrt(${compile(arg, freeVars)})`;
13553
+ }
13554
+ if (h === "Square") {
13555
+ const arg = expr.op1;
13556
+ if (arg === null)
13557
+ throw new Error("Square: no argument");
13558
+ return `Math.pow(${compile(arg, freeVars)}, 2)`;
13559
+ }
13560
+ const OPS = {
13561
+ Add: ["+", 11],
13562
+ Negate: ["-", 14],
13563
+ // Unary operator
13564
+ Subtract: ["-", 11],
13565
+ Multiply: ["*", 12],
13566
+ Divide: ["/", 13],
13567
+ Equal: ["===", 8],
13568
+ NotEqual: ["!==", 8],
13569
+ LessEqual: ["<=", 9],
13570
+ GreaterEqual: [">=", 9],
13571
+ Less: ["<", 9],
13572
+ Greater: [">", 9],
13573
+ And: ["&&", 4],
13574
+ Or: ["||", 3],
13575
+ Not: ["!", 14]
13576
+ // Unary operator
13577
+ // Xor: ['^', 6], // That's bitwise XOR, not logical XOR
13578
+ // Possible solution is to use `a ? !b : b` instead of `a ^ b`
13579
+ };
13580
+ const op3 = OPS[h];
13581
+ if (op3 !== void 0) {
13582
+ const args2 = expr.ops;
13583
+ if (args2 === null)
13584
+ return "";
13585
+ let resultStr;
13586
+ if (args2.length === 1) {
13587
+ resultStr = `${op3[0]}${compile(args2[0], freeVars, op3[1])}`;
13588
+ } else {
13589
+ resultStr = args2.map((arg) => compile(arg, freeVars, op3[1])).join(` ${op3[0]} `);
13590
+ }
13591
+ return op3[1] < prec ? `(${resultStr})` : resultStr;
13592
+ }
13593
+ const fn = {
13594
+ Abs: "Math.abs",
13595
+ Arccos: "Math.acos",
13596
+ Arcosh: "Math.acosh",
13597
+ Arsin: "Math.asin",
13598
+ Arsinh: "Math.asinh",
13599
+ Arctan: "Math.atan",
13600
+ Artanh: "Math.atanh",
13601
+ // Math.cbrt
13602
+ Ceiling: "Math.ceil",
13603
+ Chop: "_SYS.chop",
13604
+ Cos: "Math.cos",
13605
+ Cosh: "Math.cosh",
13606
+ Exp: "Math.exp",
13607
+ Floor: "Math.floor",
13608
+ Gamma: "_SYS.gamma",
13609
+ Gcd: "_SYS.gcd",
13610
+ // Math.hypot
13611
+ Lcm: "_SYS.lcm",
13612
+ Ln: "Math.log",
13613
+ Log: "Math.log10",
13614
+ LogGamma: "_SYS.lngamma",
13615
+ Lb: "Math.log2",
13616
+ Max: "Math.max",
13617
+ Min: "Math.min",
13618
+ Power: "Math.pow",
13619
+ Random: "Math.random",
13620
+ Round: "Math.round",
13621
+ Sgn: "Math.sign",
13622
+ Sin: "Math.sin",
13623
+ Sinh: "Math.sinh",
13624
+ Sqrt: "Math.sqrt",
13625
+ Tan: "Math.tan",
13626
+ Tanh: "Math.tanh"
13627
+ // Factorial: 'factorial', // TODO: implement
13628
+ // Hallucinated by Copilot, but interesting ideas...
13629
+ // Cot: 'Math.cot',
13630
+ // Sec: 'Math.sec',
13631
+ // Csc: 'Math.csc',
13632
+ // ArcCot: 'Math.acot',
13633
+ // ArcSec: 'Math.asec',
13634
+ // ArcCsc: 'Math.acsc',
13635
+ // Coth: 'Math.coth',
13636
+ // Sech: 'Math.sech',
13637
+ // Csch: 'Math.csch',
13638
+ // ArcCoth: 'Math.acoth',
13639
+ // ArcSech: 'Math.asech',
13640
+ // ArcCsch: 'Math.acsch',
13641
+ // Root: 'Math.root',
13642
+ // Gamma: 'Math.gamma',
13643
+ // Erf: 'Math.erf',
13644
+ // Erfc: 'Math.erfc',
13645
+ // Erfi: 'Math.erfi',
13646
+ // Zeta: 'Math.zeta',
13647
+ // PolyGamma: 'Math.polygamma',
13648
+ // HurwitzZeta: 'Math.hurwitzZeta', $$\zeta (s,a)=\sum _{n=0}^{\infty }{\frac {1}{(n+a)^{s}}}$$
13649
+ // DirichletEta: 'Math.dirichletEta',
13650
+ // Beta: 'Math.beta',
13651
+ // Binomial: 'Math.binomial',
13652
+ // Mod: 'Math.mod',
13653
+ // Quotient: 'Math.quotient',
13654
+ // GCD: 'Math.gcd',
13655
+ // LCM: 'Math.lcm',
13656
+ // Divisors: 'Math.divisors',
13657
+ // PrimeQ: 'Math.isPrime',
13658
+ // PrimePi: 'Math.primePi',
13659
+ // Prime: 'Math.prime',
13660
+ // NextPrime: 'Math.nextPrime',
13661
+ // PreviousPrime: 'Math.prevPrime',
13662
+ // PrimePowerQ: 'Math.isPrimePower',
13663
+ // PrimePowerPi: 'Math.primePowerPi',
13664
+ // PrimePower: 'Math.primePower',
13665
+ // NextPrimePower: 'Math.nextPrimePower',
13666
+ // PreviousPrimePower: 'Math.prevPrimePower',
13667
+ // PrimeFactors: 'Math.primeFactors',
13668
+ // DivisorSigma: 'Math.divisorSigma',
13669
+ // DivisorSigma0: 'Math.divisorSigma0',
13670
+ // DivisorSigma1: 'Math.divisorSigma1',
13671
+ // DivisorSigma2: 'Math.divisorSigma2',
13672
+ // DivisorSigma3: 'Math.divisorSigma3',
13673
+ // DivisorSigma4: 'Math.divisorSigma4',
13674
+ // DivisorCount: 'Math.divisorCount',
13675
+ // DivisorSum: 'Math.divisorSum',
13676
+ // MoebiusMu: 'Math.moebiusMu',
13677
+ // LiouvilleLambda: 'Math.liouvilleLambda',
13678
+ // CarmichaelLambda: 'Math.carmichaelLambda',
13679
+ // EulerPhi: 'Math.eulerPhi',
13680
+ // EulerPsi: 'Math.eulerPsi',
13681
+ // EulerGamma: 'Math.eulerGamma',
13682
+ // HarmonicNumber: 'Math.harmonicNumber',
13683
+ // BernoulliB: 'Math.bernoulliB',
13684
+ // StirlingS1: 'Math.stirlingS1',
13685
+ // StirlingS2: 'Math.stirlingS2',
13686
+ // BellB: 'Math.bellB',
13687
+ // BellNumber: 'Math.bellNumber',
13688
+ // LahS: 'Math.lahS',
13689
+ // LahL: 'Math.lahL',
13690
+ // RiemannR: 'Math.riemannR',
13691
+ // RiemannZeta: 'Math.riemannZeta',
13692
+ // RiemannXi: 'Math.riemannXi',
13693
+ // RiemannH: 'Math.riemannH',
13694
+ // RiemannZ: 'Math.riemannZ',
13695
+ // RiemannS: 'Math.riemannS',
13696
+ // RiemannXiZero: 'Math.riemannXiZero',
13697
+ // RiemannZetaZero: 'Math.riemannZetaZero',
13698
+ // RiemannHZero: 'Math.riemannHZero',
13699
+ // RiemannSZero: 'Math.riemannSZero',
13700
+ // RiemannPrimeCount: 'Math.riemannPrimeCount',
13701
+ // RiemannRLog: 'Math.riemannRLog',
13702
+ // RiemannRLogDerivative: 'Math.riemannRLogDerivative',
13703
+ // RiemannRLogZero: 'Math.riemannRLogZero',
13704
+ // RiemannRLogZeroDerivative: 'Math.riemannRLogZeroDerivative',
13705
+ // RiemannRZero: 'Math.riemannRZero',
13706
+ // RiemannRDerivative: 'Math.riemannRDerivative',
13707
+ // RiemannXiZeroDerivative: 'Math.riemannXiZeroDerivative',
13708
+ // RiemannZetaZeroDerivative: 'Math.riemannZetaZeroDerivative',
13709
+ // RiemannHZeroDerivative: 'Math.riemannHZeroDerivative',
13710
+ // RiemannSZeroDerivative: 'Math.riemannSZeroDerivative',
13711
+ // RiemannSZeroDerivative2: 'Math.riemannSZeroDerivative2',
13712
+ // RiemannSZeroDerivative3: 'Math.riemannSZeroDerivative3',
13713
+ // RiemannSZeroDerivative4: 'Math.riemannSZeroDerivative4',
13714
+ // RiemannSZeroDerivative5: 'Math.riemannSZeroDerivative5',
13715
+ // RiemannSZeroDerivative6: 'Math.riemannSZeroDerivative6',
13716
+ }[h] ?? h;
13717
+ const args = expr.ops;
13718
+ if (args !== null) {
13719
+ const result = [];
13720
+ for (const arg of args)
13721
+ result.push(compile(arg, freeVars));
13722
+ return `${fn}(${result.join(", ")})`;
13723
+ }
13724
+ }
13725
+ return "";
13726
+ }
13727
+ function compileLoop(expr, op3) {
13728
+ const args = expr.ops;
13729
+ if (args === null)
13730
+ throw new Error("Sum: no arguments");
13731
+ if (!expr.op1 || !expr.op2)
13732
+ throw new Error("Sum: no limits");
13733
+ const [index, lower, upper, isFinite2] = normalizeLimits(expr.op2);
13734
+ const fn = compile(expr.op1, [...expr.op1.freeVars, index], 0);
13735
+ return `(() => {
13736
+ let acc = ${op3 === "+" ? "0" : "1"};
13737
+ const fn = (_) => ${fn};
13738
+ for (let i = ${lower}; i <= ${upper}; i++)
13739
+ acc ${op3}= fn({ ..._, ${index}: i });
13740
+ return acc;
13741
+ })()`;
13742
+ }
13743
+
13744
+ // src/compute-engine/boxed-expression/abstract-boxed-expression.ts
13173
13745
  var AbstractBoxedExpression = class {
13174
13746
  constructor(ce, metadata) {
13175
13747
  this.engine = ce;
@@ -13494,6 +14066,21 @@ var ComputeEngine = (() => {
13494
14066
  N(_options) {
13495
14067
  return this.evaluate();
13496
14068
  }
14069
+ compile(to = "javascript", options) {
14070
+ if (to !== "javascript")
14071
+ return void 0;
14072
+ options ?? (options = { optimize: ["simplify", "evaluate"] });
14073
+ let expr = this;
14074
+ if (options.optimize.includes("simplify"))
14075
+ expr = expr.simplify();
14076
+ if (options.optimize.includes("evaluate"))
14077
+ expr = expr.evaluate();
14078
+ try {
14079
+ return compileToJavascript(expr);
14080
+ } catch (e) {
14081
+ }
14082
+ return void 0;
14083
+ }
13497
14084
  };
13498
14085
 
13499
14086
  // src/compute-engine/boxed-expression/serialize.ts
@@ -14956,7 +15543,7 @@ var ComputeEngine = (() => {
14956
15543
  }
14957
15544
  }
14958
15545
  return xs.map(
14959
- (op3) => !op3.isValid || op3.isNumber ? op3 : ce.error(["incompatible-domain", "Number", op3.domain], op3)
15546
+ (op3) => op3 && !op3.isValid || op3.isNumber ? op3 : ce.error(["incompatible-domain", "Number", op3.domain], op3)
14960
15547
  );
14961
15548
  }
14962
15549
  function validateSignature(sig, ops2, codomain) {
@@ -15325,33 +15912,6 @@ var ComputeEngine = (() => {
15325
15912
  ce.context = savedContext;
15326
15913
  return result ?? void 0;
15327
15914
  }
15328
- function normalizeLimits(range) {
15329
- let lower = 1;
15330
- let upper = lower + MAX_ITERATION;
15331
- let index = "Nothing";
15332
- let isFinite2 = true;
15333
- if (range.head === "Tuple" || range.head === "Triple" || range.head === "Pair" || range.head === "Single") {
15334
- index = (range.op1.head === "Hold" ? range.op1.op1.symbol : range.op1.symbol) ?? "Nothing";
15335
- lower = asSmallInteger(range.op2) ?? 1;
15336
- if (!Number.isFinite(lower))
15337
- isFinite2 = false;
15338
- if (range.op3.isNothing || range.op3.isInfinity) {
15339
- isFinite2 = false;
15340
- } else {
15341
- const u = asSmallInteger(range.op3);
15342
- if (u === null)
15343
- isFinite2 = false;
15344
- else {
15345
- upper = u;
15346
- if (!Number.isFinite(upper))
15347
- isFinite2 = false;
15348
- }
15349
- }
15350
- if (!isFinite2 && Number.isFinite(lower))
15351
- upper = lower + MAX_ITERATION;
15352
- }
15353
- return [index, lower, upper, isFinite2];
15354
- }
15355
15915
 
15356
15916
  // src/compute-engine/symbolic/negate.ts
15357
15917
  var import_complex9 = __toESM(require_complex());
@@ -15664,7 +16224,6 @@ var ComputeEngine = (() => {
15664
16224
  // ],
15665
16225
  ];
15666
16226
  function findUnivariateRoots(expr, x) {
15667
- /* @__PURE__ */ console.log("findUnivariateRoots", expr.toString(), x);
15668
16227
  const ce = expr.engine;
15669
16228
  if (expr.head === "Equal") {
15670
16229
  expr = ce.add([expr.op1.canonical, ce.neg(expr.op2.canonical)]).simplify();
@@ -18805,7 +19364,7 @@ var ComputeEngine = (() => {
18805
19364
  }
18806
19365
  },
18807
19366
  Erf: {
18808
- description: "Complementary Error Function",
19367
+ description: "Error Function",
18809
19368
  complexity: 7500
18810
19369
  },
18811
19370
  Erfc: {
@@ -18813,7 +19372,7 @@ var ComputeEngine = (() => {
18813
19372
  complexity: 7500
18814
19373
  },
18815
19374
  Factorial: {
18816
- description: "The factorial function",
19375
+ description: "Factorial Function",
18817
19376
  wikidata: "Q120976",
18818
19377
  complexity: 9e3,
18819
19378
  signature: {
@@ -18852,7 +19411,7 @@ var ComputeEngine = (() => {
18852
19411
  wikidata: "Q190573",
18853
19412
  complexity: 8e3,
18854
19413
  signature: {
18855
- domain: ["Function", "Number", "Number", "Number"],
19414
+ domain: ["Function", "Number", "Number"],
18856
19415
  N: (ce, ops2) => applyN(
18857
19416
  ops2[0],
18858
19417
  (x) => gamma(x),
@@ -18864,7 +19423,7 @@ var ComputeEngine = (() => {
18864
19423
  LogGamma: {
18865
19424
  complexity: 8e3,
18866
19425
  signature: {
18867
- domain: ["Function", "Number", "Number", "Number"],
19426
+ domain: ["Function", "Number", "Number"],
18868
19427
  N: (ce, ops2) => applyN(
18869
19428
  ops2[0],
18870
19429
  (x) => lngamma(x),
@@ -19600,6 +20159,18 @@ var ComputeEngine = (() => {
19600
20159
  level ?? (level = 1);
19601
20160
  if (level === 1) {
19602
20161
  const h = oneOf([
20162
+ [
20163
+ "Sqrt",
20164
+ [
20165
+ "Multiply",
20166
+ 6,
20167
+ [
20168
+ "Sum",
20169
+ ["Divide", 1, ["Power", "n", 2]],
20170
+ ["Triple", ["Hold", "n"], 1, { num: "+Infinity" }]
20171
+ ]
20172
+ ]
20173
+ ],
19603
20174
  "Add",
19604
20175
  "Add",
19605
20176
  "Add",
@@ -19618,13 +20189,16 @@ var ComputeEngine = (() => {
19618
20189
  "Negate",
19619
20190
  "trig"
19620
20191
  ]);
19621
- return randomExpressionWithHead(h, 1);
20192
+ if (typeof h === "string")
20193
+ return randomExpressionWithHead(h, 1);
20194
+ return h;
19622
20195
  }
19623
20196
  if (level === 2) {
19624
- if (Math.random() > 0.5)
19625
- return randomExpression(3);
19626
- if (Math.random() > 0.75)
20197
+ const r = Math.random();
20198
+ if (r > 0.75)
19627
20199
  return randomExpression(1);
20200
+ if (r > 0.5)
20201
+ return randomExpression(3);
19628
20202
  const h = oneOf([
19629
20203
  "Multiply",
19630
20204
  "Multiply",
@@ -19678,7 +20252,7 @@ var ComputeEngine = (() => {
19678
20252
  ["Rational", 12, 15],
19679
20253
  ["Rational", 15, 12],
19680
20254
  "ExponentialE",
19681
- "ImaginaryUnit",
20255
+ // 'ImaginaryUnit',
19682
20256
  ["Sqrt", 3],
19683
20257
  ["Sqrt", 5],
19684
20258
  ["Sqrt", 15],
@@ -19696,8 +20270,8 @@ var ComputeEngine = (() => {
19696
20270
  ["Power", "x", 4],
19697
20271
  ["Subtract", "x", 1],
19698
20272
  ["Add", "x", 1],
19699
- "a",
19700
- "b",
20273
+ // 'a',
20274
+ // 'b',
19701
20275
  "Pi"
19702
20276
  ]);
19703
20277
  }
@@ -19892,7 +20466,7 @@ var ComputeEngine = (() => {
19892
20466
  Apply: {
19893
20467
  signature: {
19894
20468
  domain: "Function",
19895
- evaluate: (ce, ops2) => apply(ops2[0], ops2.slice(1))
20469
+ evaluate: (_ce, ops2) => apply(ops2[0], ops2.slice(1))
19896
20470
  }
19897
20471
  },
19898
20472
  About: { signature: { domain: "Function" } },
@@ -19904,6 +20478,11 @@ var ComputeEngine = (() => {
19904
20478
  */
19905
20479
  signature: { domain: "Function" }
19906
20480
  },
20481
+ Derivative: {
20482
+ signature: {
20483
+ domain: ["Function", "Function", ["Maybe", "Number"], "Function"]
20484
+ }
20485
+ },
19907
20486
  Domain: {
19908
20487
  /** Return the domain of an expression */
19909
20488
  signature: {
@@ -20279,7 +20858,7 @@ var ComputeEngine = (() => {
20279
20858
  // expressions into CNF (Conjunctive Normal Form)
20280
20859
  // https://en.wikipedia.org/wiki/Conjunctive_normal_form
20281
20860
  // using rules (with a rule set that's kinda the inverse of the
20282
- // logic rules for simplify
20861
+ // logic rules for simplify)
20283
20862
  And: {
20284
20863
  wikidata: "Q191081",
20285
20864
  threadable: true,
@@ -20353,6 +20932,10 @@ var ComputeEngine = (() => {
20353
20932
  return ops2[1] ? ops2[1].evaluate() : ce.box("Nothing");
20354
20933
  return ops2[2] ? ops2[2].evaluate() : ce.box("Nothing");
20355
20934
  },
20935
+ // @todo: probably don't need a N() handler. Doesn't make a difference
20936
+ // for the evaluation of booleans. Also, don't need to call N() on the
20937
+ // arguments, the caller should have done that. Same for evaluate()
20938
+ // and simplify() above
20356
20939
  N: (ce, ops2) => {
20357
20940
  const cond = ops2[0];
20358
20941
  if (cond && cond.symbol === "True")
@@ -22525,26 +23108,6 @@ var ComputeEngine = (() => {
22525
23108
  );
22526
23109
  }
22527
23110
 
22528
- // src/compute-engine/library/utils.ts
22529
- function isSymbolDefinition(def) {
22530
- return !!def && typeof def === "object" && ("domain" in def || "value" in def || "constant" in def);
22531
- }
22532
- function isFunctionDefinition(def) {
22533
- if (def === void 0 || def === null)
22534
- return false;
22535
- if (typeof def !== "object")
22536
- return false;
22537
- if ("complexity" in def || "numeric" in def || "signature" in def)
22538
- return true;
22539
- if (!("domain" in def))
22540
- return false;
22541
- if (def.domain === void 0)
22542
- return false;
22543
- if (typeof def.domain === "string")
22544
- return def.domain === "Function";
22545
- return def.domain.isFunction;
22546
- }
22547
-
22548
23111
  // src/compute-engine/library/library.ts
22549
23112
  function getStandardLibrary(categories) {
22550
23113
  if (categories === "all") {
@@ -23575,14 +24138,15 @@ ${JSON.stringify(entry)}`
23575
24138
  * perform calculations using arbitrary precision floating point numbers.
23576
24139
  * Use `"auto"` or `"complex"` to allow calculations on complex numbers.
23577
24140
  *
23578
- * @param options.numericPrecision Specific how many digits of precision for the
23579
- * numeric calculations. Default is 100.
24141
+ * @param options.numericPrecision Specific how many digits of precision
24142
+ * for the numeric calculations. Default is 100.
23580
24143
  *
23581
- * @param options.tolerance If the absolute value of the difference of two numbers
23582
- * is less than `tolerance`, they are considered equal. Used by `chop()` as well.
24144
+ * @param options.tolerance If the absolute value of the difference of two
24145
+ * numbers is less than `tolerance`, they are considered equal. Used by
24146
+ * `chop()` as well.
23583
24147
  *
23584
- * @param options.defaultDomain If an unknown symbol is encountered, assume it should
23585
- * be a variable in this domain. **Default** `ExtendedRealNumber`
24148
+ * @param options.defaultDomain If an unknown symbol is encountered, assume
24149
+ * this is its domain. **Default** `ExtendedRealNumber`
23586
24150
  */
23587
24151
  constructor(options) {
23588
24152
  /** @internal */
@@ -23943,6 +24507,10 @@ ${JSON.stringify(entry)}`
23943
24507
  return new this._bignum(a);
23944
24508
  }
23945
24509
  complex(a, b) {
24510
+ if (a instanceof Decimal)
24511
+ a = a.toNumber();
24512
+ if (b instanceof Decimal)
24513
+ b = b.toNumber();
23946
24514
  return new import_complex19.Complex(a, b);
23947
24515
  }
23948
24516
  isBignum(a) {
@@ -24520,9 +25088,29 @@ ${JSON.stringify(entry)}`
24520
25088
  this.latexSyntax.updateOptions(opts);
24521
25089
  }
24522
25090
  get jsonSerializationOptions() {
24523
- if (this._useRawJsonSerializationOptions)
24524
- return this._rawJsonSerializationOptions;
24525
- return this._jsonSerializationOptions;
25091
+ if (this._useRawJsonSerializationOptions) {
25092
+ return new Proxy(this._rawJsonSerializationOptions, {
25093
+ get(options, prop) {
25094
+ if (!(prop in options))
25095
+ return void 0;
25096
+ return options[prop];
25097
+ }
25098
+ });
25099
+ }
25100
+ const self = this;
25101
+ return new Proxy(this._jsonSerializationOptions, {
25102
+ get(options, prop) {
25103
+ if (!(prop in options))
25104
+ return void 0;
25105
+ return options[prop];
25106
+ },
25107
+ set(options, prop, value) {
25108
+ if (!(prop in options))
25109
+ return false;
25110
+ self.jsonSerializationOptions = { [prop]: value };
25111
+ return true;
25112
+ }
25113
+ });
24526
25114
  }
24527
25115
  set jsonSerializationOptions(val) {
24528
25116
  if (val.exclude)
@@ -24638,10 +25226,10 @@ ${JSON.stringify(entry)}`
24638
25226
  };
24639
25227
 
24640
25228
  // src/compute-engine.ts
24641
- var version = "0.12.7";
25229
+ var version = "0.14.0";
24642
25230
  globalThis[Symbol.for("io.cortexjs.compute-engine")] = {
24643
25231
  ComputeEngine: ComputeEngine.prototype.constructor,
24644
- version: "0.12.7"
25232
+ version: "0.14.0"
24645
25233
  };
24646
25234
  return __toCommonJS(compute_engine_exports);
24647
25235
  })();