@mathzetta/inlinemath 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +64 -20
  2. package/dist/cas.external.js +2 -2
  3. package/dist/cas.js +2 -2
  4. package/dist/chunks/calculate-Cz87Lt0N.js +2 -0
  5. package/dist/chunks/draw-Bev17BJJ.js +2 -0
  6. package/dist/chunks/edit-C65xXzo8.js +2 -0
  7. package/dist/chunks/edit-M68aRA5o.js +2 -0
  8. package/dist/chunks/{html-CvuSyhzk.js → html-BimAqn7x.js} +2 -2
  9. package/dist/chunks/html-CupluJSh.js +2 -0
  10. package/dist/chunks/lite-3Fb-OHbt.js +2 -0
  11. package/dist/inlinemath-cas.external.global.min.js +2 -2
  12. package/dist/inlinemath-cas.global.min.js +2 -2
  13. package/dist/inlinemath-lite-calc.global.min.js +2 -2
  14. package/dist/inlinemath-lite.external.global.min.js +2 -2
  15. package/dist/inlinemath-lite.global.min.js +2 -2
  16. package/dist/inlinemath.css +32 -1
  17. package/dist/inlinemath.external.global.min.js +2 -2
  18. package/dist/inlinemath.external.js +2 -2
  19. package/dist/inlinemath.global.min.js +2 -2
  20. package/dist/inlinemath.js +2 -2
  21. package/dist/lite-calc.js +2 -2
  22. package/dist/lite.external.js +2 -2
  23. package/dist/lite.js +2 -2
  24. package/dist/markdown.external.js +2 -2
  25. package/dist/markdown.js +2 -2
  26. package/inlinemath.css +32 -1
  27. package/package.json +3 -3
  28. package/src/cas.js +25 -15
  29. package/src/edit.js +96 -0
  30. package/src/glyphs.js +2 -0
  31. package/src/index.d.ts +2 -2
  32. package/src/index.js +1 -1
  33. package/src/layout.js +55 -11
  34. package/src/markdown.d.ts +2 -2
  35. package/src/markdown.js +354 -39
  36. package/src/mathzetta.js +2 -1
  37. package/src/types.d.ts +77 -6
  38. package/src/variables.js +228 -0
  39. package/src/view.js +226 -6
  40. package/dist/chunks/calculate-BX9lJ7Ff.js +0 -2
  41. package/dist/chunks/draw-Cm4exbg7.js +0 -2
  42. package/dist/chunks/html-DWtfytjA.js +0 -2
  43. package/dist/chunks/lite-Bj_L6w2g.js +0 -2
package/dist/cas.js CHANGED
@@ -1,2 +1,2 @@
1
- /* Inline Math 0.1.0 — MIT licence; includes mathzetta (and @mathzetta/cas, for the CAS) */
2
- import{m as e,o as n,q as t,r,u as s,G as o,v as i,w as a,x as u,y as l,i as c,z as f,A as p,f as d,B as h,C as m}from"./chunks/lite-Bj_L6w2g.js";import{c as g}from"./chunks/calculate-BX9lJ7Ff.js";import{a as v}from"./chunks/html-DWtfytjA.js";const b=new Map,y=-1,w="\\:",x=e=>"string"==typeof e&&e.startsWith(w)&&e.length>2;function q(e){if(!e||!e.symbol)throw new Error("operator needs a symbol");if(!Number.isInteger(e.arity)||e.arity<0&&e.arity!==y)throw new Error(`operator "${e.symbol}" needs an integer arity >= 0, or VARIADIC`);if(e.commutative&&2!==e.arity)throw new Error(`only binary operators can be commutative ("${e.symbol}")`);const n={symbol:e.symbol,arity:e.arity,commutative:!!e.commutative,fold:"function"==typeof e.fold?e.fold:null,label:e.label||e.symbol};return b.set(n.symbol,n),n}const k=Object.freeze({symbol:w,arity:y,commutative:!1,fold:null,label:"function"});function $(e){const n=b.get(e);return n||(x(e)?{...k,symbol:e,label:e.slice(2)}:null)}function S(e){return b.has(e)||x(e)}const O=e=>Number.isFinite(e)&&Number.isInteger(e)?e:null,N=e=>Number.isFinite(e)?e:null;!function(){q({symbol:"+",arity:2,commutative:!0,label:"add",fold:(e,n)=>N(e+n)}),q({symbol:"-",arity:2,label:"subtract",fold:(e,n)=>N(e-n)}),q({symbol:"*",arity:2,commutative:!0,label:"multiply",fold:(e,n)=>N(e*n)}),q({symbol:"/",arity:2,label:"divide",fold:(e,n)=>0===n?null:O(e/n)}),q({symbol:"^",arity:2,label:"power",fold:(e,n)=>Number.isInteger(n)&&Math.abs(n)<=64?N(e**n):null}),q({symbol:"neg",arity:1,label:"negate",fold:e=>N(-e)}),q({symbol:"pm",arity:1,label:"plus or minus"}),q({symbol:"±",arity:2,label:"plus or minus"}),q({symbol:"mod",arity:2,label:"modulo",fold:(e,n)=>0===n?null:O((e%n+n)%n)}),q({symbol:"!",arity:1,label:"factorial",fold:e=>Number.isInteger(e)&&e>=0&&e<=18?[...Array(e).keys()].reduce((e,n)=>e*(n+1),1):null}),q({symbol:"_",arity:2,label:"subscript"}),q({symbol:"der",arity:2,label:"derivative"}),q({symbol:"int",arity:y,label:"integral"}),q({symbol:"lim",arity:y,label:"limit"}),q({symbol:"\\sumidx",arity:y,label:"sum over an index"}),q({symbol:"\\prodidx",arity:y,label:"product over an index"}),q({symbol:"abs",arity:1,label:"absolute value",fold:e=>N(Math.abs(e))}),q({symbol:"floor",arity:1,label:"floor",fold:e=>N(Math.floor(e))}),q({symbol:"ceil",arity:1,label:"ceiling",fold:e=>N(Math.ceil(e))}),q({symbol:"round",arity:2,label:"round",fold:(e,n)=>Number.isInteger(n)?N(Math.round(e*10**n)/10**n):null}),q({symbol:"fixed",arity:2,label:"fixed",fold:()=>null}),q({symbol:"sqrt",arity:1,label:"square root",fold:e=>O(Math.sqrt(e))}),q({symbol:"root",arity:2,label:"nth root",fold:(e,n)=>O(Math.round(n**(1/e))**e===n?Math.round(n**(1/e)):NaN)});for(const e of["sin","cos","tan","csc","sec","cot","sinh","cosh","tanh","arcsin","arccos","arctan","arcsinh","arccosh","arctanh","ln","loglog","logloglog","expm1"])q({symbol:e,arity:1,label:e});q({symbol:"log",arity:2,label:"log to a base"}),q({symbol:"atan2",arity:2,label:"atan2"}),q({symbol:"perm",arity:2,label:"permutations"}),q({symbol:"comb",arity:2,label:"combinations"}),q({symbol:"random",arity:0,label:"random"});for(const e of["max","min","gcd","mean","sum","prod"])q({symbol:e,arity:y,label:e});for(const e of["()","[]","{}","(]","[)"])q({symbol:e,arity:y,label:"group"});for(const e of["=","===","≠","≠=","<",">","≤","≥","∈","∉","∪","∩","≈","≡","→","pmod","&","|","\\xor","\\nand","\\nor"])q({symbol:e,arity:2,label:e});q({symbol:"\\not",arity:1,label:"not"}),q({symbol:"?:",arity:3,label:"if then else"})}();const A="num",I="sym",M="op",E=Object.freeze([]);class T extends Error{constructor(e){super(e),this.name="ExprError"}}function j(e){if("number"!=typeof e||!Number.isFinite(e))throw new T(`not a finite number: ${e}`);const n=(t=e,Object.is(t,-0)?"0":String(t));var t;return Object.freeze({type:A,token:n,value:e,args:E,s:n})}function Z(e){if("string"!=typeof e||""===e)throw new T("symbol needs a non-empty token");return Object.freeze({type:I,token:e,value:null,args:E,s:e})}function z(e){const n=/^(-?)0*(\d+?)(?:\.(\d*?)0*)?$/.exec(String(e));if(!n)throw new T(`not an exact decimal: ${e}`);const[,t,r,s=""]=n,o=s?`${r}.${s}`:r,i=/^0(\.0*)?$/.test(o)?"0":t+o;return Object.freeze({type:A,token:i,value:Number(i),args:E,s:i})}const D=/^-?\d+(\.\d+)?$/;function B(e){const n=String(e);if(D.test(n))return z(n);if(""!==n&&!/\s/.test(n)){const e=Number(n);if(Number.isFinite(e))return j(e)}return Z(n)}function C(e,n){const t=$(e);if(!t)throw new T(`unknown operator "${e}"`);if(t.arity!==y&&n.length!==t.arity)throw new T(`"${e}" takes ${t.arity} operand(s), got ${n.length}`);const r=Object.freeze(n.slice()),s=t.arity===y?` ${r.length}`:"",o=`${r.length?r.map(e=>e.s).join(" "):""}${r.length,""}${s} ${e}`.trimStart();return Object.freeze({type:M,op:e,token:e,value:null,args:r,s:o})}const F=e=>e.type===A,V=e=>e.type===M;function R(e){return U(function(e){const n=String(e).trim();return""===n?[]:n.split(/\s+/)}(e))}function U(e){if(!Array.isArray(e))throw new T("fromPostfix needs an array of tokens");if(0===e.length)throw new T("empty expression");const n=[];for(let t=0;t<e.length;t++){const r=String(e[t]);if(S(r)){let e=$(r).arity;if(e===y){const s=n.pop();if(e=s&&s.type===A&&Number.isInteger(s.value)&&s.value>=0?s.value:-1,e<0)throw new T(`"${r}" at position ${t+1} takes any number of operands, so a count must come before it`)}if(n.length<e)throw new T(`"${r}" at position ${t+1} needs ${e} operand(s), only ${n.length} on the stack`);const s=n.splice(n.length-e,e);n.push(C(r,s))}else n.push(B(r))}if(1!==n.length){const t=[...new Set(e.filter(e=>!S(e)))];throw new T(`expression leaves ${n.length} values on the stack; it should leave exactly 1. Read as operands: ${t.join(", ")} — is one of those meant to be an operator?`)}return n[0]}function P(e){if(e.type!==M)return 0;let n=0;for(const t of e.args)n=Math.max(n,P(t));return n+1}function W(e){if(e.type!==M)return 1;let n=1;for(const t of e.args)n+=W(t);return n}function L(e,n=[]){if(e.type!==M)n.push(e.token);else for(const t of e.args)L(t,n);return n}function _(e){return e.type===A||e.type!==I&&e.args.every(_)}function H(e,n="pre",t=[],r=[]){"pre"===n&&r.push({node:e,path:t});for(let s=0;s<e.args.length;s++)H(e.args[s],n,t.concat(s),r);return"post"===n&&r.push({node:e,path:t}),r}function J(e,n,t){if(0===n.length)return t;const[r,...s]=n,o=e.args.slice();return o[r]=J(o[r],s,t),C(e.op,o)}class Q extends Error{constructor(e){super(e),this.name="CasError"}}const Y=1e5,G=e=>e<0n?-e:e,K=e=>0n===e?0:G(e).toString(2).length;function X(e,n){for(e=G(e),n=G(n);n;)[e,n]=[n,e%n];return e}class ee{constructor(e,n=1n){if(0n===n)throw new Q("division by zero");n<0n&&(e=-e,n=-n);const t=X(e,n)||1n;if(this.n=e/t,this.d=n/t,K(this.n)>Y||K(this.d)>Y)throw new Q("a number too large to keep exactly")}static of(e){return new ee(BigInt(e))}add(e){return new ee(this.n*e.d+e.n*this.d,this.d*e.d)}sub(e){return new ee(this.n*e.d-e.n*this.d,this.d*e.d)}mul(e){return new ee(this.n*e.n,this.d*e.d)}div(e){if(0n===e.n)throw new Q("division by zero");return new ee(this.n*e.d,this.d*e.n)}neg(){return new ee(-this.n,this.d)}abs(){return this.n<0n?this.neg():this}inv(){return ee.ONE.div(this)}pow(e){if((e=BigInt(e))<0n)return this.inv().pow(-e);if((0n===this.n||1n===G(this.n))&&1n===this.d)return 0n===e||-1n===this.n&&e%2n==0n?ee.ONE:this;if(BigInt(Math.max(K(this.n),K(this.d)))*e>BigInt(Y))throw new Q("a power too large to work out exactly");return new ee(this.n**e,this.d**e)}get isZero(){return 0n===this.n}get isOne(){return 1n===this.n&&1n===this.d}get isInteger(){return 1n===this.d}get sign(){return this.n<0n?-1:this.n>0n?1:0}equals(e){return this.n===e.n&&this.d===e.d}compare(e){const n=this.n*e.d,t=e.n*this.d;return n<t?-1:n>t?1:0}floor(){const e=this.n/this.d;return new ee(this.n<0n&&e*this.d!==this.n?e-1n:e)}ceil(){return this.neg().floor().neg()}toNumber(){const e=Number(this.n),n=Number(this.d);if(Number.isFinite(e)&&Number.isFinite(n))return e/n;const t=BigInt(Math.max(K(this.n),K(this.d))-1e3);return Number(this.n>>t)/Number(this.d>>t)}toString(){return 1n===this.d?String(this.n):`${this.n}/${this.d}`}}function ne(e){const n=/^(-?)(\d*)(?:\.(\d*))?(?:[eE]([+-]?\d+))?$/.exec(String(e));if(!n||""===n[2]&&!n[3])return null;const[,t,r,s="",o="0"]=n;let i=new ee(BigInt((r||"0")+s),10n**BigInt(s.length));const a=Number(o);return a&&(i=i.mul(ee.of(10).pow(a))),t?i.neg():i}function te(e,n){if(e<2n)return e;if(n>=K(e))return 1n;const t=BigInt(n);let r=1n<<BigInt(Math.ceil(K(e)/n));for(;;){const n=((t-1n)*r+e/r**(t-1n))/t;if(n>=r)break;r=n}for(;r**t>e;)r--;for(;(r+1n)**t<=e;)r++;return r}ee.ZERO=new ee(0n),ee.ONE=new ee(1n),ee.MINUS_ONE=new ee(-1n),ee.HALF=new ee(1n,2n);const re=(()=>{const e=[],n=new Uint8Array(1e4);for(let t=2;t<n.length;t++)if(!n[t]){e.push(BigInt(t));for(let e=t*t;e<n.length;e+=t)n[e]=1}return e})();function se(e,n){const t=BigInt(n);let r=1n,s=1n,o=e;for(const e of re){if(e*e>o)break;if(o%e)continue;let n=0n;for(;o%e===0n;)o/=e,n++;r*=e**(n/t),s*=e**(n%t)}if(o>1n){const e=function(e,n){if(e<0n)return null;if(e<2n)return e;const t=te(e,n);return t**BigInt(n)===e?t:null}(o,n);null!==e?r*=e:s*=o}return{outside:r,inside:s}}const oe=new Set(["pi","e","π"]),ie={complex:!1};function ae(e,n){const t=ie.complex;ie.complex=Boolean(e);try{return n()}finally{ie.complex=t}}const ue=e=>oe.has(e)||ie.complex&&"i"===e,le=e=>ie.complex&&"atom"===e.k&&"sym"===e.node.type&&"i"===e.node.token,ce=e=>({k:"num",q:e}),fe=ce(ee.ONE),pe=ce(ee.ZERO),de=ce(ee.HALF),he=e=>"num"===e.k,me=e=>({k:"atom",node:e}),ge=new WeakMap;function ve(e){let n=ge.get(e);return void 0===n&&ge.set(e,n=Qe(e).s),n}function be(e){if("num"===e.k)return 0;if("atom"===e.k)return"sym"===e.node.type&&ue(e.node.token)?0:1;if("add"===e.k)return Math.max(...e.terms.map(e=>be(e.x)));let n=0;for(const t of e.fs){const e=be(t.b);e&&(n+=e*(he(t.e)?t.e.q.toNumber():1))}return n}function ye(e,n){return"num"===e.k?n&&!he(n)?3:0:le(e)?1.5:"atom"===e.k&&"sym"===e.node.type?ue(e.node.token)?n&&!he(n)?3:1:2:"atom"===e.k?3:4}const we=(e,n)=>e<n?-1:e>n?1:0;function xe(e){const n=new Map,t=(e,t)=>{"atom"!==e.k||"sym"!==e.node.type||ue(e.node.token)||n.set(e.node.token,(n.get(e.node.token)??0)+t)};if("mul"===e.k)for(const n of e.fs)t(n.b,he(n.e)?n.e.q.toNumber():1);else t(e,1);return n}function qe(e,n){const t=be(n.x)-be(e.x);if(t)return t;const r=xe(e.x),s=xe(n.x);for(const e of[...new Set([...r.keys(),...s.keys()])].sort()){const n=(s.get(e)??0)-(r.get(e)??0);if(n)return n}return we(ve(e.x),ve(n.x))}function ke(e,n){return e.isOne?n:e.isZero?pe:Ne([ce(e),n])}function $e(e){if("num"===e.k)return{coef:e.q,rest:null};if("mul"!==e.k||e.c.isOne)return{coef:ee.ONE,rest:e};const n=1===e.fs.length&&he(e.fs[0].e)&&e.fs[0].e.q.isOne?e.fs[0].b:{k:"mul",c:ee.ONE,fs:e.fs};return{coef:e.c,rest:n}}function Se(e){let n=ee.ZERO;const t=new Map,r=(e,n)=>{const r=ve(n),s=t.get(r);s?s.coef=s.coef.add(e):t.set(r,{coef:e,x:n})};for(const t of e)if("num"===t.k)n=n.add(t.q);else if("add"===t.k){n=n.add(t.c);for(const e of t.terms)r(e.coef,e.x)}else{const{coef:e,rest:n}=$e(t);r(e,n)}const s=[...t.values()].filter(e=>!e.coef.isZero);return s.length?n.isZero&&1===s.length?ke(s[0].coef,s[0].x):(s.sort(qe),{k:"add",c:n,terms:s}):ce(n)}function Oe(e,n){if(!he(n))return e.isOne?{coef:ee.ONE,fs:[]}:{coef:ee.ONE,fs:[{b:ce(e),e:n}]};const t=n.q;if(t.isInteger)return{coef:e.pow(t.n),fs:[]};if(e.isZero){if(t.sign<0)throw new Q("division by zero");return{coef:ee.ZERO,fs:[]}}if(e.isOne)return{coef:ee.ONE,fs:[]};if(e.sign<0){if(t.d%2n==1n){const{coef:r,fs:s}=Oe(e.neg(),n);return{coef:t.n%2n==0n?r:r.neg(),fs:s}}if(ie.complex&&2n===t.d){const{coef:r,fs:s}=Oe(e.neg(),n);return{coef:r,fs:[...s,{b:Me,e:ce(new ee(t.n))}]}}return{coef:ee.ONE,fs:[{b:ce(e),e:n}]}}if(!e.isInteger){const r=Oe(new ee(e.n),n),s=Oe(new ee(e.d),ce(t.neg()));return{coef:r.coef.mul(s.coef),fs:[...r.fs,...s.fs]}}const r=t.floor(),s=t.sub(r);if(BigInt(K(e.n))*s.n>BigInt(Y)||s.d>1000n)return{coef:ee.ONE,fs:[{b:ce(e),e:n}]};let o=r.isZero?ee.ONE:e.pow(r.n);const{outside:i,inside:a}=se(e.n**s.n,Number(s.d));o=o.mul(new ee(i));return{coef:o,fs:a>1n?[{b:ce(new ee(a)),e:ce(new ee(1n,s.d))}]:[]}}function Ne(e){let n=ee.ONE;const t=new Map,r=(e,n)=>{const r=ve(e),s=t.get(r);s?s.e=Se([s.e,n]):t.set(r,{b:e,e:n})};for(const t of e)if("num"===t.k)n=n.mul(t.q);else if("mul"===t.k){n=n.mul(t.c);for(const e of t.fs)r(e.b,e.e)}else r(t,fe);if(n.isZero)return pe;const s=[],o=new Map;for(const e of t.values())if(!he(e.e)||!e.e.q.isZero){if("num"===e.b.k){if(he(e.e)&&!e.e.q.isInteger&&e.b.q.sign>0&&e.b.q.isInteger){const n=e.e.q.toString(),t=o.get(n);t?t.n*=e.b.q.n:o.set(n,{n:e.b.q.n,e:e.e});continue}const t=Oe(e.b.q,e.e);n=n.mul(t.coef),s.push(...t.fs);continue}if("mul"===e.b.k&&he(e.e)&&e.e.q.isInteger){const t=Ae(e.b,e.e);"mul"===t.k?(n=n.mul(t.c),s.push(...t.fs)):"num"===t.k?n=n.mul(t.q):s.push({b:t,e:fe});continue}s.push(e)}for(const{n:e,e:t}of o.values()){const r=Oe(new ee(e),t);n=n.mul(r.coef),s.push(...r.fs)}if(n.isZero)return pe;const i=new Map;for(const e of s){const n=ve(e.b),t=i.get(n);t?t.e=Se([t.e,e.e]):i.set(n,{...e})}let a=[...i.values()].filter(e=>!(he(e.e)&&e.e.q.isZero));if(ie.complex){a=a.flatMap(e=>{if(!le(e.b)||!he(e.e)||!e.e.q.isInteger)return[e];const t=(e.e.q.n%4n+4n)%4n;return t>=2n&&(n=n.neg()),t%2n?[{b:e.b,e:fe}]:[]});const e=a.filter(e=>"add"===e.b.k&&he(e.e)&&e.e.q.isInteger&&Te(e.b)),t=a.some(e=>le(e.b)),r=e.every(e=>(e.e.q.sign<0?-e.e.q.n:e.e.q.n)<=60n);if(e.length&&r&&(e.length>1||t||!e[0].e.q.isOne)){const r=a.filter(n=>!e.includes(n)&&!le(n.b));let s=t?[Me]:[fe];for(const n of e){const e=n.e.q.sign<0?ze(n.b):n.b;for(let t=0n;t<(n.e.q.sign<0?-n.e.q.n:n.e.q.n);t++)s=je(s,Xe(e))}return Ne([ce(n),Se(s),...r.map(e=>Ie(e.b,e.e))])}}if(a.some(e=>"num"===e.b.k&&he(e.e)&&e.e.q.compare(ee.ONE)>=0))return Ne([ce(n),...a.map(e=>"num"===e.b.k?Ae(e.b,e.e):{k:"mul",c:ee.ONE,fs:[e]})]);if(!a.length)return ce(n);if(1===a.length&&!n.isOne&&"add"===a[0].b.k&&he(a[0].e)&&a[0].e.q.isOne){const e=a[0].b;return Se([ce(n.mul(e.c)),...e.terms.map(e=>ke(n.mul(e.coef),e.x))])}return n.isOne&&1===a.length&&he(a[0].e)&&a[0].e.q.isOne?a[0].b:(a=a.sort((e,n)=>ye(e.b,e.e)-ye(n.b,n.e)||we(ve(e.b),ve(n.b))),{k:"mul",c:n,fs:a})}function Ae(e,n){if(ie.complex&&he(n)&&n.q.isInteger){if(le(e))return Ne([{k:"mul",c:ee.ONE,fs:[{b:e,e:n}]}]);if("add"===e.k&&Te(e)&&!n.q.isOne)return Ne([{k:"mul",c:ee.ONE,fs:[{b:e,e:n}]}])}if(he(n)){if(n.q.isZero){if(he(e)&&e.q.isZero)throw new Q("0^0 is undefined");return fe}if(n.q.isOne)return e}if(he(e)){const t=Oe(e.q,n);if(!t.fs.length)return ce(t.coef);if(t.fs.some(e=>le(e.b)))return Ne([ce(t.coef),...t.fs.map(e=>({k:"mul",c:ee.ONE,fs:[e]}))]);const r={k:"mul",c:t.coef,fs:t.fs};return t.coef.isOne&&1===t.fs.length&&he(t.fs[0].e)&&t.fs[0].e.q.isOne?t.fs[0].b:r}if(ie.complex&&he(n)&&2n===n.q.d&&Te(e)){const t=Ze(e);if(t&&he(t.im)&&!t.im.q.isZero){const e=e=>Ae(e,ce(ee.of(2))),r=Ae(Se([e(t.re),e(t.im)]),de),s=Ae(Ne([Se([r,t.re]),ce(ee.HALF)]),de),o=Ae(Ne([Se([r,Ce(t.re)]),ce(ee.HALF)]),de);return Ae(Se([s,Ne([ce(ee.of(t.im.q.sign)),o,Me])]),ce(new ee(n.q.n)))}}if("mul"===e.k){if(he(n)&&n.q.isInteger)return Ne([ce(e.c.pow(n.q.n)),...e.fs.map(e=>Ie(e.b,Ne([e.e,n])))]);if(!e.c.isOne&&e.c.sign>0)return Ne([Ae(ce(e.c),n),Ae({k:"mul",c:ee.ONE,fs:e.fs},n)]);if(e.c.isOne&&1===e.fs.length){const[t]=e.fs;if(he(t.e)&&he(n)&&1n===t.e.q.n&&t.e.q.d%2n==1n)return Ie(t.b,Ne([t.e,n]))}}return{k:"mul",c:ee.ONE,fs:[{b:e,e:n}]}}function Ie(e,n){return he(n)&&n.q.isZero?fe:he(e)?Ae(e,n):he(n)&&n.q.isOne?e:{k:"mul",c:ee.ONE,fs:[{b:e,e:n}]}}const Me=me(Z("i")),Ee=e=>ie.complex&&Qe(e).s.split(" ").includes("i");function Te(e){return ie.complex&&Ee(e)&&0===Ke(Qe(e)).size}function je(e,n){const t=[];for(const r of e)for(const e of n)t.push(Ne([r,e]));return Xe(Se(t))}function Ze(e){const n=[],t=[];for(const r of Xe(e)){const{coef:e,rest:s}=$e(r),o=s?en(s):[],i=o.filter(e=>le(e)),a=o.filter(e=>!le(e));if(a.some(e=>Ee(e)))return null;(i.length?t:n).push(Ne([ce(e),...a]))}return{re:Se(n),im:Se(t)}}function ze(e){const n=Ze(e);if(!n)return Ae(e,ce(ee.MINUS_ONE));const t=Se([Ae(n.re,ce(ee.of(2))),Ae(n.im,ce(ee.of(2)))]);return Ne([Se([n.re,Ne([ce(ee.MINUS_ONE),n.im,Me])]),Ae(t,ce(ee.MINUS_ONE))])}const De={re:([e])=>Ze(e)?.re??null,im:([e])=>Ze(e)?.im??null,conj:([e])=>{const n=Ze(e);return n?Se([n.re,Ne([ce(ee.MINUS_ONE),n.im,Me])]):null},arg:([e])=>{const n=Ze(e);return n?Ue("atan2",[n.im,n.re]):null},abs:([e])=>{const n=Ze(e);return!n||he(n.im)&&n.im.q.isZero?null:Ae(Se([Ae(n.re,ce(ee.of(2))),Ae(n.im,ce(ee.of(2)))]),de)}},Be={Re:"re",re:"re",Im:"im",im:"im",conj:"conj",overline:"conj",bar:"conj",arg:"arg"},Ce=e=>Ne([ce(ee.MINUS_ONE),e]),Fe=(e,n)=>Ne([e,Ae(n,ce(ee.MINUS_ONE))]),Ve=3000n,Re={abs:([e])=>he(e)?ce(e.q.abs()):"mul"!==e.k||e.c.isOne?null:Ne([ce(e.c.abs()),Ue("abs",[$e(e).rest])]),floor:([e])=>he(e)?ce(e.q.floor()):null,ceil:([e])=>he(e)?ce(e.q.ceil()):null,"!":([e])=>{if(!he(e)||!e.q.isInteger||e.q.sign<0||e.q.n>Ve)return null;let n=1n;for(let t=2n;t<=e.q.n;t++)n*=t;return ce(new ee(n))},mod:([e,n])=>he(e)&&he(n)&&!n.q.isZero?ce(e.q.sub(n.q.mul(e.q.div(n.q).floor()))):null,max:e=>e.every(he)&&e.length?e.reduce((e,n)=>n.q.compare(e.q)>0?n:e):null,min:e=>e.every(he)&&e.length?e.reduce((e,n)=>n.q.compare(e.q)<0?n:e):null,gcd:e=>e.length&&e.every(e=>he(e)&&e.q.isInteger)?ce(new ee(e.reduce((e,n)=>X(e,n.q.n),0n))):null,log:([e,n])=>{if(!he(e)||!he(n)||e.q.sign<=0||n.q.sign<=0||e.q.isOne)return null;if(n.q.isOne)return pe;const t=Math.log(n.q.toNumber())/Math.log(e.q.toNumber());if(!Number.isFinite(t))return null;for(let r=1;r<=12;r++){const s=Math.round(t*r);if(!(Math.abs(t*r-s)>1e-9||0===s)&&(Math.abs(s)<=256&&e.q.pow(BigInt(s)).equals(n.q.pow(BigInt(r)))))return ce(new ee(BigInt(s),BigInt(r)))}return null},comb:([e,n])=>he(e)&&he(n)&&e.q.isInteger&&n.q.isInteger&&e.q.sign>=0&&n.q.sign>=0&&e.q.n<=Ve?ce(function(e,n){if(n>e)return ee.ZERO;n>e-n&&(n=e-n);let t=1n;for(let r=1n;r<=n;r++)t=t*(e-n+r)/r;return new ee(t)}(e.q.n,n.q.n)):null,perm:([e,n])=>{if(!(he(e)&&he(n)&&e.q.isInteger&&n.q.isInteger&&e.q.sign>=0&&n.q.sign>=0&&e.q.n<=Ve))return null;if(n.q.n>e.q.n)return pe;let t=1n;for(let r=0n;r<n.q.n;r++)t*=e.q.n-r;return ce(new ee(t))}};function Ue(e,n){if(ie.complex&&De[e]){const t=De[e](n);if(t)return t}const t=Re[e];if(t){const e=t(n);if(e)return e}return me(C(e,n.map(Qe)))}const Pe=new Map;function We(e){const n=ie.complex?`ℂ ${e.s}`:e.s,t=Pe.get(n);if(t)return t;const r=function(e){if("num"===e.type){const n=ne(e.token);if(!n)throw new Q(`not an exact number: ${e.token}`);return ce(n)}if("sym"===e.type)return"π"===e.token?me(Z("pi")):me(e);const n=e.args.map(We);switch(e.op){case"+":return Se(n);case"-":return((e,n)=>Se([e,Ce(n)]))(n[0],n[1]);case"neg":return Ce(n[0]);case"*":return Ne(n);case"/":return Fe(n[0],n[1]);case"^":return Ae(n[0],n[1]);case"sqrt":return Ae(n[0],de);case"root":return Ae(n[1],Ae(n[0],ce(ee.MINUS_ONE)));default:{const t=e.op.startsWith("\\:")?e.op.slice(2):null;return t&&ie.complex&&Be[t]&&1===n.length?Ue(Be[t],n):t&&S(t)&&$(t).arity===n.length?Ue(t,n):Ue(e.op,n)}}}(e);return Pe.size>2e4&&Pe.clear(),Pe.set(n,r),r}const Le=e=>Qe(We(e)),_e=e=>z(String(e));function He(e){return e.isInteger?_e(e.n):C("/",[_e(e.n),_e(e.d)])}const Je=new WeakMap;function Qe(e){let n=Je.get(e);return n||Je.set(e,n=function(e){switch(e.k){case"num":return He(e.q);case"atom":return e.node;case"mul":return function(e,n){const t=[],r=[];for(const e of n)he(e.e)&&e.e.q.sign<0?r.push(Ye(e.b,ce(e.e.q.neg()))):t.push(Ye(e.b,e.e));let s=1n!==e.n&&-1n!==e.n||!t.length?Ge([_e(e.n),...t]):Ge(t);-1n===e.n&&t.length&&(s=C("neg",[s]));1n!==e.d&&r.unshift(_e(e.d));return r.length?C("/",[s,Ge(r)]):s}(e.c,e.fs);case"add":return function(e){let n=null;const t=e=>ie.complex&&Ee(e.x)&&0===Ke(Qe(e.x)).size,r=[...e.terms.filter(e=>!t(e)),...e.terms.filter(t)],s=e.c,o=()=>{s.isZero||(n=n?s.sign<0?C("-",[n,He(s.neg())]):C("+",[n,He(s)]):He(s))};let i=!1;for(const e of r)!i&&t(e)&&(o(),i=!0),n=n?e.coef.sign<0?C("-",[n,Qe(ke(e.coef.neg(),e.x))]):C("+",[n,Qe(ke(e.coef,e.x))]):Qe(ke(e.coef,e.x));i||o();return n}(e);default:throw new Error(`bad form ${e.k}`)}}(e)),n}function Ye(e,n){const t=Qe(e);if(he(n)){const e=n.q;if(e.isOne)return t;if(1n===e.n&&2n===e.d)return C("sqrt",[t]);if(1n===e.n)return C("root",[_e(e.d),t])}return C("^",[t,Qe(n)])}const Ge=e=>e.reduce((e,n)=>e?C("*",[e,n]):n,null);function Ke(e,n=new Set){if("sym"===e.type)ue(e.token)||n.add(e.token);else if(V(e))for(const t of e.args)Ke(t,n);return n}function Xe(e){if("add"!==e.k)return[e];const n=e.terms.map(e=>ke(e.coef,e.x));return e.c.isZero||n.push(ce(e.c)),n}function en(e){if("num"===e.k)return[e];if("mul"!==e.k)return[e];const n=e.c.isOne?[]:[ce(e.c)];for(const t of e.fs)n.push(Ie(t.b,t.e));return n}const nn="_",tn=new WeakMap;function rn(e,n){return[...n,...$(e.op)?.arity===y?[String(e.args.length)]:[],e.op].join(" ")}function sn(e,n){let t=tn.get(e);t||tn.set(e,t=new Map);const r=t.get(n);if(r)return r;const s=function(e,n){const t={key:nn,slots:[e]};if(e.type!==M||n<=0)return[t];const r=e.args.map(e=>sn(e,n-1)),s=[t],o=new Array(r.length).fill(0);for(;;){const n=[],t=[];for(let e=0;e<r.length;e++){const s=r[e][o[e]];n.push(s.key);for(const e of s.slots)t.push(e)}if(s.push({key:rn(e,n),slots:t}),s.length>=4096)break;let i=r.length-1;for(;i>=0&&!(++o[i]<r[i].length);i--)o[i]=0;if(i<0)break}return s}(e,n);return t.set(n,s),s}function on(e){return e.type!==M?nn:rn(e,e.args.map(on))}function an(e,n=[]){if(e.type!==M)n.push(e);else for(const t of e.args)an(t,n);return n}const un=new Map,ln=new Map;class cn extends Error{constructor(e){super(e),this.name="RequirementError"}}function fn(e,n,t=""){un.set(e,{name:e,fn:n,doc:t,arity:Math.max(0,n.length-1)})}function pn(e,n,t=""){ln.set(e,{name:e,fn:n,doc:t})}function dn(e){return un.get(e)||null}function hn(e){return ln.get(e)||null}const mn=e=>e.type===A;function gn(e,n){return e.type===M&&(e.op===n||e.args.some(e=>gn(e,n)))}fn("always",()=>!0,"matches anything"),fn("never",()=>!1,"matches nothing"),fn("isLeaf",e=>e.type!==M,"a bare operand, not an operation"),fn("isCompound",e=>e.type===M,"an operation, not a bare operand"),fn("isSymbol",e=>e.type===I,"a non-numeric operand such as x"),fn("isOperation",(e,n)=>e.type===M&&e.op===n,"is this specific operation"),fn("notOperation",(e,n)=>!(e.type===M&&e.op===n),"is anything except this operation"),fn("isNumber",mn,"a numeric literal"),fn("isInteger",e=>mn(e)&&Number.isInteger(e.value),"a whole number"),fn("isPositive",e=>mn(e)&&e.value>0,"greater than zero"),fn("isNegative",e=>mn(e)&&e.value<0,"less than zero"),fn("isNonNegative",e=>mn(e)&&e.value>=0,"zero or greater"),fn("isZero",e=>mn(e)&&0===e.value,"exactly 0"),fn("isOne",e=>mn(e)&&1===e.value,"exactly 1"),fn("isNonZero",e=>mn(e)&&0!==e.value,"a number that is provably not 0"),fn("isNotZeroLiteral",e=>!(mn(e)&&0===e.value),"anything except a literal 0"),fn("isPositiveInteger",e=>mn(e)&&Number.isInteger(e.value)&&e.value>0,"a whole number above 0"),fn("isNegativeInteger",e=>mn(e)&&Number.isInteger(e.value)&&e.value<0,"a whole number below 0"),fn("isEven",e=>mn(e)&&Number.isInteger(e.value)&&e.value%2==0,"a whole even number"),fn("isOdd",e=>mn(e)&&Number.isInteger(e.value)&&1===Math.abs(e.value%2),"a whole odd number"),fn("greaterThan",(e,n)=>mn(e)&&e.value>Number(n),"above a given value"),fn("lessThan",(e,n)=>mn(e)&&e.value<Number(n),"below a given value"),fn("isValue",(e,n)=>mn(e)&&e.value===Number(n),"equals a given number"),fn("isNumeric",_,"contains no symbols: a constant (it need not fold to a number: 1 sin)"),fn("hasSymbol",e=>!_(e),"mentions a symbol somewhere, so it is not just a number"),fn("isVar",(e,n)=>e.type===I&&e.token===String(n),"is exactly this symbol"),fn("contains",(e,n)=>L(e).includes(String(n)),"mentions this operand somewhere"),fn("isFree",(e,n)=>!L(e).includes(String(n)),"never mentions this operand"),fn("hasOperation",(e,n)=>gn(e,String(n)),"uses this operation somewhere inside"),fn("equals",(e,n)=>e.s===String(n),"is exactly this postfix expression");const vn=e=>e.type===M?null:e.token;function bn(e){if("string"==typeof e)return{name:e,args:[]};if(Array.isArray(e)&&e.length>0&&"string"==typeof e[0])return{name:e[0],args:e.slice(1)};throw new cn(`bad requirement: ${JSON.stringify(e)}`)}pn("freeOf",(e,n)=>{const t=vn(n);return null!==t&&!L(e).includes(t)},"the first operand never mentions the second"),pn("dependsOn",(e,n)=>{const t=vn(n);return null!==t&&L(e).includes(t)},"the first operand does mention the second"),pn("sameAs",(...e)=>e.every(n=>n.s===e[0].s),"these operands are structurally identical"),pn("differs",(...e)=>new Set(e.map(e=>e.s)).size===e.length,"these operands are all different"),pn("sameValue",(...e)=>e.every(e=>mn(e))&&e.every(n=>n.value===e[0].value),"these operands are the same number");const yn="simplify";class wn extends Error{constructor(e,n){super(n?`rule "${n}": ${e}`:e),this.name="RuleError",this.ruleId=n}}const xn=/^[A-Za-z_][A-Za-z0-9_]*$/;function qn(e,n){if(F(e))return{literal:e.value};const t=e.token;if(t.startsWith("=")){const e=t.slice(1);if(""===e)throw new wn('"=" needs an operand after it',n);return{token:e}}if(!xn.test(t))throw new wn(`"${t}" is not a usable slot name; use letters, digits and _`,n);if(S(t))throw new wn(`slot name "${t}" collides with an operator`,n);return{name:t}}function kn(e){if(!V(e))return[e];const n=e.args.map(kn),t=$(e.op),r=[];for(const s of function(e){let n=[[]];for(const t of e){const e=[];for(const r of n)for(const n of t)e.push(r.concat([n]));if(n=e,n.length>64)return n.slice(0,64)}return n}(n))if(r.push(C(e.op,s)),t.commutative&&2===s.length&&s[0].s!==s[1].s&&r.push(C(e.op,[s[1],s[0]])),r.length>=64)break;return r}function $n(e,n=[]){return"op"===e.kind?e.args.forEach(e=>$n(e,n)):"const"===e.kind&&e.free&&n.push(e.node.token),n}function Sn(e){if(!e||"object"!=typeof e)throw new wn("rule must be a mapping");const n=e.id||e.name;if(!n)throw new wn("rule needs an id");if(!e.pattern)throw new wn("rule needs a pattern",n);if(void 0===e.output||null===e.output)throw new wn("rule needs an output",n);let t;try{t=R(String(e.pattern))}catch(e){if(e instanceof T)throw new wn(`bad pattern: ${e.message}`,n);throw e}const r=an(t).map(e=>qn(e,n)),s=new Set(r.filter(e=>e.name).map(e=>e.name)),o=function(e,n,t){const r=[],s=e.when||{};if("object"!=typeof s||Array.isArray(s))throw new wn('"when" must map slot names to lists of requirements',t);for(const[e,o]of Object.entries(s)){if(!n.has(e))throw new wn(`"when" mentions "${e}", which is not a slot in the pattern`,t);const s=Array.isArray(o)?o:[o];for(const n of s){const{name:s,args:o}=bn(n),i=dn(s);if(!i)throw new wn(`unknown requirement "${s}"`,t);r.push({slot:e,name:s,args:o,fn:i.fn})}}return r}(e,s,n),i=function(e,n,t){const r=[],s=e.require||[];if(!Array.isArray(s))throw new wn('"require" must be a list of relations',t);for(const e of s){const{name:s,args:o}=bn(e),i=hn(s);if(!i)throw new wn(`unknown relation "${s}"`,t);if(o.length<2)throw new wn(`relation "${s}" needs at least two operands`,t);for(const e of o)if("string"==typeof e&&!n.has(e)&&xn.test(e))throw new wn(`relation "${s}" mentions "${e}", which is not a slot in the pattern`,t);r.push({name:s,args:o,fn:i.fn})}return r}(e,s,n),a=function(e,n,t){let r;try{r=R(e)}catch(n){throw new wn(`bad output "${e}": ${n.message}`,t)}const s=e=>V(e)?{kind:"op",op:e.op,args:e.args.map(s)}:F(e)?{kind:"const",node:e}:n.has(e.token)?{kind:"slot",name:e.token}:e.token.startsWith("=")?{kind:"const",node:Z(e.token.slice(1))}:{kind:"const",node:e,free:!0};return s(r)}(String(e.output),s,n),u=e.commutative?kn(t):[t],l=[],c=new Set;for(const e of u){const t=on(e),r=an(e).map(e=>qn(e,n)),s=t+"\0"+r.map(e=>e.name??(void 0!==e.literal?`#${e.literal}`:`=${e.token}`)).join(",");c.has(s)||(c.add(s),l.push({key:t,slots:r}))}const f={id:String(n),name:e.name?String(e.name):String(n),pattern:String(e.pattern),patternTree:t,output:String(e.output),outputTemplate:a,explain:e.explain?String(e.explain).trim():"",mode:e.mode?String(e.mode):yn,tags:Array.isArray(e.tags)?e.tags.map(String):[],priority:Number.isFinite(e.priority)?e.priority:0,fold:!!e.fold,commutative:!!e.commutative,enabled:void 0===e.enabled||!!e.enabled,when:o,require:i,slots:[...s],depth:P(t),bindings:l,freeSymbols:$n(a),source:e};for(const e of l)e.rule=f;return f}function On(e){const n={};for(const t of e.when)(n[t.slot]||=[]).push(t.args.length?[t.name,...t.args]:t.name);const t={id:e.id};return e.name!==e.id&&(t.name=e.name),e.mode!==yn&&(t.mode=e.mode),t.pattern=e.pattern,Object.keys(n).length&&(t.when=n),e.require.length&&(t.require=e.require.map(e=>[e.name,...e.args])),t.output=e.output,e.explain&&(t.explain=e.explain),e.fold&&(t.fold=!0),e.commutative&&(t.commutative=!0),e.priority&&(t.priority=e.priority),e.tags.length&&(t.tags=e.tags),e.enabled||(t.enabled=!1),t}class Nn extends Error{constructor(e,n){super(null==n?e:`${e} (line ${n+1})`),this.name="YamlError",this.line=n}}class An{constructor(e){this.records=e,this.i=0,this.pushed=[]}peek(){if(this.pushed.length)return this.pushed[this.pushed.length-1];for(;this.i<this.records.length&&this.records[this.i].blank;)this.i++;return this.i<this.records.length?this.records[this.i]:null}next(){if(this.pushed.length)return this.pushed.pop();const e=this.peek();return e&&this.i++,e}push(e){this.pushed.push(e)}}const In=e=>"-"===e||e.startsWith("- ");function Mn(e){let n=null,t=0;for(let r=0;r<e.length;r++){const s=e[r];if(n)s===n?"'"===n&&"'"===e[r+1]?r++:n=null:'"'===n&&"\\"===s&&r++;else if('"'===s||"'"===s)n=s;else if("["===s||"{"===s)t++;else if("]"===s||"}"===s)t--;else if(":"===s&&0===t&&(r+1===e.length||" "===e[r+1])){const n=e.slice(0,r).trim();return""===n?null:{key:En(n),rest:e.slice(r+1).trim()}}}return null}function En(e){return e.length>=2&&'"'===e[0]&&'"'===e[e.length-1]?JSON.parse(e):e.length>=2&&"'"===e[0]&&"'"===e[e.length-1]?e.slice(1,-1).replace(/''/g,"'"):e}function Tn(e){const n=new An(function(e){return String(e).split(/\r?\n/).map((e,n)=>{const t=e.search(/\S/);if(-1===t)return{raw:e,n:n,indent:0,text:"",blank:!0};const r=function(e){let n=null;for(let t=0;t<e.length;t++){const r=e[t];if(n)r===n?"'"===n&&"'"===e[t+1]?t++:n=null:'"'===n&&"\\"===r&&t++;else if('"'===r||"'"===r)n=r;else if("#"===r&&(0===t||/\s/.test(e[t-1])))return e.slice(0,t)}return e}(e.slice(t)).trimEnd();return{raw:e,n:n,indent:t,text:r,blank:""===r}})}(e));let t=n.peek();if(t&&"---"===t.text&&(n.next(),t=n.peek()),!t)return null;const r=Zn(n,t.indent),s=n.peek();if(s&&"..."!==s.text&&"---"!==s.text)throw new Nn(`unexpected content "${s.text}"`,s.n);return r}const jn=/^[|>][-+]?\d*$/;function Zn(e,n){const t=e.peek();return!t||t.indent<n?null:In(t.text)?zn(e,t.indent):Mn(t.text)?function(e,n){const t={};for(;;){const r=e.peek();if(!r||r.indent!==n)break;const s=Mn(r.text);if(!s)break;e.next();const{key:o,rest:i}=s;if(""===i){const r=e.peek();r&&r.indent>n?t[o]=Zn(e,r.indent):r&&r.indent===n&&In(r.text)?t[o]=zn(e,n):t[o]=null}else jn.test(i)?t[o]=Dn(e,i,n):t[o]=Bn(i,r.n)}return t}(e,t.indent):(e.next(),jn.test(t.text)?Dn(e,t.text,t.indent-1):Bn(t.text,t.n))}function zn(e,n){const t=[];for(;;){const r=e.peek();if(!r||r.indent!==n||!In(r.text))break;if(e.next(),"-"===r.text){const r=e.peek();t.push(r&&r.indent>n?Zn(e,r.indent):null);continue}if(jn.test(r.text.slice(2).trim())){t.push(Dn(e,r.text.slice(2).trim(),n));continue}const s=r.text.slice(2),o=n+2+(s.length-s.trimStart().length);e.push({raw:r.raw,n:r.n,indent:o,text:s.trim(),blank:!1}),t.push(Zn(e,o))}return t}function Dn(e,n,t){const r=n[0],s=(n.match(/[-+]/)||[""])[0],o=(n.match(/\d+/)||[null])[0];let i=o?t+Number(o):null;const a=[];for(;e.i<e.records.length;){const n=e.records[e.i];if(""===n.raw.trim()){a.push(""),e.i++;continue}const r=n.raw.search(/\S/);if(r<=t)break;if(null===i&&(i=r),r<i)break;a.push(n.raw.slice(i)),e.i++}for(;a.length&&""===a[a.length-1];)a.pop();let u;if("|"===r)u=a.join("\n");else{const e=[];for(const n of a)""===n?e.push("\n"):e.length&&"\n"!==e[e.length-1]?e[e.length-1]+=" "+n:e.push(n);u=e.join("").replace(/\n(?!$)/g,"\n")}return"-"===s?u:"+"===s?u+"\n":""===u?"":u+"\n"}function Bn(e,n){const t=e.trim();return""===t||"~"===t||"null"===t||"Null"===t||"NULL"===t?null:"true"===t||"True"===t||"TRUE"===t||"false"!==t&&"False"!==t&&"FALSE"!==t&&("["===t[0]||"{"===t[0]?function(e,n){const t={text:e,i:0,line:n},r=Fn(t);if(Cn(t),t.i<t.text.length)throw new Nn(`unexpected "${t.text.slice(t.i)}" in flow value`,n);return r}(t,n):'"'===t[0]||"'"===t[0]?En(t):/^[-+]?(\d+\.?\d*|\.\d+)([eE][-+]?\d+)?$/.test(t)?Number(t):t)}const Cn=e=>{for(;e.i<e.text.length&&/\s/.test(e.text[e.i]);)e.i++};function Fn(e){Cn(e);const n=e.text[e.i];return"["===n?function(e){e.i++;const n=[];for(;;){if(Cn(e),e.i>=e.text.length)throw new Nn("unterminated [",e.line);if("]"===e.text[e.i])return e.i++,n;if(n.push(Fn(e)),Cn(e),","===e.text[e.i])e.i++;else if("]"!==e.text[e.i])throw new Nn(`expected , or ] near "${e.text.slice(e.i)}"`,e.line)}}(e):"{"===n?function(e){e.i++;const n={};for(;;){if(Cn(e),e.i>=e.text.length)throw new Nn("unterminated {",e.line);if("}"===e.text[e.i])return e.i++,n;const t=String(Fn(e));if(Cn(e),":"!==e.text[e.i])throw new Nn(`expected : after "${t}"`,e.line);if(e.i++,n[t]=Fn(e),Cn(e),","===e.text[e.i])e.i++;else if("}"!==e.text[e.i])throw new Nn(`expected , or } near "${e.text.slice(e.i)}"`,e.line)}}(e):Bn(function(e){const n=e.text[e.i];if('"'===n||"'"===n){const t=e.i;for(e.i++;e.i<e.text.length;)if("\\"===e.text[e.i]&&'"'===n)e.i+=2;else if(e.text[e.i]===n){if("'"!==n||"'"!==e.text[e.i+1])return e.i++,e.text.slice(t,e.i);e.i+=2}else e.i++;throw new Nn("unterminated quoted string",e.line)}const t=e.i;for(;e.i<e.text.length;){const n=e.text[e.i];if(","===n||"]"===n||"}"===n)break;if(":"===n){const n=e.text[e.i+1];if(void 0===n||/[\s,\]}]/.test(n))break}e.i++}return e.text.slice(t,e.i).trim()}(e),e.line)}const Vn=/^(true|false|null|yes|no|on|off|~)$/i;function Rn(e){if(null==e)return"null";if("boolean"==typeof e)return e?"true":"false";if("number"==typeof e){if(!Number.isFinite(e))throw new Nn(`cannot serialise ${e}`);return String(e)}const n=String(e);return function(e){return!!(""===e||/^\s|\s$/.test(e)||/[\u0000-\u001f\u007f]/.test(e)||/^[-?:,[\]{}#&*!|>'"%@`]/.test(e)||/: |\s#/.test(e)||Vn.test(e)||/^[-+]?(\d+\.?\d*|\.\d+)([eE][-+]?\d+)?$/.test(e))}(n)?JSON.stringify(n):n}const Un=e=>null==e||"object"!=typeof e;function Pn(e){return Array.isArray(e)?`[${e.map(Pn).join(", ")}]`:e&&"object"==typeof e?`{${Object.entries(e).map(([e,n])=>`${Rn(e)}: ${Pn(n)}`).join(", ")}}`:Rn(e)}function Wn(e){return Array.isArray(e)?!!e.every(e=>Un(e)||Array.isArray(e)&&e.every(Un))&&Pn(e).length<=72:!(!e||"object"!=typeof e)&&(Object.values(e).every(e=>Un(e)||Array.isArray(e)&&e.every(Un))&&Pn(e).length<=72)}function Ln(e){const n=[];return _n(e,0,n),n.length?n.join("\n")+"\n":""}function _n(e,n,t){const r=" ".repeat(n);if(Array.isArray(e)){if(0===e.length)return void t.push(r+"[]");for(const r of e)Hn(r,n,t)}else{if(e&&"object"==typeof e){const s=Object.entries(e).filter(([,e])=>void 0!==e);if(0===s.length)return void t.push(r+"{}");for(const[e,r]of s)Jn(e,r,n,t);return}!function(e,n,t){if("string"==typeof e&&e.includes("\n")){t.push(n+"|-");for(const r of e.replace(/\n+$/,"").split("\n"))t.push(n+" "+r);return}t.push(n+Rn(e))}(e,r,t)}}function Hn(e,n,t){const r=" ".repeat(n);if(null!==e&&"object"==typeof e&&!Wn(e)){const s=[];if(_n(e,n+2,s),0===s.length)return void t.push(r+"-");t.push(r+"- "+s[0].slice(n+2));for(let e=1;e<s.length;e++)t.push(s[e]);return}if(null===e||"object"!=typeof e)if("string"==typeof e&&e.includes("\n")){t.push(r+"- |-");for(const r of e.replace(/\n+$/,"").split("\n"))t.push(" ".repeat(n+4)+r)}else t.push(r+"- "+Rn(e));else t.push(r+"- "+Pn(e))}function Jn(e,n,t,r){const s=" ".repeat(t),o=Rn(e);if("string"==typeof n&&n.includes("\n")){r.push(`${s}${o}: |-`);for(const e of n.replace(/\n+$/,"").split("\n"))r.push(" ".repeat(t+2)+e)}else{if(null!==n&&"object"==typeof n)return Wn(n)?void r.push(`${s}${o}: ${Pn(n)}`):(r.push(`${s}${o}:`),void _n(n,Array.isArray(n)?t:t+2,r));r.push(`${s}${o}: ${Rn(n)}`)}}class Qn{constructor(e=[]){this.index=new Map,this.rules=[],this.maxDepth=0,this.name="",this.views=new Map;for(const n of e)this.add(n)}add(e){const n=e&&e.bindings?e:Sn(e);if(this.rules.some(e=>e.id===n.id))throw new wn(`duplicate rule id "${n.id}"`);return this.rules.push(n),n.enabled&&this.link(n),n.depth>this.maxDepth&&(this.maxDepth=n.depth),this.views.clear(),n}view(e){if(!e)return this;let n=this.views.get(e);return n||(n=new Qn(this.rules.filter(n=>n.mode===e)),n.name=this.name,this.views.set(e,n)),n}modes(){return[...new Set(this.rules.map(e=>e.mode))].sort((e,n)=>e===yn?-1:n===yn?1:e.localeCompare(n))}link(e){for(const n of e.bindings){let e=this.index.get(n.key);e||this.index.set(n.key,e=[]),e.push(n),e.sort((e,n)=>n.rule.priority-e.rule.priority||n.rule.depth-e.rule.depth)}}remove(e){const n=this.rules.findIndex(n=>n.id===e);return-1!==n&&(this.rules.splice(n,1),this.reindex(),!0)}setEnabled(e,n){const t=this.get(e);return!!t&&(t.enabled=!!n,this.reindex(),!0)}reindex(){this.index=new Map,this.maxDepth=0,this.views.clear();for(const e of this.rules)e.enabled&&this.link(e),e.depth>this.maxDepth&&(this.maxDepth=e.depth)}get(e){return this.rules.find(n=>n.id===e)||null}candidates(e){return this.index.get(e)||null}get size(){return this.rules.length}static fromYaml(e,{strict:n=!0}={}){const t=Tn(e);return Qn.fromSpecs(t,{strict:n})}static fromSpecs(e,{strict:n=!0}={}){let t=e,r="";if(e&&!Array.isArray(e)&&"object"==typeof e&&(t=e.rules,r=e.name?String(e.name):""),!Array.isArray(t))throw new wn('expected a list of rules, or a mapping with a "rules" list');const s=new Qn;s.name=r;const o=[];for(let e=0;e<t.length;e++)try{s.add(t[e])}catch(n){o.push(`#${e+1}: ${n.message}`)}if(o.length&&n)throw new wn(`${o.length} rule(s) failed to compile:\n ${o.join("\n ")}`);return s.errors=o,s}toSpecs(){return this.rules.map(On)}toYaml(){const e=this.toSpecs();return this.name?Ln({name:this.name,rules:e}):Ln(e)}keyReport(){return[...this.index.entries()].map(([e,n])=>({key:e,rules:n.map(e=>e.rule.id)})).sort((e,n)=>e.key.localeCompare(n.key))}}function Yn(e,n){const t=Object.create(null),r=e.slots;for(let e=0;e<r.length;e++){const s=r[e],o=n[e];if(void 0!==s.literal){if(!F(o)||o.value!==s.literal)return null;continue}if(void 0!==s.token){if(o.s!==s.token)return null;continue}const i=t[s.name];if(void 0!==i){if(i.s!==o.s)return null}else t[s.name]=o}return t}function Gn(e,n){for(const t of e.when){const e=n[t.slot];if(void 0===e)return!1;if(!t.fn(e,...t.args))return!1}for(const t of e.require){const e=t.args.map(e=>void 0!==n[e]?n[e]:e);if(!t.fn(...e))return!1}return!0}function Kn(e,n){return n.rule.priority-e.rule.priority||n.rule.depth-e.rule.depth}function Xn(e,n){const t=[];if(0===n.maxDepth)return t;for(const{key:r,slots:s}of function(e,n){const t=sn(e,n),r=[];for(const e of t)e.key!==nn&&r.push(e);return r}(e,n.maxDepth)){const e=n.candidates(r);if(e)for(const n of e){const e=Yn(n,s);e&&(Gn(n.rule,e)&&t.push({rule:n.rule,binding:n,key:r,bound:e}))}}return t.sort(Kn)}function et(e,n){switch(e.kind){case"slot":{const t=n[e.name];if(!t)throw new Error(`output references unbound slot "${e.name}"`);return t}case"const":return e.node;case"op":return C(e.op,e.args.map(e=>et(e,n)));default:throw new Error(`bad output template: ${JSON.stringify(e)}`)}}const nt=4e5,tt=()=>new Q("a number too large to approximate"),rt=e=>e<0n?-e:e;class st{constructor(e){this.P=e,this.S=10n**BigInt(e),this.cache=new Map}fromQ(e){return e.n*this.S/e.d}mul(e,n){return e*n/this.S}div(e,n){if(0n===n)throw new Q("division by zero");return e*this.S/n}sqrt(e){if(e<0n)throw new Q("the square root of a negative number is not real");return te(e*this.S,2)}series(e,n){let t=0n,r=e;for(let e=1;0n!==r;e++)if(t+=r,r=n(r,e),e>1e5)throw new Q("a series did not converge");return t}atanhInv(e){const n=BigInt(e),t=n*n;let r=this.S/n,s=0n;for(let e=1n;0n!==r;e+=2n)s+=r/e,r/=t;return s}atanInv(e){const n=BigInt(e),t=n*n;let r=this.S/n,s=0n;for(let e=1n,n=1n;0n!==r;e+=2n,n=-n)s+=n*r/e,r/=t;return s}get pi(){return this.memo("pi",()=>16n*this.atanInv(5)-4n*this.atanInv(239))}get ln2(){return this.memo("ln2",()=>2n*this.atanhInv(3))}get e(){return this.memo("e",()=>this.exp(this.S))}memo(e,n){return this.cache.has(e)||this.cache.set(e,n()),this.cache.get(e)}exp(e){const n=(e+(e>=0n?this.ln2/2n:-this.ln2/2n))/this.ln2;if(n>BigInt(nt))throw tt();if(n<-BigInt(nt))return 0n;const t=e-n*this.ln2,r=this.series(this.S,(e,n)=>e*t/this.S/BigInt(n));return n>=0n?r<<n:r>>-n}ln(e){if(e<=0n)throw new Q("the log of a number that is not positive is not real");let n=0n,t=e;for(;t>=this.S;)t>>=1n,n++;for(;t<this.S/2n;)t<<=1n,n--;const r=this.div(t-this.S,t+this.S),s=this.mul(r,r);let o=r,i=0n;for(let e=1n;0n!==o;e+=2n)i+=o/e,o=this.mul(o,s);return 2n*i+n*this.ln2}sin(e){const n=2n*this.pi;let t=e%n;t>this.pi&&(t-=n),t<-this.pi&&(t+=n);const r=this.mul(t,t);return this.series(t,(e,n)=>-e*r/this.S/BigInt(2*n*(2*n+1)))}cos(e){return this.sin(e+this.pi/2n)}atan(e){if(rt(e)>this.S){const n=this.pi/2n;return(e>0n?n:-n)-this.atan(this.div(this.S,e))}let n=e;for(let e=0;e<2;e++)n=this.div(n,this.S+this.sqrt(this.S+this.mul(n,n)));const t=this.mul(n,n);let r=n,s=0n;for(let e=1n,n=1n;0n!==r;e+=2n,n=-n)s+=n*r/e,r=this.mul(r,t);return 4n*s}asin(e){if(rt(e)>this.S)throw new Q("arcsin of a number beyond ±1 is not real");return rt(e)===this.S?e>0n?this.pi/2n:-this.pi/2n:this.atan(this.div(e,this.sqrt(this.S-this.mul(e,e))))}}function ot(e,n,t){if(t>0n)return e.atan(e.div(n,t));if(t<0n)return e.atan(e.div(n,t))+(n>=0n?e.pi:-e.pi);if(0n===n)throw new Q("the argument of 0 is undefined");return n>0n?e.pi/2n:-e.pi/2n}const it={add:(e,n)=>[e[0]+n[0],e[1]+n[1]],sub:(e,n)=>[e[0]-n[0],e[1]-n[1]],mul:(e,n,t)=>[e.mul(n[0],t[0])-e.mul(n[1],t[1]),e.mul(n[0],t[1])+e.mul(n[1],t[0])],div(e,n,t){const r=e.mul(t[0],t[0])+e.mul(t[1],t[1]);if(0n===r)throw new Q("division by zero");return[e.div(e.mul(n[0],t[0])+e.mul(n[1],t[1]),r),e.div(e.mul(n[1],t[0])-e.mul(n[0],t[1]),r)]},abs:(e,n)=>e.sqrt(e.mul(n[0],n[0])+e.mul(n[1],n[1])),exp(e,n){const t=e.exp(n[0]);return[e.mul(t,e.cos(n[1])),e.mul(t,e.sin(n[1]))]},ln(e,n){const t=it.abs(e,n);if(0n===t)throw new Q("the log of 0 is undefined");return[e.ln(t),ot(e,n[1],n[0])]},pow(e,n,t,r){if(0n===n[0]&&0n===n[1])return[0n,0n];if(r&&r.isInteger){let t=r.n<0n?-r.n:r.n,s=[e.S,0n],o=n;for(;t>0n;)1n&t&&(s=it.mul(e,s,o)),o=it.mul(e,o,o),t>>=1n;return r.n<0n?it.div(e,[e.S,0n],s):s}return it.exp(e,it.mul(e,t,it.ln(e,n)))},sinh:(e,n)=>(e.exp(n)-e.exp(-n))/2n,cosh:(e,n)=>(e.exp(n)+e.exp(-n))/2n},at={sin:(e,[n,t])=>[e.mul(e.sin(n),it.cosh(e,t)),e.mul(e.cos(n),it.sinh(e,t))],cos:(e,[n,t])=>[e.mul(e.cos(n),it.cosh(e,t)),-e.mul(e.sin(n),it.sinh(e,t))],tan:(e,n)=>it.div(e,at.sin(e,n),at.cos(e,n)),ln:(e,n)=>it.ln(e,n),sqrt:(e,n)=>it.exp(e,it.mul(e,[e.S/2n,0n],it.ln(e,n))),sinh:(e,[n,t])=>[e.mul(it.sinh(e,n),e.cos(t)),e.mul(it.cosh(e,n),e.sin(t))],cosh:(e,[n,t])=>[e.mul(it.cosh(e,n),e.cos(t)),e.mul(it.sinh(e,n),e.sin(t))]},ut=e=>({q:e}),lt=([e,n])=>0n===n?{f:e}:{z:[e,n]};function ct(e,n,t){const r=e=>((e,n)=>n.z??[ft(e,n),0n])(t,n[e]);switch(e.op){case"+":return lt(it.add(r(0),r(1)));case"-":return lt(it.sub(r(0),r(1)));case"neg":return lt([-r(0)[0],-r(0)[1]]);case"*":return lt(it.mul(t,r(0),r(1)));case"/":return lt(it.div(t,r(0),r(1)));case"^":return lt(it.pow(t,r(0),r(1),n[1].q));case"sqrt":return lt(at.sqrt(t,r(0)));case"root":return lt(it.pow(t,r(1),it.div(t,[t.S,0n],r(0)),n[0].q?.inv()));case"abs":return{f:it.abs(t,r(0))};case"arg":return{f:ot(t,r(0)[1],r(0)[0])};case"re":return{f:r(0)[0]};case"im":return{f:r(0)[1]};case"conj":return lt([r(0)[0],-r(0)[1]]);case"log":return lt(it.div(t,it.ln(t,r(1)),it.ln(t,r(0))));default:{const s=at[e.op];if(!s||1!==n.length)throw new Q(`no complex value for ${e.op}`);return lt(s(t,r(0)))}}}function ft(e,n){return n.q?e.fromQ(n.q):n.f}const pt={sin:(e,n)=>e.sin(n),cos:(e,n)=>e.cos(n),tan:(e,n)=>e.div(e.sin(n),e.cos(n)),sec:(e,n)=>e.div(e.S,e.cos(n)),csc:(e,n)=>e.div(e.S,e.sin(n)),cot:(e,n)=>e.div(e.cos(n),e.sin(n)),arcsin:(e,n)=>e.asin(n),arccos:(e,n)=>e.pi/2n-e.asin(n),arctan:(e,n)=>e.atan(n),sinh:(e,n)=>(e.exp(n)-e.exp(-n))/2n,cosh:(e,n)=>(e.exp(n)+e.exp(-n))/2n,tanh:(e,n)=>{const t=e.exp(n),r=e.exp(-n);return e.div(t-r,t+r)},arcsinh:(e,n)=>e.ln(n+e.sqrt(e.mul(n,n)+e.S)),arccosh:(e,n)=>{if(n<e.S)throw new Q("arccosh of a number below 1 is not real");return e.ln(n+e.sqrt(e.mul(n,n)-e.S))},arctanh:(e,n)=>{if(rt(n)>=e.S)throw new Q("arctanh of a number beyond ±1 is not real");return e.ln(e.div(e.S+n,e.S-n))/2n},ln:(e,n)=>e.ln(n),loglog:(e,n)=>e.ln(e.ln(n)),logloglog:(e,n)=>e.ln(e.ln(e.ln(n))),expm1:(e,n)=>e.exp(n)-e.S};function dt(e,n,t){if("num"===e.type)return ut(ne(e.token));if("sym"===e.type){if("pi"===e.token||"π"===e.token)return{f:n.pi};if("e"===e.token)return{f:n.e};if("i"===e.token&&ie.complex)return{z:[0n,n.S]};if(t&&e.token in t){const n=t[e.token],r="number"==typeof n||"string"==typeof n||"bigint"==typeof n?ne(String(n)):null;if(!r)throw new Q(`the value of ${e.token} is not a number`);return ut(r)}throw new Q(`${e.token} has no value`)}ie.complex&&e.op.startsWith("\\:")&&Be[e.op.slice(2)]&&(e=C(Be[e.op.slice(2)],e.args));const r=e.args.map(e=>dt(e,n,t));if(r.some(e=>e.z)||["re","im","conj","arg"].includes(e.op)||function(e,n){if(!ie.complex)return!1;const t=e=>e.q?e.q.sign<0:void 0!==e.f&&e.f<0n;return"sqrt"===e.op||"ln"===e.op||"log"===e.op?t(n["log"===e.op?1:0])||"log"===e.op&&t(n[0]):"^"===e.op?t(n[0])&&!(n[1].q&&n[1].q.d%2n==1n):"root"===e.op&&t(n[1])&&!(n[0].q&&n[0].q.isInteger&&n[0].q.n%2n==1n)}(e,r))return ct(e,r,n);const s=r.every(e=>e.q),o=e=>ft(n,r[e]);switch(e.op){case"+":return s?ut(r[0].q.add(r[1].q)):{f:o(0)+o(1)};case"-":return s?ut(r[0].q.sub(r[1].q)):{f:o(0)-o(1)};case"neg":return r[0].q?ut(r[0].q.neg()):{f:-r[0].f};case"*":return s?ut(r[0].q.mul(r[1].q)):{f:n.mul(o(0),o(1))};case"/":return s?ut(r[0].q.div(r[1].q)):{f:n.div(o(0),o(1))};case"^":return mt(n,r[0],r[1]);case"sqrt":return mt(n,r[0],ut(ee.HALF));case"root":return mt(n,r[1],r[0].q?ut(r[0].q.inv()):{f:n.div(n.S,r[0].f)});case"abs":return r[0].q?ut(r[0].q.abs()):{f:rt(r[0].f)};case"floor":return ut(r[0].q?r[0].q.floor():new ee(ht(r[0].f,n.S)));case"ceil":return ut(r[0].q?r[0].q.ceil():new ee(-ht(-r[0].f,n.S)));case"log":return{f:n.div(n.ln(o(1)),n.ln(o(0)))};case"atan2":return{f:ot(n,o(0),o(1))};case"max":case"min":if(!r.length)throw new Q(`${e.op} of nothing`);return s?ut(r.map(e=>e.q).reduce((n,t)=>("max"===e.op?t.sub(n).sign>0:t.sub(n).sign<0)?t:n)):{f:r.map((e,n)=>o(n)).reduce((n,t)=>"max"===e.op?t>n?t:n:t<n?t:n)};case"sum":return s?ut(r.reduce((e,n)=>e.add(n.q),ee.ZERO)):{f:r.reduce((e,n,t)=>e+o(t),0n)};case"prod":return s?ut(r.reduce((e,n)=>e.mul(n.q),ee.ONE)):{f:r.reduce((e,t,r)=>n.mul(e,o(r)),n.S)};case"mean":if(!r.length)throw new Q("mean of nothing");return s?ut(r.reduce((e,n)=>e.add(n.q),ee.ZERO).div(new ee(BigInt(r.length)))):{f:r.reduce((e,n,t)=>e+o(t),0n)/BigInt(r.length)};case"mod":{if(s){if(r[1].q.isZero)throw new Q("mod 0 is undefined");return ut(r[0].q.sub(r[1].q.mul(r[0].q.div(r[1].q).floor())))}const e=o(1);if(0n===e)throw new Q("mod 0 is undefined");return{f:o(0)-n.mul(e,ht(n.div(o(0),e),n.S)*n.S)}}case"round":{if(!r[1].q?.isInteger)throw new Q("round needs a whole number of places");const e=10n**rt(r[1].q.n),t=r[0].q??new ee(o(0),n.S),s=r[1].q.sign>=0,i=(s?t.mul(new ee(e)):t.div(new ee(e))).add(ee.HALF).floor();return ut(s?i.div(new ee(e)):i.mul(new ee(e)))}case"!":{if(!r[0].q?.isInteger||r[0].q.sign<0)throw new Q("factorial is only worked out for whole numbers");let e=1n;for(let n=2n;n<=r[0].q.n;n++)if(e*=n,0n==(255n&n)&&K(e)>nt)throw tt();return ut(new ee(e))}default:{const t=pt[e.op];if(!t||1!==r.length)throw new Q(`no numeric value for ${e.op}`);return{f:t(n,o(0))}}}}const ht=(e,n)=>{const t=e/n;return e<0n&&t*n!==e?t-1n:t};function mt(e,n,t){if(t.q&&t.q.isInteger){if(n.q)return ut(n.q.pow(t.q.n));let r=t.q.n;const s=r<0n;s&&(r=-r);let o=e.S,i=n.f;for(;r>0n;){if(1n&r&&(o=e.mul(o,i)),i=e.mul(i,i),K(o)>nt+4*e.P||K(i)>8e5){if(s)return{f:0n};throw tt()}r>>=1n}return{f:s?e.div(e.S,o):o}}const r=ft(e,n);if(0n===r){if(t.q?t.q.sign>0:t.f>0n)return ut(ee.ZERO);throw new Q("0 to a power that is not positive is undefined")}if(r<0n){if(t.q&&t.q.d%2n==1n){const n=mt(e,{f:-r},t).f;return{f:t.q.n%2n==0n?n:-n}}throw new Q("a negative number to a fractional power is not real")}if(t.q&&1n===rt(t.q.n)&&t.q.d<=64n){const n=te(r*e.S**(t.q.d-1n),Number(t.q.d));return{f:t.q.n<0n?e.div(e.S,n):n}}return{f:e.exp(e.mul(ft(e,t),e.ln(r)))}}function gt(e,n,t){const r=e<0n?"-":"",s=rt(e);if(0n===s)return{sign:"",digits:"0",point:1};const o=s.toString(),i=o.length-n.P;let a=o.slice(0,t);o.length>t&&o[t]>="5"&&(a=(BigInt(a)+1n).toString());let u=i;return a.length>t&&(a=a.slice(0,t),u++),{sign:r,digits:a.replace(/0+$/,"")||"0",point:u}}function vt({sign:e,digits:n,point:t}){if("0"===n)return"0";if(t>21||t<-6){return`${e}${n.length>1?`${n[0]}.${n.slice(1)}`:n}e${t-1}`}return t<=0?`${e}0.${"0".repeat(-t)}${n}`:t>=n.length?`${e}${n}${"0".repeat(t-n.length)}`:`${e}${n.slice(0,t)}.${n.slice(t)}`}function bt(e){let n=0n,t=0n,r=e.d;for(;r%2n==0n;)r/=2n,n++;for(;r%5n==0n;)r/=5n,t++;const s=n>t?n:t;let o=rt(e.n)*10n**s/e.d;if(0n===o)return 1;for(;o%10n==0n;)o/=10n;return o.toString().length}function yt(e){let n=e.d;for(;n%2n==0n;)n/=2n;for(;n%5n==0n;)n/=5n;return 1n===n}function wt(e){const n=/^(-?[\d.]+)e(-?\d+)$/.exec(e);return n?C("*",[z(n[1]),C("^",[z("10"),z(n[2])])]):z(e)}function xt(e,{digits:n=15,scope:t}={}){if(!Number.isInteger(n)||n<1||n>1e5)throw new Q("digits must be a whole number from 1 to 100000");let r=n+25,s=null;for(let o=0;o<4;o++){const i=new st(r),a=dt(e,i,t);if(a.z){const e=kt(a.z,i,n);if(e.retry&&o<3){r+=e.retry;continue}return void 0===e.real?e:qt(e.real,i,n,null)}if(a.q&&a.q.isInteger&&rt(a.q.n).toString().length<=n)return{text:a.q.n.toString(),node:z(a.q.n.toString()),number:Number(a.q.n),re:Number(a.q.n),im:0,exact:!0};const u=ft(i,a);if(0n===u&&(!a.q||!a.q.isZero)&&o<3){s=null,r*=4;continue}const l=gt(u,i,n);if(s&&l.point<-10&&s.point-l.point>=(r-s.P)/2)return{text:"0",node:z("0"),number:0,re:0,im:0,exact:!1};if(!(l.point<-10&&o<3)||s&&s.point===l.point)return qt(u,i,n,a.q);s={point:l.point,P:r},r+=10-l.point}throw new Q("could not approximate")}function qt(e,n,t,r){const s=vt(gt(e,n,t));return{text:s,node:wt(s),number:Number(s),re:Number(s),im:0,exact:Boolean(r)&&yt(r)&&bt(r)<=t}}function kt([e,n],t,r){const s=10n**BigInt(Math.max(0,t.P-r-12)),o=e=>rt(e)>s;if(!o(n))return{real:e};const i=gt(n,t,r);if(i.point<-10&&o(n))return{retry:10-i.point};const a=vt(i),u="1"===a?"i":"-1"===a?"-i":`${a}i`,l="1"===a?Z("i"):C("*",[wt(a.replace(/^-/,"")),Z("i")]);if(!o(e))return{text:u,node:a.startsWith("-")?C("neg",[l]):l,number:NaN,re:0,im:Number(a),exact:!1};const c=vt(gt(e,t,r)),f=a.startsWith("-"),p="1"===a.replace(/^-/,"")?Z("i"):C("*",[wt(a.replace(/^-/,"")),Z("i")]);return{text:`${c} ${f?"-":"+"} ${u.replace(/^-/,"")}`,node:C(f?"-":"+",[wt(c),p]),number:NaN,re:Number(c),im:Number(a),exact:!1}}function $t(e,n={}){const t=e=>(e=>0===Ke(e).size)(e)?"num"===e.type&&/^-?\d+$/.test(e.token)?e:xt(e,n).node:V(e)?C(e.op,e.args.map(t)):e;return t(e)}const St={variable:null},Ot=(e,n)=>null!==n&&Ke(e).has(n);function Nt(e){if("num"===e.type)return ne(e.token);if(V(e)&&"/"===e.op&&e.args.every(e=>"num"===e.type)){const n=ne(e.args[0].token),t=ne(e.args[1].token);return n&&t&&!t.isZero?n.div(t):null}return null}const At=e=>0===Ke(e).size;function It(e,n,t){const r=function(e){const n=We(e);return"num"===n.k?n.q.isZero?n.q:null:"atom"===n.k&&"sym"===n.node.type&&"pi"===n.node.token?ne("1"):"mul"===n.k&&1===n.fs.length&&"atom"===n.fs[0].b.k&&"pi"===n.fs[0].b.node.token&&"num"===n.fs[0].e.k&&n.fs[0].e.q.isOne?n.c:null}(e);if(!r)return!1;const[s,o="1"]=String(n).split("/");return t(r.compare(ne(s).div(ne(o))))}function Mt(e){if(!At(e))return NaN;try{const{number:n}=xt(e,{digits:30});return Math.sign(n)}catch{return NaN}}function Et(){dn("hasVariable")||(fn("hasVariable",e=>Ot(e,St.variable),"mentions the variable being solved for"),fn("freeOfVariable",e=>null!==St.variable&&!Ot(e,St.variable),"does not mention the variable being solved for"),fn("isRational",e=>null!==Nt(e),"an exact number: 3, -2, 1/2"),fn("isWhole",e=>Nt(e)?.isInteger??!1,"a whole number (any size)"),fn("isEvenWhole",e=>{const n=Nt(e);return Boolean(n?.isInteger&&n.n%2n==0n)},"an even whole number"),fn("isOddWhole",e=>{const n=Nt(e);return Boolean(n?.isInteger&&n.n%2n!=0n)},"an odd whole number"),fn("isPositiveRational",e=>(Nt(e)?.sign??0)>0,"an exact number above 0"),fn("isNegativeRational",e=>(Nt(e)?.sign??0)<0,"an exact number below 0"),fn("isConstant",At,"has no unknowns (numbers, π and e only)"),fn("notOne",e=>{const n=Nt(e);return!n||!n.isOne},"anything except the number 1"),fn("notMinusOne",e=>{const n=Nt(e);return!n||!n.equals(ne("-1"))},"anything except the number -1"),fn("hasMinusSign",e=>function(e){const n=We(e);return"num"===n.k?n.q.sign<0:"mul"===n.k&&n.c.sign<0}(e),"written with a leading minus: -x, -2x, -π/6"),fn("piMultipleAtLeast",(e,n)=>It(e,n,e=>e>=0),"a multiple of π, at least k·π"),fn("piMultipleAbove",(e,n)=>It(e,n,e=>e>0),"a multiple of π, above k·π"),fn("piMultipleBelow",(e,n)=>It(e,n,e=>e<0),"a multiple of π, below k·π"),fn("piMultipleAtMost",(e,n)=>It(e,n,e=>e<=0),"a multiple of π, at most k·π"),fn("isPositiveConstant",e=>Mt(e)>0,"no unknowns, and above 0 (e, π, √2, 3)"),fn("isNegativeConstant",e=>Mt(e)<0,"no unknowns, and below 0"),fn("hasImaginaryPart",e=>{if(!ie.complex)return!1;const n=Ze(We(e));return Boolean(n)&&!("num"===n.im.k&&n.im.q.isZero)},"complex mode: has a nonzero imaginary part (unknowns count as real)"),fn("isSymbolNode",e=>"sym"===e.type&&!oe.has(e.token),"a single unknown such as x"))}function Tt(e){const n=new Map;for(const t of e){const e=t.id??t.name;if(!e)throw new Error(`a rule needs an id (pattern ${t.pattern})`);n.set(String(e),{...n.get(String(e))??{},...t})}const t=[...n.values()].map(e=>{const n={...e};try{void 0!==n.pattern&&(n.pattern=function(e){const n=R(e),t=e=>"num"===e.type||("sym"===e.type?e.token.startsWith("="):e.args.every(t)),r=e=>"sym"===e.type?Z(e.token.slice(1)):"num"===e.type?e:C(e.op,e.args.map(r)),s=e=>"sym"===e.type?Z(`=${e.token}`):"num"===e.type?e:C(e.op,e.args.map(s)),o=e=>"op"!==e.type?e:t(e)?s(Le(r(e))):C(e.op,e.args.map(o));return o(n).s}(String(n.pattern)))}catch(e){throw new Error(`rule "${n.id}": bad pattern "${n.pattern}": ${e.message}`)}return"hidden"===n.step&&(n.tags=[...n.tags??[],"hidden"]),n});return Qn.fromSpecs(t,{strict:!0})}function jt(e,n,t,r){return e.explain?e.explain.replace(/\{(\w+)\}/g,(e,s)=>"result"===s?t?r(t):e:n[s]?r(n[s]):e).trim():""}const Zt=e=>V(e)&&("+"===e.op||"-"===e.op),zt=e=>V(e)&&("*"===e.op||"/"===e.op);function*Dt(e,n,{order:t="pre"}={}){for(const r of function(e,n,{order:t="post"}={}){const r=[];for(const{node:s,path:o}of H(e,t))for(const e of Xn(s,n))r.push({...e,node:s,path:o});return r}(e,n,{order:t})){const n=et(r.rule.outputTemplate,r.bound);yield{rule:r.rule,bound:r.bound,path:r.path,before:r.node,after:n,next:()=>Le(J(e,r.path,n))}}for(const{node:r,path:s}of H(e,t)){const t=Zt(r);if(!t&&!zt(r))continue;const o=t?Xe(We(r)):en(We(r));if(o.length<3)continue;const i=t?Se:Ne;for(let t=0;t<o.length;t++)for(let r=t+1;r<o.length;r++){const a=Qe(i([o[t],o[r]]));for(const u of Xn(a,n)){const n=et(u.rule.outputTemplate,u.bound),l=o.filter((e,n)=>n!==t&&n!==r);yield{rule:u.rule,bound:u.bound,path:s,before:a,after:n,next:()=>Le(J(e,s,Qe(i([We(n),...l]))))}}}}}function Bt(e,n,{format:t,order:r="pre",maxSteps:s=200,variable:o=null}={}){const i=St.variable;St.variable=o;try{let o=Le(e);const i=new Set([o.s]),a=[];for(let e=0;e<s;e++){let e=null;for(const t of Dt(o,n,{order:r})){const n=t.next();if(n.s!==o.s&&!i.has(n.s)){e={c:t,next:n};break}}if(!e)break;const{c:s,next:u}=e;a.push({id:s.rule.id,name:s.rule.name,tags:s.rule.tags,from:o.s,to:u.s,path:s.path,before:s.before.s,after:s.after.s,explanation:jt(s.rule,s.bound,Le(s.after),t)}),o=u,i.add(o.s)}return{node:o,steps:a}}finally{St.variable=i}}const Ct={full:[],normal:["hidden"],brief:["hidden","tidy","identity","value","split","base","arithmetic"]},Ft=(e,n)=>"all"===n||"*"===n||Array.isArray(n)&&n.some(n=>n===e.id||e.tags?.includes(n));function Vt(e){if(!1===e)return null;if(void 0===e||!0===e)return{show:"all",hide:Ct.normal,explain:!0};if("string"==typeof e){if(!Ct[e])throw new Error(`steps: "${e}" is not one of ${Object.keys(Ct).join(", ")}`);return{show:"all",hide:Ct[e],explain:!0}}const n=e.detail??"normal";if(!Ct[n])throw new Error(`steps.detail: "${n}" is not one of ${Object.keys(Ct).join(", ")}`);return{show:e.show??"all",hide:[...Ct[n],...e.hide??[]],explain:e.explain??!0}}function Rt(e,n){if(!n)return[];const t=[];let r=null;for(const s of e){if(!(Ft(s,n.show)&&!Ft(s,n.hide))){r=r??{from:s.from,ids:[]},r.ids.push(s.id);continue}const e={...s};r&&(e.from=r.from,e.also=r.ids,e.path=null,r=null);!0===n.explain||!1!==n.explain&&Ft(s,n.explain)||delete e.explanation,t.push(e)}if(r&&t.length){const n=t[t.length-1];n.to=e[e.length-1].to,n.also=[...n.also??[],...r.ids]}return t}const Ut=ce(ee.ONE),Pt=(e,n)=>"atom"===e.k&&"sym"===e.node.type&&e.node.token===n;function Wt(e){switch(e.k){case"num":default:return e;case"atom":return"op"===e.node.type?Ue(e.node.op,e.node.args.map(e=>Wt(We(e)))):e;case"add":return Se(Xe(e).map(Wt));case"mul":{let n=[ce(e.c)];for(const t of e.fs){const e=Wt(t.b);if("add"===e.k&&he(t.e)&&t.e.q.isInteger&&t.e.q.sign>0&&t.e.q.n<=BigInt(60))for(let r=0n;r<t.e.q.n;r++)n=Lt(n,Xe(e));else n=Lt(n,[Ie(e,t.e)])}return Se(n)}}}function Lt(e,n){const t=[];for(const r of e)for(const e of n)t.push(Ne([r,e]));return Xe(Se(t))}function _t(e,n){const t=new Map;for(const r of Xe(Wt(e))){const{coef:e,rest:s}=$e(r);let o=0;const i=[ce(e)];for(const e of s?en(s):[]){const{b:t,e:r}="mul"===e.k&&1===e.fs.length&&e.c.isOne?e.fs[0]:{b:e,e:Ut};if(Pt(t,n)){if(!he(r)||!r.q.isInteger||r.q.sign<0)return null;o+=Number(r.q.n)}else{if(Ht(t,n)||Ht(r,n))return null;i.push(e)}}t.set(o,Se([t.get(o)??ce(ee.ZERO),Ne(i)]))}for(const[e,n]of t)he(n)&&n.q.isZero&&t.delete(e);return t}const Ht=(e,n)=>Ke(Qe(e)).has(n);function Jt(e){if(!e)return null;const n=Math.max(0,...e.keys());if(n>256)return null;const t=[];for(let r=0;r<=n;r++){const n=e.get(r)??ce(ee.ZERO);if(!he(n))return null;t.push(n.q)}return t}function Qt(e,n){const t=We(Z(n));return Se(e.map((e,n)=>Ne([ce(e),Ae(t,ce(ee.of(n)))])))}const Yt=e=>{const n=e.slice();for(;n.length>1&&n[n.length-1].isZero;)n.pop();return n},Gt=(e,n)=>e.reduceRight((e,t)=>e.mul(n).add(t),ee.ZERO);function Kt(e,n){const t=e.length-1,r=new Array(t);let s=ee.ZERO;for(let o=t;o>=1;o--)s=e[o].add(s.mul(n)),r[o-1]=s;return r}function Xt(e){if(0n===(e=(e=>e<0n?-e:e)(e)))return null;if(e>10n**14n)return null;const n=[];let t=e;for(let e=2n;e*e<=t;e+=2n===e?1n:2n){if(t%e)continue;let r=0;for(;t%e===0n;)t/=e,r++;n.push([e,r])}t>1n&&n.push([t,1]);let r=[1n];for(const[e,t]of n){const n=[];for(const s of r)for(let r=0,o=1n;r<=t;r++,o*=e)n.push(s*o);if(r=n,r.length>2e4)return null}return r.sort((e,n)=>e<n?-1:e>n?1:0)}function er(e){let n=Yt(e);const t=[];for(;n.length>1&&n[0].isZero;)t.push(ee.ZERO),n=n.slice(1);if(n.length<=1)return{roots:t,rest:n};const r=n.reduce((e,n)=>e*n.d/X(e,n.d),1n),s=n.map(e=>e.n*r/e.d),o=Xt(s[0]),i=Xt(s[s.length-1]);if(!o||!i)return{roots:t,rest:n};const a=new Map;for(const e of o)for(const n of i)for(const t of[1n,-1n]){const r=new ee(t*e,n);a.set(r.toString(),r)}const u=[...a.values()].sort((e,n)=>e.compare(n));for(const e of u)for(;n.length>1&&Gt(n,e).isZero;)t.push(e),n=Kt(n,e);return{roots:t.sort((e,n)=>e.compare(n)),rest:n}}function nr(e){if("num"===e.k)return{coef:e.q,factors:[],notes:[]};if("atom"===e.k)return{coef:ee.ONE,factors:[{base:e,exp:Ut}],notes:[]};if("mul"===e.k){let n=e.c;const t=[],r=[];for(const s of e.fs)if("add"===s.b.k&&he(s.e)&&s.e.q.isInteger){const e=nr(s.b);n=n.mul(e.coef.pow(s.e.q.n));for(const n of e.factors)t.push({base:n.base,exp:Ne([n.exp,s.e])});r.push(...e.notes)}else t.push({base:s.b,exp:s.e});return tr(n,t,r)}return function(e){const n=Xe(e),t=[],r=n.map(e=>{const{coef:n,rest:t}=$e(e);return{coef:n,fs:t?en(t).map(sr):[]}}),s=r.reduce((e,n)=>({n:X(e.n,n.coef.n),d:e.d*n.coef.d/X(e.d,n.coef.d)}),{n:0n,d:1n});let o=new ee(s.n||1n,s.d);rr(e)<0&&(o=o.neg());const i=[];for(const e of r[0].fs){if(!he(e.e)||e.e.q.sign<=0)continue;let n=e.e.q;const t=ve(e.b);let s=!0;for(const e of r.slice(1)){const r=e.fs.find(e=>ve(e.b)===t&&he(e.e)&&e.e.q.sign>0);if(!r){s=!1;break}r.e.q.compare(n)<0&&(n=r.e.q)}s&&i.push({base:e.b,exp:ce(n)})}let a=e;if(!o.isOne||i.length){const e=Ne([ce(o),...i.map(e=>Ie(e.base,e.exp))]);a=Se(n.map(n=>Ne([n,Ae(e,ce(ee.MINUS_ONE))]))),t.push({id:"factor.common",values:{common:e}})}const u="add"===a.k?function(e,n){const t=[...or(e)];for(const r of t){const s=Jt(_t(e,r));if(!s||s.length<3)continue;if(1!==t.length)break;const{roots:o,rest:i}=er(s);if(!o.length)break;const a=[];let u=i[i.length-1]??ee.ONE;const l=i.map(e=>e.div(u)),c=[...o].sort((e,n)=>e.abs().compare(n.abs())||n.sign-e.sign);for(const e of c){const t=Qt([new ee(-e.n),new ee(e.d)],r);a.push({base:t,exp:Ut}),u=u.div(new ee(e.d)),n.push({id:"factor.root",values:{root:ce(e),factor:t}})}if(l.length>1){const e=l.reduce((e,n)=>e*n.d/X(e,n.d),1n),n=l.map(n=>n.mul(new ee(e))),t=n.reduce((e,n)=>X(e,n.n),0n)||1n;u=u.mul(new ee(t,e)),a.push({base:Qt(n.map(e=>e.div(new ee(t))),r),exp:Ut})}return tr(u,a,[])}const r=Xe(e);if(2===r.length){const[e,t]=r;for(const r of[2,3]){const s=ir(e,r),o=ir(Ce(t),r),i=3===r?ir(t,r):null;if(s&&o&&2===r){n.push({id:"factor.squares",values:{a:s,b:o}});const e=nr(Se([s,Ce(o)])),t=nr(Se([s,o]));return tr(e.coef.mul(t.coef),[...e.factors,...t.factors],[...e.notes,...t.notes])}if(3===r&&s&&(o||i)){const e=o??i,t=o?-1:1;n.push({id:t<0?"factor.cubes-difference":"factor.cubes-sum",values:{a:s,b:e}});const r=Se(t<0?[s,Ce(e)]:[s,e]),a=Se([Ae(s,ce(ee.of(2))),t<0?Ne([s,e]):Ce(Ne([s,e])),Ae(e,ce(ee.of(2)))]),u=nr(r);return tr(u.coef,[...u.factors,{base:a,exp:Ut}],u.notes)}}}return{coef:ee.ONE,factors:[{base:e,exp:Ut}],notes:[]}}(a,t):nr(a);return tr(o.mul(u.coef),[...i,...u.factors],[...t,...u.notes.filter(e=>!t.includes(e))])}(e)}function tr(e,n,t){const r=new Map;for(const e of n){const n=ve(e.base),t=r.get(n);t?t.exp=Se([t.exp,e.exp]):r.set(n,{...e})}return{coef:e,factors:[...r.values()].filter(e=>!(he(e.exp)&&e.exp.q.isZero)),notes:t}}const rr=e=>$e(Xe(e)[0]).coef.sign;const sr=e=>"mul"===e.k&&e.c.isOne&&1===e.fs.length?{b:e.fs[0].b,e:e.fs[0].e}:{b:e,e:Ut},or=e=>Ke(Qe(e));function ir(e,n){const{coef:t,rest:r}=$e(e);if(t.sign<0)return null;const s=function(e,n){const t=e=>{if(e<0n)return null;let t=0n,r=1n;for(;r**BigInt(n)<=e;)r*=2n;for(;t<r-1n;){const s=(t+r)/2n;s**BigInt(n)<=e?t=s:r=s}return t**BigInt(n)===e?t:null},r=t(e.n),s=t(e.d);return null!==r&&null!==s?new ee(r,s):null}(t,n);if(!s)return null;const o=[ce(s)];for(const e of r?en(r).map(sr):[]){if(!he(e.e))return null;const t=e.e.q.div(ee.of(n));if(!t.isInteger)return null;o.push(Ie(e.b,ce(t)))}return Ne(o)}function ar({coef:e,factors:n}){const t=[],r=[];for(const e of n){const n=he(e.exp)&&e.exp.q.sign<0,s=n?ce(e.exp.q.neg()):e.exp,o=Qe(Ie(e.base,s));(n?r:t).push(o)}const s=e=>e.reduce((e,n)=>e?C("*",[e,n]):n,null),o=e.n<0n?-e.n:e.n;let i=t.length?s(1n===o?t:[Qe(ce(new ee(o))),...t]):Qe(ce(new ee(o)));return e.n<0n&&(i=C("neg",[i])),1n!==e.d&&r.unshift(Qe(ce(new ee(e.d)))),r.length?C("/",[i,s(r)]):i}function ur(e){if("mul"!==e.k)return{num:e,den:Ut};const n=[ce(new ee(e.c.n))],t=[ce(new ee(e.c.d))];for(const r of e.fs)he(r.e)&&r.e.q.sign<0?t.push(Ie(r.b,ce(r.e.q.neg()))):n.push(Ie(r.b,r.e));return{num:Ne(n),den:Ne(t)}}function lr(e){if("add"!==e.k)return ur(e);const n=Xe(e).map(ur),t=new Map;let r=1n;for(const e of n){const{coef:n,rest:s}=$e(e.den);r=r*n.n/X(r,n.n);for(const e of s?en(s).map(sr):[]){const n=ve(e.b),r=t.get(n);(!r||he(e.e)&&he(r.e)&&e.e.q.compare(r.e.q)>0)&&t.set(n,e)}}const s=Ne([ce(new ee(r)),...[...t.values()].map(e=>Ie(e.b,e.e))]);if(he(s)&&s.q.isOne)return{num:e,den:Ut};return{num:Wt(Se(n.map(e=>Ne([e.num,s,Ae(e.den,ce(ee.MINUS_ONE))])))),den:s}}function cr(e){const{num:n,den:t}=lr(e);if(he(t)&&t.q.isOne)return null;const r=nr(n),s=nr(t),o=new Set(r.factors.map(e=>ve(e.base))),i=s.factors.filter(e=>o.has(ve(e.base))),a=[...r.factors,...s.factors.map(e=>({base:e.base,exp:Ce(e.exp)}))];return{...tr(r.coef.div(s.coef),a,[...r.notes,...s.notes]),cancelled:i.map(e=>e.base)}}const fr=(e,n)=>C("=",[e,n]),pr=Le(C("+",[Z("x"),C("neg",[Z("x")])])),dr=e=>V(e)&&"="===e.op;function hr(e,n,t,r={}){const s=[],o=(n,t,r,o,i,a={})=>s.push(e.step(n,t,r,o,i,a));o.raw=e=>s.push(e);const i=dr(n)?n:fr(n,pr),a=fr(Le(i.args[0]),Le(i.args[1]));a.s!==i.s&&o("normal","Work out each side",["tidy","arithmetic"],i,a);const u=[],l=[],c=new Set;u.numeric=c,wr(e,a,t,r,o,u,l,0);const f=[],p=new Set;for(const n of u.map(n=>c.has(n)?n:(n=>Bt(n,e.set.view("simplify"),{format:e.format}).node)(n))){const e=n.s;if(p.has(e))continue;p.add(e);const r=c.has(n)?null:vr(i,t,n);r?o("solve.reject","Check the answer",["check"],fr(Z(t),n),fr(Z(t),n),{value:n,reason:r}):f.push(n)}return f.sort(mr),{solutions:f,unsolved:l,steps:s,always:l.some(e=>e.always)}}function mr(e,n){const t=gr(e),r=gr(n);return null===t||null===r?e.s<n.s?-1:1:(Math.abs(t.im)>0)-(Math.abs(r.im)>0)||t.re-r.re||t.im-r.im}function gr(e){if(Ke(e).size)return null;try{const{re:n,im:t}=xt(e,{digits:20});return{re:n,im:t}}catch{return null}}function vr(e,n,t){const[r,s]=e.args,o=new Set([...Ke(r),...Ke(s),...Ke(t)]);if(o.delete(n),o.size)return null;const i=e=>br(e,n,t);try{const e=xt(i(r),{digits:40}),n=xt(i(s),{digits:40}),t=Math.max(1,Math.hypot(e.re,e.im),Math.hypot(n.re,n.im));return Math.hypot(e.re-n.re,e.im-n.im)>1e-12*t?"it does not make the two sides equal":null}catch(e){return`the original equation has no value there (${e.message})`}}function br(e,n,t){return"sym"===e.type?e.token===n?t:e:V(e)?C(e.op,e.args.map(e=>br(e,n,t))):e}const yr=24;function wr(e,n,t,r,s,o,i,a){if(a>yr)return Nr(e,n,t,r,s,o,i);const u=function(e){const n=[],t=e=>{if(V(e)&&"|"===e.op)return void e.args.forEach(t);if(!dr(e))return void n.push(e);const r=e.args[1],s=H(r,"pre").find(({node:e})=>V(e)&&"pm"===e.op);if(!s)return void n.push(e);const o=s.node.args[0],i=Le(J(r,s.path,o)),a=Le(J(r,s.path,C("neg",[o])));t(fr(e.args[0],i)),a.s!==i.s&&t(fr(e.args[0],a))};return t(e),n}(n);if(u.length>1){s("solve.split","Two cases",["split"],n,u.reduce((e,n)=>e?C("|",[e,n]):n,null));for(const n of u)wr(e,n,t,r,s,o,i,a+1);return}if(1===u.length&&u[0].s!==n.s)return wr(e,u[0],t,r,s,o,i,a+1);const[l,c]=n.args;if("sym"===l.type&&l.token===t&&!Ht(We(c),t))return void o.push(c);const f=Se([We(l),Ce(We(c))]);if(!Ht(f,t))return he(f)&&f.q.isZero?(s("solve.always","Always true",["check"],n,n,{v:t}),void i.push(Object.assign(Object.create(n),{always:!0}))):void s("solve.never","No solution",["check"],n,n,{v:t});const p=Xe(f).filter(e=>Ht(e,t)),d=Xe(f).filter(e=>!Ht(e,t)),h=Se(p),m=Ce(Se(d));if(ie.complex){const u=_t(f,t);if(u&&[...u.values()].every(e=>!Ht(e,t))&&Math.max(...u.keys())>=2){const l=fr(Qe(f),pr);return l.s!==n.s&&s("solve.one-side","Everything on one side",["move"],n,l,{v:t}),Sr(e,f,u,t,r,s,o,i,a,l)}}if(1===p.length)return xr(e,n,h,m,t,r,s,o,i,a);const g=fr(Qe(f),pr),v=_t(f,t);if(v&&[...v.values()].every(e=>!Ht(e,t))&&Math.max(...v.keys())>=2)return g.s!==n.s&&s("solve.one-side","Everything on one side",["move"],n,g,{v:t}),Sr(e,f,v,t,r,s,o,i,a,g);const b=nr(f),y=b.factors.filter(e=>Ht(e.base,t)&&!(he(e.exp)&&e.exp.q.sign<0));if(y.length>=2||1===y.length&&b.factors.length>1){const u=fr(ar(b),pr);g.s!==n.s&&s("solve.one-side","Everything on one side",["move"],n,g,{v:t}),u.s!==g.s&&s("solve.factor","Factor",["factor"],g,u,{});const l=y.map(e=>fr(Qe(e.base),pr));l.length>1&&s("solve.zero-product","A product is zero when a factor is",["split"],u,l.reduce((e,n)=>e?C("|",[e,n]):n,null),{});for(const n of l)wr(e,n,t,r,s,o,i,a+1);return}const w=lr(f);if(Ht(w.den,t)){const u=fr(Qe(w.num),pr);return s("solve.clear-denominator","Clear the denominator",["move"],n,u,{den:Qe(w.den)}),wr(e,u,t,r,s,o,i,a+1)}const x=p.filter(e=>!$r(e,t));if(1===x.length&&/\b(sqrt|root|abs)\b/.test(Qe(x[0]).s))return xr(e,n,x[0],Ce(Se(Xe(f).filter(e=>e!==x[0]))),t,r,s,o,i,a);const q=function(e,n){const t=Qe(e),r=new Map;for(const{node:e}of H(t,"pre"))if(V(e)&&Ke(e).has(n))if("^"!==e.op||Ke(e.args[0]).has(n))["sin","cos","tan","ln","sqrt","abs"].includes(e.op)&&e.args[0].s===n&&r.set(e.s,e);else{const t=We(e.args[1]),{coef:s,rest:o}=$e(t);if(o&&s.isInteger&&Qe(o).s===n){const t=Qe(Ae(We(e.args[0]),We(Z(n))));r.set(t.s,t)}}const s="u"===n?"w":"u";for(const e of r.values()){const r=Or(t,e,n,s);if(!r||Ke(r).has(n))continue;const o=We(r),i=_t(o,s);if(i&&Math.max(...i.keys())>=1)return{kernel:We(e),poly:o,symbol:s}}return null}(f,t);if(q){const n=q.symbol;s("solve.substitute","Substitute",["substitute"],g,fr(Qe(q.poly),pr),{u:Z(n),kernel:Qe(q.kernel)});const u=[];wr(e,fr(Qe(q.poly),pr),n,r,s,u,i,a+1);for(const n of u)wr(e,fr(Qe(q.kernel),n),t,r,s,o,i,a+1);return}return Nr(e,g,t,r,s,o,i)}function xr(e,n,t,r,s,o,i,a,u,l){let c=fr(Qe(t),Qe(r));c.s!==n.s&&i("solve.move","Move the terms",["move"],n,c,{v:s});const{coef:f,rest:p}=$e(t),d=p?en(p):[],h=Ne([ce(f),...d.filter(e=>!Ht(e,s))]);if(!he(h)||!h.q.isOne){const e=Ne(d.filter(e=>Ht(e,s))),n=fr(Qe(e),Qe(Fe(r,h))),t=he(h)&&!h.q.isInteger&&(1n===h.q.n||-1n===h.q.n);i(t?"solve.multiply":"solve.divide",t?"Multiply both sides":"Divide both sides",["move"],c,n,{by:Qe(t?ce(h.q.inv()):h),v:s}),c=n}if("sym"===c.args[0].type&&c.args[0].token===s)return void a.push(c.args[1]);const m=We(c.args[1]);if(he(m)&&m.q.isZero){const n=We(c.args[0]),t=en(n).filter(e=>Ht(e,s)&&!qr(e));if(t.length>1||t.length<en(n).filter(e=>Ht(e,s)).length){const n=t.map(e=>fr(Qe(kr(e)),pr));i("solve.zero-product","A product is zero when a factor is",["split"],c,n.reduce((e,n)=>e?C("|",[e,n]):n,null),{});for(const t of n)wr(e,t,s,o,i,a,u,l+1);return}}const g=Bt(c,e.set.view("isolate"),{format:e.format,maxSteps:1,variable:s});return g.steps.length?(function(e,n){for(const t of n)e.raw(t)}(i,g.steps),wr(e,g.node,s,o,i,a,u,l+1)):Nr(e,c,s,o,i,a,u)}const qr=e=>"mul"===e.k&&e.c.isOne&&1===e.fs.length&&he(e.fs[0].e)&&e.fs[0].e.q.sign<0,kr=e=>"mul"===e.k&&e.c.isOne&&1===e.fs.length&&he(e.fs[0].e)&&e.fs[0].e.q.sign>0?e.fs[0].b:e,$r=(e,n)=>{const t=_t(e,n);return Boolean(t)&&[...t.values()].every(e=>!Ht(e,n))};function Sr(e,n,t,r,s,o,i,a,u,l){const c=Math.max(...t.keys()),f=Jt(t);if(ie.complex&&c>=3&&c<=64&&f&&f.every((e,n)=>0===n||n===c||e.isZero)&&!f[0].isZero){const n=f[0].neg().div(f[c]),t=Ae(ce(n.abs()),ce(new ee(1n,BigInt(c)))),s=[];for(let r=0;r<c;r++){const o=Ne([ce(new ee(BigInt((n.sign<0?1:0)+2*r),BigInt(c))),We(Z("pi"))]),i=C("*",[Qe(t),C("+",[C("cos",[Qe(o)]),C("*",[Z("i"),C("sin",[Qe(o)])])])]);s.push(Bt(i,e.set.view("simplify"),{format:e.format}).node)}return o("solve.roots","All n roots",["complex"],l,s.map(e=>fr(Z(r),e)).reduce((e,n)=>e?C("|",[e,n]):n),{v:r,n:String(c),last:String(c-1),r:Qe(ce(n))}),void i.push(...s)}if(f){const{roots:t}=er(f);if(t.length){const t=nr(n),c=fr(ar(t),pr);if(t.factors.length>1||t.factors.some(e=>!(he(e.exp)&&e.exp.q.isOne))){o("solve.factor","Factor",["factor"],l,c,{});const n=t.factors.filter(e=>Ht(e.base,r)).map(e=>fr(Qe(e.base),pr));n.length>1&&o("solve.zero-product","A product is zero when a factor is",["split"],c,n.reduce((e,n)=>e?C("|",[e,n]):n,null),{});for(const t of n)wr(e,t,r,s,o,i,a,u+1);return}}}if(2===c){const e=t.get(2),n=t.get(1)??ce(ee.ZERO),s=t.get(0)??ce(ee.ZERO),a=Se([Ae(n,ce(ee.of(2))),Ne([ce(ee.of(-4)),e,s])]);if(he(a)&&a.q.sign<0&&!ie.complex)return void o("solve.no-real","No real solutions",["quadratic"],l,l,{D:Qe(a)});const u=Ne([ce(ee.of(2)),e]),c=Ae(a,ce(ee.HALF)),f=Qe(Fe(Se([Ce(n),c]),u)),p=Qe(Fe(Se([Ce(n),Ce(c)]),u)),d=f.s===p.s?fr(Z(r),f):C("|",[fr(Z(r),f),fr(Z(r),p)]);return o(ie.complex&&he(a)&&a.q.sign<0?"solve.quadratic-complex":"solve.quadratic","The quadratic formula",["quadratic"],l,d,{a:Qe(e),b:Qe(n),c:Qe(s),D:Qe(a),root:Qe(c),v:r}),i.push(f),void(p.s!==f.s&&i.push(p))}return Nr(e,l,r,s,o,i,a)}function Or(e,n,t,r){if(e.s===n.s)return Z(r);if(!V(e))return e;if("^"===e.op&&"^"===n.op&&e.args[0].s===n.args[0].s){const n=We(e.args[1]),{coef:s,rest:o}=$e(n);if(o&&Qe(o).s===t&&s.isInteger)return C("^",[Z(r),Qe(ce(s))])}return C(e.op,e.args.map(e=>Or(e,n,t,r)))}function Nr(e,n,t,r,s,o,i){if(r.approximate){const e="number"==typeof r.approximate?r.approximate:15,i=We(C("-",[n.args[0],n.args[1]])),a=ie.complex?Jt(_t(i,t)):null,u=a&&a.length>2?function(e,n){const t=e.length-1,r=e[t],s=e.map(e=>e/r),o=(e,n)=>{let r=1,o=0;for(let i=t-1;i>=0;i--)[r,o]=[r*e-o*n+s[i],r*n+o*e];return[r,o]};let i=Array.from({length:t},(e,n)=>[1.3*Math.cos(2*Math.PI*n/t+.4),1.3*Math.sin(2*Math.PI*n/t+.4)]);for(let e=0;e<500;e++){let e=0;if(i=i.map(([n,r],s)=>{let[a,u]=o(n,r);for(let e=0;e<t;e++){if(e===s)continue;const t=n-i[e][0],o=r-i[e][1],l=t*t+o*o;[a,u]=[(a*t+u*o)/l,(u*t-a*o)/l]}return e=Math.max(e,Math.hypot(a,u)),[n-a,r-u]}),e<1e-15)break}const a=e=>Math.abs(e)<1e-12?0:Number(e.toPrecision(n));return i.map(([e,n])=>[a(e),a(n)]).sort((e,n)=>(0!==e[1])-(0!==n[1])||e[0]-n[0]||e[1]-n[1]).map(([e,n])=>{const t=Ar(e);if(0===n)return t;const r=C("*",[Ar(Math.abs(n)),Z("i")]);return 0===e?n<0?C("neg",[r]):r:C(n<0?"-":"+",[t,r])})}(a.map(e=>e.toNumber()),Math.min(e,14)):function(e,n,t){const r=We(C("-",[e.args[0],e.args[1]])),s=Qe(r),o=e=>{try{return xt(br(s,n,Ir(e)),{digits:30}).number}catch{return NaN}},i=[],a=[];for(let e=-400;e<=400;e++)a.push(Math.sign(e)*(Math.abs(e)/20)**2);for(let e=0;e+1<a.length;e++){let n=a[e],r=a[e+1],s=o(n);const u=o(r);if(Number.isNaN(s)||Number.isNaN(u))continue;if(0===s){i.push(Ir(n));continue}if(s*u>0)continue;for(let e=0;e<200&&r-n>1e-16*Math.abs(n);e++){const e=(n+r)/2,t=o(e);if(Number.isNaN(t))break;s*t<=0?r=e:(n=e,s=t)}const l=(n+r)/2;Math.abs(o(l))<1e-6&&i.push(Ir(Number(l.toPrecision(Math.min(t,15)))))}return i}(n,t,e);for(const e of u)o.numeric?.add(e);return s("solve.numeric","Numeric solutions",["numeric"],n,u.length?u.map(e=>fr(Z(t),e)).reduce((e,n)=>e?C("|",[e,n]):n):n,{v:t,count:String(u.length)}),void o.push(...u)}s("solve.unsolved","No exact method",["unsolved"],n,n,{v:t}),i.push(n)}const Ar=e=>z(String(e).includes("e")?e.toFixed(20):String(e)),Ir=e=>z(Number.isInteger(e)?String(e):e.toFixed(17));const Mr=(e,n)=>C("int",[e,"string"==typeof n?Z(n):n]);function Er(e,n,t,r=0){if(r>6)throw new Q("integration went too deep");const s=[],o=e.set.view("integrate"),i=Bt(n,e.set.view("simplify"),{format:e.format});s.push(...i.steps);let a=Le(Mr(i.node,t));for(let n=0;n<40;n++){const n=Bt(a,o,{format:e.format});s.push(...n.steps),a=n.node;const t=H(a,"pre").find(({node:e})=>{return V(n=e)&&"int"===n.op&&2===n.args.length;var n});if(!t)return{node:a,steps:s};const i=Tr(e,t.node,r);if(!i)throw new Q(`no rule for ∫ ${e.format(t.node.args[0])} d${t.node.args[1].token}`);s.push(...i.steps),a=Le(J(a,t.path,i.node))}throw new Q("integration did not finish")}function Tr(e,n,t){const[r,s]=n.args,o=s.token,i=We(r),a=function(e,n){const{num:t,den:r}=lr(e),s=nr(t),o=nr(r),i=s.coef.div(o.coef);if(i.isOne||!Ht(e,n))return null;const a=Ne([...s.factors.map(e=>Ie(e.base,e.exp)),...o.factors.map(e=>Ie(e.base,Ce(e.exp)))]);return{c:i,rest:a}}(i,o);if(a){const t=C("*",[Qe(ce(a.c)),Mr(Qe(a.rest),s)]);return{node:t,steps:[e.step("integrate.constant","Take the number out",["split"],n,t,{c:Qe(ce(a.c))})]}}const u=Wt(i);if(Qe(u).s!==r.s&&"add"===u.k){const t=Mr(Qe(u),s);return{node:t,steps:[e.step("integrate.expand","Multiply out",["expand"],n,t,{})]}}const l=function(e,n){const t=new Map;for(const{node:r}of H(e,"pre")){if(!V(r))continue;const e="^"===r.op?r.args:"/"===r.op?[r.args[1]]:"der"===r.op||"int"===r.op?[]:1===r.args.length||"root"===r.op?[r.args[r.args.length-1]]:[];for(const r of e){if("sym"===r.type||!Ke(r).has(n))continue;const e=_t(We(r),n);if(!e||1!==Math.max(...e.keys()))continue;const s=e.get(1);Ht(s,n)||he(s)&&s.q.isZero||t.set(r.s,{node:r,a:s})}}for(const r of t.values()){if(!Ke(jr(e,r.node,Z("§"))).has(n))return r}return null}(r,o);if(l){const s="u"===o?"t":"u",i=jr(r,l.node,Z(s));if(!Ke(i).has(o)){const r=Er(e,Le(i),s,t+1),a=Le(br(r.node,s,l.node)),u=Qe(Fe(We(a),l.a));return{node:u,steps:[e.step("integrate.substitute","Substitute",["substitute"],n,Le(Mr(i,s)),{u:Z(s),inside:l.node,a:Qe(l.a),v:o}),...r.steps,e.step("integrate.back","Substitute back",["substitute"],r.node,u,{u:Z(s),inside:l.node})]}}}const c=function(e,n,t,r){const{num:s,den:o}=lr(t);if(!Ht(o,r))return null;const i=Jt(_t(s,r)),a=Jt(_t(o,r));if(!i||!a||a.length<2)return null;const u=We(Z(r)),l=e=>Qt(e,r);if(i.length>=a.length){const{q:t,r:s}=function(e,n){const t=Yt(n);let r=Yt(e);const s=t[t.length-1];if(s.isZero)throw new Q("division by the zero polynomial");const o=new Array(Math.max(1,r.length-t.length+1)).fill(ee.ZERO);for(;r.length>=t.length&&(1!==r.length||!r[0].isZero);){const e=r.length-t.length,n=r[r.length-1].div(s);if(o[e]=n,r=Yt(r.map((r,s)=>s>=e&&s-e<t.length?r.sub(n.mul(t[s-e])):r)),r.length-1<e+t.length-1&&r[r.length-1].isZero)break;if(r.length<t.length)break}return{q:Yt(o),r:r}}(i,a),o=Mr(Qe(Se([l(t),Fe(l(s),l(a))])),Z(r));return{node:o,steps:[e.step("integrate.divide","Divide the polynomials",["divide"],n,o,{})]}}const{roots:c,rest:f}=er(a),p=new Set(c.map(String)).size===c.length;if(!c.length||!p||1!==f.length)return null;const d=(e=>e.length<=1?[ee.ZERO]:e.slice(1).map((e,n)=>e.mul(ee.of(n+1))))(a),h=c.map(e=>Fe(ce(Gt(i,e).div(Gt(d,e))),Se([u,ce(e.neg())]))),m=Mr(Qe(Se(h)),Z(r));return{node:m,steps:[e.step("integrate.partial-fractions","Partial fractions",["partial-fractions"],n,m,{})]}}(e,n,i,o);return c||function(e,n,t,r,s){if(s>=6)return null;const o=en(t),i=o.filter(e=>Zr(e,r)||!Ht(e,r)),a=o.filter(e=>!i.includes(e));if(1!==a.length)return null;const u=Ne(i),l=a[0];if(!Ht(u,r))return null;const c=Qe(l),f=V(c)?c.op:"";let p,d,h;"ln"===f||"arctan"===f||"arcsin"===f?(p=l,d=u):(p=u,d=l);try{h=Er(e,Qe(d),r,s+1)}catch{return null}const m=We(e.differentiate(Qe(p),r)),g=Ne([p,We(h.node)]),v=Mr(Qe(Ne([m,We(h.node)])),Z(r)),b=Le(C("-",[Qe(g),v]));return{node:b,steps:[e.step("integrate.parts","Integration by parts",["parts"],n,b,{u:Qe(p),dv:Qe(d),V:h.node,du:Qe(m),v:r})]}}(e,n,i,o,t)}function jr(e,n,t){return e.s===n.s?t:V(e)?C(e.op,e.args.map(e=>jr(e,n,t))):e}const Zr=(e,n)=>{const t=_t(e,n);return Boolean(t)&&[...t.values()].every(e=>!Ht(e,n))&&Math.max(...t.keys())>=1};function zr(e,n,t,r,s,o){for(const e of[r,s])if(Ke(e).has("∞")||/∞|infinity/.test(e.s))throw new Q("integrals to infinity need limits, which this CAS does not do yet");if(o&&!Ke(r).size&&!Ke(s).size){const i=xt(r,{digits:20}).number,a=xt(s,{digits:20}).number,u=[...Ke(o)].filter(e=>e!==t);if(!u.length){const[r,s]=i<=a?[i,a]:[a,i];for(const i of function(e,n){const t=[],r={tan:"cos",sec:"cos",csc:"sin",cot:"sin"};return H(e,"pre").forEach(({node:e})=>{if(!V(e))return;let s=null;"/"===e.op?s=e.args[1]:"^"===e.op&&"num"===e.args[1].type&&e.args[1].value<0||"^"===e.op&&V(e.args[1])&&"neg"===e.args[1].op?s=e.args[0]:r[e.op]&&(s=C(r[e.op],[e.args[0]])),s&&Ke(s).has(n)&&!t.some(e=>e.s===s.s)&&t.push(s)}),t}(o,t)){let o=[];try{o=e.solve(C("=",[i,z("0")]),t,{steps:!1}).solutions}catch{continue}for(const i of o){const o=xt(i,{digits:20});if(!Number.isFinite(o.number)||o.im||o.number<r||o.number>s)continue;if(o.number>r&&o.number<s)throw new Q(`the integrand has no value at ${t} = ${e.format(i)}, between the limits, so F(b) - F(a) would be wrong`);let a=NaN;try{a=xt(Le(br(n,t,i)),{digits:15}).number}catch{}if(!Number.isFinite(a))throw new Q(`the integral diverges at ${t} = ${e.format(i)}: F has no value at that limit`)}}}for(let e=0;!u.length&&e<=64;e++){const n=i+(a-i)*(e+.5)/65;try{const e=xt(br(o,t,z(n.toFixed(15))),{digits:15}).number;if(!Number.isFinite(e))throw new Q("not finite")}catch(e){throw new Q(`the integrand has no value at ${t} = ${n.toPrecision(6)}, between the limits, so F(b) - F(a) would be wrong`)}}}const i=e=>Le(br(n,t,e)),a=Le(C("-",[i(s),i(r)])),u=C("-",[i(s),i(r)]);return{value:a,step:e.step("integrate.evaluate","Between the limits",["evaluate"],n,u,{a:r,b:s,F:n,v:t})}}const Dr={"=":1,"≠":1,"<":1,">":1,"≤":1,"≥":1,"+":2,"-":2,"±":2,"*":3,"/":3,neg:4,pm:4,"^":5},Br={pi:"π","≤":"≤","≥":"≥"};function Cr(e){return Pr(e).text}function Fr(e,n,t=!1){return e.prec<n||t&&e.prec===n?`(${e.text})`:e.text}const Vr=e=>"op"===e.type?e.op:null,Rr=e=>e.text.startsWith("-"),Ur={"()":["(",")"],"[]":["[","]"],"{}":["{","}"],"(]":["(","]"],"[)":["[",")"]};function Pr(e){if("num"===e.type)return{text:e.token,prec:e.token.startsWith("-")?4:9};if("sym"===e.type)return{text:Br[e.token]??e.token,prec:9};const n=e.args.map(Pr),t=Dr[e.op];switch(e.op){case"+":case"-":case"±":{const r="+"===e.op&&["+","-"].includes(Vr(e.args[1])),s=Rr(n[1])?`(${n[1].text})`:r?n[1].text:Fr(n[1],t,!0);return{text:`${Fr(n[0],t)} ${"±"===e.op?"±":e.op} ${s}`,prec:t}}case"*":{const r=Fr(n[0],t),s=Rr(n[1])?`(${n[1].text})`:"*"===Vr(e.args[1])?n[1].text:Fr(n[1],t,!0);return{text:"num"===e.args[0].type&&"num"!==e.args[1].type&&!/^[\d(-]/.test(s)||"sym"===e.args[1].type&&"i"===e.args[1].token&&!/[\dA-Za-z]$/.test(r)?`${r}${s}`:`${r}·${s}`,prec:t}}case"/":return{text:`${Fr(n[0],t)}/${Fr(n[1],t,!0)}`,prec:t};case"^":return{text:`${Fr(n[0],t+1)}^${Fr(n[1],t)}`,prec:t};case"neg":return{text:`-${Fr(n[0],3)}`,prec:4};case"pm":return{text:`±${Fr(n[0],4)}`,prec:4};case"!":return{text:`${Fr(n[0],9)}!`,prec:6};case"abs":return{text:`|${n[0].text}|`,prec:9};case"root":return{text:`root(${n[0].text}, ${n[1].text})`,prec:9};case"der":return{text:`d/d${n[1].text} (${n[0].text})`,prec:6};case"int":return{text:4===n.length?`∫ from ${n[2].text} to ${n[3].text} of ${n[0].text} d${n[1].text}`:`∫ ${n[0].text} d${n[1].text}`,prec:1};case"|":return{text:`${n[0].text} or ${n[1].text}`,prec:0};case"_":return{text:`${Fr(n[0],9)}_${n[1].prec>=9&&!/\s/.test(n[1].text)?n[1].text:`(${n[1].text})`}`,prec:9};case"()":case"[]":case"{}":case"(]":case"[)":return{text:`${Ur[e.op][0]}${n.map(e=>e.text).join(", ")}${Ur[e.op][1]}`,prec:9};case"&":return{text:`${n[0].text} and ${n[1].text}`,prec:0};default:return void 0!==t?{text:`${Fr(n[0],t)} ${e.op} ${Fr(n[1],t,!0)}`,prec:t}:{text:`${e.op.replace(/^\\:?/,"")}(${n.map(e=>e.text).join(", ")})`,prec:9}}}const Wr=['name: Differentiation\n\n# `u v der` means d(u)/dv (MathZetta\'s postfix: mathzetta/docs/postfix.md). Every rule here rewrites one derivative into smaller\n# derivatives, so differentiating always terminates: the expressions sitting\n# under a `D` get strictly smaller at every step.\n#\n# The variable is a slot, not a fixed letter, so these rules work for d/dx,\n# d/dt or anything else. That is what freeOf and dependsOn are for: they ask\n# whether one operand mentions whatever the variable slot bound to.\n#\n# Where two rules share a structure key, requirements keep them apart and\n# priority picks the one that reads better. The constant-multiple rule outranks\n# the product rule for exactly that reason.\n\nrules:\n # ---- the two base cases ----------------------------------------------\n - id: d-constant\n name: Derivative of a constant\n mode: differentiate\n pattern: c v der\n require:\n - [freeOf, c, v]\n output: "0"\n priority: 10\n explain: "{c} does not change when {v} changes, so its rate of change is 0."\n tags: [base]\n\n - id: d-variable\n name: Derivative of the variable\n mode: differentiate\n pattern: u v der\n require:\n - [sameAs, u, v]\n output: "1"\n priority: 10\n explain: "{v} changes exactly as fast as itself, so the rate is 1."\n tags: [base]\n\n # ---- splitting a derivative into smaller ones ------------------------\n - id: d-sum\n name: Sum rule\n mode: differentiate\n pattern: u w + v der\n output: u v der w v der +\n explain: "Differentiate {u} and {w} separately, then add the two results."\n tags: [split]\n\n - id: d-difference\n name: Difference rule\n mode: differentiate\n pattern: u w - v der\n output: u v der w v der -\n explain: "Differentiate {u} and {w} separately, then subtract the second from the first."\n tags: [split]\n\n - id: d-negate\n name: Derivative of a negative\n mode: differentiate\n pattern: u neg v der\n output: u v der neg\n explain: "The minus sign just carries through to the derivative of {u}."\n tags: [split]\n\n - id: d-constant-multiple\n name: Constant multiple rule\n mode: differentiate\n pattern: c u * v der\n commutative: true\n require:\n - [freeOf, c, v]\n - [dependsOn, u, v]\n output: c u v der *\n priority: 5\n explain: "{c} is only a scale factor, so it comes along unchanged while {u} is differentiated."\n tags: [split]\n\n - id: d-constant-divisor\n name: Dividing by a constant\n mode: differentiate\n pattern: u c / v der\n require:\n - [freeOf, c, v]\n output: u v der c /\n priority: 5\n explain: "Dividing by {c} is only a scale factor, so differentiate {u} and keep the division."\n tags: [split]\n\n - id: d-product\n name: Product rule\n mode: differentiate\n pattern: u w * v der\n require:\n - [dependsOn, u, v]\n - [dependsOn, w, v]\n output: u v der w * u w v der * +\n explain: "Differentiate {u} and keep {w}, then keep {u} and differentiate {w}, and add the two."\n tags: [split]\n\n - id: d-quotient\n name: Quotient rule\n mode: differentiate\n pattern: u w / v der\n output: u v der w * u w v der * - w 2 ^ /\n explain: "Bottom times the derivative of the top, minus top times the derivative of the bottom, all over {w} squared."\n tags: [split]\n\n # ---- powers -----------------------------------------------------------\n - id: d-power-of-variable\n name: Power rule\n mode: differentiate\n pattern: u n ^ v der\n require:\n - [sameAs, u, v]\n - [freeOf, n, v]\n output: n u n 1 - ^ *\n fold: true\n priority: 6\n explain: "Bring the {n} down in front and drop the power by one."\n tags: [power]\n\n - id: d-power-chain\n name: Power rule with the chain rule\n mode: differentiate\n pattern: u n ^ v der\n require:\n - [freeOf, n, v]\n - [dependsOn, u, v]\n output: n u n 1 - ^ * u v der *\n fold: true\n explain: "Bring the {n} down and drop the power by one, then multiply by the derivative of {u}."\n tags: [power, chain]\n\n - id: d-exponential-base\n name: Derivative of a constant to a power\n mode: differentiate\n pattern: a u ^ v der\n require:\n - [freeOf, a, v]\n - [dependsOn, u, v]\n output: a u ^ a ln * u v der *\n explain: "A constant base gives itself back, multiplied by the natural log of {a} and the derivative of {u}."\n tags: [power, chain]\n\n # ---- the standard functions, each with its chain-rule factor ---------\n # e^u is `=e u ^`: the base is the literal symbol e. Outranks the general\n # a^u rule (which would give e^u · ln e · u\').\n - id: d-exp\n name: Derivative of e to a power\n mode: differentiate\n pattern: =e u ^ v der\n require:\n - [dependsOn, u, v]\n output: =e u ^ u v der *\n priority: 7\n explain: "e to a power is its own derivative, times the derivative of {u}."\n tags: [chain]\n\n - id: d-ln\n name: Derivative of a natural log\n mode: differentiate\n pattern: u ln v der\n output: u v der u /\n explain: "The derivative of {u} over {u} itself."\n tags: [chain]\n\n - id: d-sqrt\n name: Derivative of a square root\n mode: differentiate\n pattern: u sqrt v der\n output: u v der 2 u sqrt * /\n explain: "The derivative of {u}, over twice the square root of {u}."\n tags: [chain]\n\n - id: d-sin\n name: Derivative of sine\n mode: differentiate\n pattern: u sin v der\n output: u cos u v der *\n explain: "Sine differentiates to cosine, times the derivative of {u}."\n tags: [chain, trig]\n\n - id: d-cos\n name: Derivative of cosine\n mode: differentiate\n pattern: u cos v der\n output: u sin u v der * neg\n explain: "Cosine differentiates to minus sine, times the derivative of {u}."\n tags: [chain, trig]\n\n - id: d-tan\n name: Derivative of tangent\n mode: differentiate\n pattern: u tan v der\n output: u v der u cos 2 ^ /\n explain: "The derivative of {u}, over cosine squared of {u}."\n tags: [chain, trig]\n\n # ---- the rest of the standard functions -----------------------------\n - id: d-csc\n name: Derivative of cosecant\n mode: differentiate\n pattern: u csc v der\n output: u csc u cot * u v der * neg\n explain: "Cosecant differentiates to minus cosecant times cotangent, times the derivative of {u}."\n tags: [chain, trig]\n\n - id: d-sec\n name: Derivative of secant\n mode: differentiate\n pattern: u sec v der\n output: u sec u tan * u v der *\n explain: "Secant differentiates to secant times tangent, times the derivative of {u}."\n tags: [chain, trig]\n\n - id: d-cot\n name: Derivative of cotangent\n mode: differentiate\n pattern: u cot v der\n output: u v der u sin 2 ^ / neg\n explain: "Minus the derivative of {u}, over sine squared of {u}."\n tags: [chain, trig]\n\n - id: d-arcsin\n name: Derivative of arcsine\n mode: differentiate\n pattern: u arcsin v der\n output: u v der 1 u 2 ^ - sqrt /\n explain: "The derivative of {u}, over the square root of 1 minus {u} squared."\n tags: [chain, trig]\n\n - id: d-arccos\n name: Derivative of arccosine\n mode: differentiate\n pattern: u arccos v der\n output: u v der 1 u 2 ^ - sqrt / neg\n explain: "Minus the derivative of {u}, over the square root of 1 minus {u} squared."\n tags: [chain, trig]\n\n - id: d-arctan\n name: Derivative of arctangent\n mode: differentiate\n pattern: u arctan v der\n output: u v der 1 u 2 ^ + /\n explain: "The derivative of {u}, over 1 plus {u} squared."\n tags: [chain, trig]\n\n - id: d-sinh\n name: Derivative of hyperbolic sine\n mode: differentiate\n pattern: u sinh v der\n output: u cosh u v der *\n explain: "Hyperbolic sine differentiates to hyperbolic cosine, times the derivative of {u}."\n tags: [chain, hyperbolic]\n\n - id: d-cosh\n name: Derivative of hyperbolic cosine\n mode: differentiate\n pattern: u cosh v der\n output: u sinh u v der *\n explain: "Hyperbolic cosine differentiates to hyperbolic sine — no minus sign, unlike cosine — times the derivative of {u}."\n tags: [chain, hyperbolic]\n\n - id: d-tanh\n name: Derivative of hyperbolic tangent\n mode: differentiate\n pattern: u tanh v der\n output: u v der u cosh 2 ^ /\n explain: "The derivative of {u}, over hyperbolic cosine squared of {u}."\n tags: [chain, hyperbolic]\n\n - id: d-arcsinh\n name: Derivative of inverse hyperbolic sine\n mode: differentiate\n pattern: u arcsinh v der\n output: u v der u 2 ^ 1 + sqrt /\n explain: "The derivative of {u}, over the square root of {u} squared plus 1."\n tags: [chain, hyperbolic]\n\n - id: d-arccosh\n name: Derivative of inverse hyperbolic cosine\n mode: differentiate\n pattern: u arccosh v der\n output: u v der u 2 ^ 1 - sqrt /\n explain: "The derivative of {u}, over the square root of {u} squared minus 1."\n tags: [chain, hyperbolic]\n\n - id: d-arctanh\n name: Derivative of inverse hyperbolic tangent\n mode: differentiate\n pattern: u arctanh v der\n output: u v der 1 u 2 ^ - /\n explain: "The derivative of {u}, over 1 minus {u} squared."\n tags: [chain, hyperbolic]\n\n # log base a: `a u log` in MathZetta\'s postfix\n - id: d-log\n name: Derivative of a logarithm\n mode: differentiate\n pattern: a u log v der\n require:\n - [freeOf, a, v]\n output: u v der u a ln * /\n explain: "The derivative of {u}, over {u} times the natural log of {a}."\n tags: [chain]\n\n - id: d-abs\n name: Derivative of an absolute value\n mode: differentiate\n pattern: u abs v der\n output: u u abs / u v der *\n explain: "The absolute value keeps the sign of {u}: {u} over its absolute value, times the derivative of {u}."\n tags: [chain]\n\n # n-th root: `n u root`\n - id: d-root\n name: Derivative of a root\n mode: differentiate\n pattern: n u root v der\n require:\n - [freeOf, n, v]\n output: u v der n n u root n 1 - ^ * /\n fold: true\n explain: "The derivative of {u}, over {n} times the {n}th root of {u} to the power {n} minus 1."\n tags: [chain]\n','name: More derivatives\n\n# Derivative rules the CAS adds to rules/calculus.yaml (which calcvidnew also uses).\n\nrules:\n - id: d-general-power\n name: A power with the variable in both places\n mode: differentiate\n pattern: u w ^ v der\n require:\n - [dependsOn, u, v]\n - [dependsOn, w, v]\n output: u w ^ w v der u ln * w u v der * u / + *\n explain: "Write {u}^{w} as e^({w} ln {u}) and use the chain rule: the derivative is {u}^{w} times the derivative of {w} ln {u}."\n tags: [chain]\n','name: Integrals\n\n# mode: integrate. `f v 2 int` is ∫ f dv (MathZetta\'s postfix; the 2 counts f and v).\n# Each rule turns one integral into smaller ones, or into an answer. The CAS also\n# tries, when no rule fits: multiplying out, a linear substitution (∫ f(ax + b) dx\n# from the rule for ∫ f(u) du), and integration by parts for polynomial × e^, sin,\n# cos, ln, arctan. Definite integrals are the antiderivative between the limits.\n#\n# Patterns see the normal form: 1/x is "1 x /", x^-2 is "1 x 2 ^ /", √x is "x sqrt",\n# 1/√(1 - x²) is "1 x 2 ^ neg 1 + sqrt /".\n\nrules:\n # ---- splitting -----------------------------------------------------------\n - id: i-sum\n name: Sum rule\n mode: integrate\n pattern: u w + v 2 int\n output: u v 2 int w v 2 int +\n explain: "Integrate {u} and {w} separately, and add."\n tags: [split]\n\n - id: i-difference\n name: Difference rule\n mode: integrate\n pattern: u w - v 2 int\n output: u v 2 int w v 2 int -\n explain: "Integrate {u} and {w} separately, and subtract."\n tags: [split]\n\n - id: i-negate\n name: A minus sign\n mode: integrate\n pattern: u neg v 2 int\n output: u v 2 int neg\n explain: "The minus sign comes out of the integral."\n tags: [split]\n\n - id: i-constant-multiple\n name: Constant multiple\n mode: integrate\n pattern: c u * v 2 int\n commutative: true\n require:\n - [freeOf, c, v]\n - [dependsOn, u, v]\n output: c u v 2 int *\n priority: 5\n explain: "{c} doesn\'t change with {v}, so it comes out of the integral."\n tags: [split]\n\n - id: i-constant-divisor\n name: Dividing by a constant\n mode: integrate\n pattern: u c / v 2 int\n require:\n - [freeOf, c, v]\n - [dependsOn, u, v]\n output: u v 2 int c /\n priority: 5\n explain: "Dividing by {c} comes out of the integral."\n tags: [split]\n\n - id: i-constant-over\n name: A constant over something\n mode: integrate\n pattern: c u / v 2 int\n require:\n - [freeOf, c, v]\n - [dependsOn, u, v]\n when:\n c: [notOne]\n output: c 1 u / v 2 int *\n priority: 4\n explain: "{c} comes out of the integral, leaving ∫ 1/{u}."\n tags: [split]\n\n # ---- the table -----------------------------------------------------------\n - id: i-constant\n name: Integral of a constant\n mode: integrate\n pattern: c v 2 int\n require:\n - [freeOf, c, v]\n output: c v *\n priority: 10\n explain: "A constant {c} integrates to {c}·{v}."\n tags: [base]\n\n - id: i-variable\n name: Integral of the variable\n mode: integrate\n pattern: u v 2 int\n require:\n - [sameAs, u, v]\n output: v 2 ^ 2 /\n priority: 10\n explain: "∫ {v} d{v} = {v}²/2."\n tags: [base]\n\n - id: i-power\n name: Power rule\n mode: integrate\n pattern: u n ^ v 2 int\n require:\n - [sameAs, u, v]\n - [freeOf, n, v]\n when:\n n: [notMinusOne]\n output: v n 1 + ^ n 1 + /\n explain: "Add 1 to the power and divide by the new power: {result}."\n tags: [power]\n\n - id: i-reciprocal\n name: Integral of 1/x\n mode: integrate\n pattern: 1 u / v 2 int\n require:\n - [sameAs, u, v]\n output: v abs ln\n explain: "∫ 1/{v} d{v} = ln|{v}| (the power rule can\'t divide by 0 here)."\n tags: [log]\n\n - id: i-reciprocal-power\n name: Power rule (a power below)\n mode: integrate\n pattern: 1 u n ^ / v 2 int\n require:\n - [sameAs, u, v]\n - [freeOf, n, v]\n when:\n n: [notOne]\n output: v 1 n - ^ 1 n - /\n explain: "1/{v}^{n} is {v}^(-{n}): add 1 to the power and divide by it."\n tags: [power]\n\n - id: i-sqrt\n name: Integral of a square root\n mode: integrate\n pattern: u sqrt v 2 int\n require:\n - [sameAs, u, v]\n output: 2 v 3 2 / ^ * 3 /\n explain: "√{v} is {v}^(1/2): add 1 to the power and divide by 3/2."\n tags: [power]\n\n - id: i-reciprocal-sqrt\n name: Integral of 1/√x\n mode: integrate\n pattern: 1 u sqrt / v 2 int\n require:\n - [sameAs, u, v]\n output: 2 v sqrt *\n explain: "1/√{v} is {v}^(-1/2): add 1 to the power and divide by 1/2."\n tags: [power]\n\n - id: i-root\n name: Integral of a root\n mode: integrate\n pattern: n u root v 2 int\n require:\n - [sameAs, u, v]\n - [freeOf, n, v]\n output: v 1 n / 1 + ^ 1 n / 1 + /\n explain: "The {n}th root of {v} is {v}^(1/{n}): add 1 to the power and divide by it."\n tags: [power]\n\n - id: i-exp\n name: Integral of e^x\n mode: integrate\n pattern: =e u ^ v 2 int\n require:\n - [sameAs, u, v]\n output: =e v ^\n explain: "e^{v} is its own integral."\n tags: [exp]\n\n - id: i-exponential\n name: Integral of a^x\n mode: integrate\n pattern: a u ^ v 2 int\n require:\n - [sameAs, u, v]\n - [freeOf, a, v]\n output: a v ^ a ln /\n explain: "∫ {a}^{v} d{v} = {a}^{v} / ln {a}."\n tags: [exp]\n\n - id: i-ln\n name: Integral of ln x\n mode: integrate\n pattern: u ln v 2 int\n require:\n - [sameAs, u, v]\n output: v v ln * v -\n explain: "By parts: ∫ ln {v} d{v} = {v} ln {v} - {v}."\n tags: [log]\n\n - { id: i-sin, name: Integral of sin, mode: integrate, pattern: u sin v 2 int, require: [[sameAs, u, v]], output: v cos neg, tags: [trig], explain: "The derivative of -cos {v} is sin {v}." }\n - { id: i-cos, name: Integral of cos, mode: integrate, pattern: u cos v 2 int, require: [[sameAs, u, v]], output: v sin, tags: [trig], explain: "The derivative of sin {v} is cos {v}." }\n - { id: i-tan, name: Integral of tan, mode: integrate, pattern: u tan v 2 int, require: [[sameAs, u, v]], output: v cos abs ln neg, tags: [trig], explain: "tan = sin/cos, and -ln|cos {v}| differentiates to it." }\n - { id: i-sec-squared, name: Integral of sec², mode: integrate, pattern: 1 u cos 2 ^ / v 2 int, require: [[sameAs, u, v]], output: v tan, tags: [trig], explain: "The derivative of tan {v} is 1/cos²{v}." }\n - { id: i-sec-squared-written, name: Integral of sec², mode: integrate, pattern: u sec 2 ^ v 2 int, require: [[sameAs, u, v]], output: v tan, tags: [trig], explain: "The derivative of tan {v} is sec²{v}." }\n - { id: i-csc-squared, name: Integral of csc², mode: integrate, pattern: 1 u sin 2 ^ / v 2 int, require: [[sameAs, u, v]], output: v cot neg, tags: [trig], explain: "The derivative of -cot {v} is 1/sin²{v}." }\n - { id: i-sin-squared, name: Integral of sin², mode: integrate, pattern: u sin 2 ^ v 2 int, require: [[sameAs, u, v]], output: v 2 / 2 v * sin 4 / -, tags: [trig], explain: "sin²{v} = (1 - cos 2{v})/2, which integrates term by term." }\n - { id: i-cos-squared, name: Integral of cos², mode: integrate, pattern: u cos 2 ^ v 2 int, require: [[sameAs, u, v]], output: v 2 / 2 v * sin 4 / +, tags: [trig], explain: "cos²{v} = (1 + cos 2{v})/2, which integrates term by term." }\n - { id: i-sinh, name: Integral of sinh, mode: integrate, pattern: u sinh v 2 int, require: [[sameAs, u, v]], output: v cosh, tags: [trig], explain: "The derivative of cosh {v} is sinh {v}." }\n - { id: i-cosh, name: Integral of cosh, mode: integrate, pattern: u cosh v 2 int, require: [[sameAs, u, v]], output: v sinh, tags: [trig], explain: "The derivative of sinh {v} is cosh {v}." }\n - { id: i-arctan, name: Integral of 1/(1 + x²), mode: integrate, pattern: 1 u 2 ^ 1 + / v 2 int, require: [[sameAs, u, v]], output: v arctan, tags: [trig], explain: "The derivative of arctan {v} is 1/(1 + {v}²)." }\n - { id: i-arcsin, name: Integral of 1/√(1 - x²), mode: integrate, pattern: 1 u 2 ^ neg 1 + sqrt / v 2 int, require: [[sameAs, u, v]], output: v arcsin, tags: [trig], explain: "The derivative of arcsin {v} is 1/√(1 - {v}²)." }\n','name: Values and identities\n\n# The CAS\'s simplify rules (mode: simplify). They see expressions in normal form\n# (src/cas/form.js), as drawn: x/2, 2x - 3, -x, √x is "x sqrt",\n# ∛x is "3 x root", π/6 is "=pi 6 /", 2π/3 is "2 =pi * 3 /", e^x is "=e x ^".\n#\n# - a word is a slot (u, v, n …); a fixed symbol is written =pi, =e\n# - a number is itself; "1 2 /" is ½\n# - arithmetic (2 + 3, x + x, √8 = 2√2) is done for you before and after every rule\n# - a rule for a sum or product of two parts also fires on any two parts of a longer one\n# - tags pick what a step list shows (steps: \'brief\' hides value, identity, tidy …)\n#\n# To change one: copy it into a file of your own with the same id and edit it;\n# to turn one off: give its id with enabled: false. createCAS({ rules: [yours] }).\n\nrules:\n # ---- logs and exponentials -------------------------------------------\n - id: ln-one\n name: Log of 1\n pattern: 1 ln\n output: "0"\n explain: "e^0 = 1, so ln 1 = 0."\n tags: [value]\n\n - id: ln-e\n name: Log of e\n pattern: =e ln\n output: "1"\n explain: "e^1 = e, so ln e = 1."\n tags: [value]\n\n - id: ln-exp\n name: Log undoes e to a power\n pattern: =e u ^ ln\n output: u\n explain: "ln and e^ undo each other: ln(e^{u}) = {u}."\n tags: [inverse]\n\n - id: exp-ln\n name: e to a power undoes the log\n pattern: =e u ln ^\n output: u\n explain: "e^ and ln undo each other: e^(ln {u}) = {u} (for {u} > 0)."\n tags: [inverse]\n\n - id: exp-multiple-ln\n name: A multiple of a log in a power\n pattern: =e n u ln * ^\n when:\n n: [isRational]\n output: u n ^\n explain: "e^({n} ln {u}) = (e^(ln {u}))^{n} = {result}."\n tags: [inverse]\n\n - id: log-same-base\n name: Log of its own base\n pattern: b b log\n output: "1"\n explain: "{b}^1 = {b}, so the log of {b} to base {b} is 1."\n tags: [value]\n\n - id: log-of-power\n name: Log undoes a power of its base\n pattern: b b u ^ log\n output: u\n explain: "log base {b} and {b}^ undo each other."\n tags: [inverse]\n\n - id: power-of-log\n name: A power undoes the log to its base\n pattern: b b u log ^\n output: u\n explain: "{b}^(log base {b} of {u}) = {u}."\n tags: [inverse]\n\n # ---- roots and absolute value --------------------------------------------\n - id: sqrt-of-square\n name: Square root of a square\n pattern: u 2 ^ sqrt\n output: u abs\n explain: "√({u}²) is the size of {u}, whatever its sign: |{u}|."\n tags: [identity]\n\n - id: abs-squared\n name: Absolute value squared\n pattern: u abs 2 ^\n output: u 2 ^\n explain: "Squaring removes the sign anyway: |{u}|² = {u}²."\n tags: [identity]\n\n - id: abs-of-abs\n name: Absolute value twice\n pattern: u abs abs\n output: u abs\n explain: "|{u}| is never negative, so its absolute value is itself."\n tags: [identity]\n\n - id: abs-positive\n name: Absolute value of a positive number\n pattern: u abs\n when:\n u: [isPositiveConstant]\n output: u\n explain: "{u} is positive, so |{u}| = {u}."\n tags: [value]\n\n - id: abs-negative\n name: Absolute value of a negative number\n pattern: u abs\n when:\n u: [isNegativeConstant]\n output: u neg\n explain: "{u} is negative, so |{u}| = -({u})."\n tags: [value]\n\n - id: abs-of-exp\n name: e to a power is positive\n pattern: =e u ^ abs\n output: =e u ^\n explain: "e to any power is positive, so the absolute value changes nothing."\n tags: [identity]\n\n # ---- trigonometry: signs and turns ---------------------------------------\n - id: sin-odd\n name: Sine of a negative angle\n pattern: u sin\n when:\n u: [hasMinusSign]\n output: u neg sin neg\n explain: "sin(-θ) = -sin θ."\n tags: [symmetry]\n\n - id: cos-even\n name: Cosine of a negative angle\n pattern: u cos\n when:\n u: [hasMinusSign]\n output: u neg cos\n explain: "cos(-θ) = cos θ."\n tags: [symmetry]\n\n - id: tan-odd\n name: Tangent of a negative angle\n pattern: u tan\n when:\n u: [hasMinusSign]\n output: u neg tan neg\n explain: "tan(-θ) = -tan θ."\n tags: [symmetry]\n\n - id: sin-full-turn\n name: A full turn\n pattern: u sin\n when:\n u: [[piMultipleAtLeast, 2]]\n output: u 2 =pi * - sin\n explain: "Turning a full 2π brings you back: sin({u}) = sin({u} - 2π)."\n tags: [symmetry]\n\n - id: cos-full-turn\n name: A full turn\n pattern: u cos\n when:\n u: [[piMultipleAtLeast, 2]]\n output: u 2 =pi * - cos\n explain: "Turning a full 2π brings you back: cos({u}) = cos({u} - 2π)."\n tags: [symmetry]\n\n - id: tan-half-turn\n name: Tangent repeats every π\n pattern: u tan\n when:\n u: [[piMultipleAtLeast, 1]]\n output: u =pi - tan\n explain: "tan repeats every π: tan({u}) = tan({u} - π)."\n tags: [symmetry]\n\n - id: sin-half-turn\n name: A half turn\n pattern: u sin\n when:\n u: [[piMultipleAbove, 1], [piMultipleBelow, 2]]\n output: u =pi - sin neg\n explain: "Half a turn flips the sign: sin({u}) = -sin({u} - π)."\n tags: [symmetry]\n\n - id: cos-half-turn\n name: A half turn\n pattern: u cos\n when:\n u: [[piMultipleAbove, 1], [piMultipleBelow, 2]]\n output: u =pi - cos neg\n explain: "Half a turn flips the sign: cos({u}) = -cos({u} - π)."\n tags: [symmetry]\n\n - id: sin-second-quarter\n name: The second quarter turn\n pattern: u sin\n when:\n u: [[piMultipleAbove, 1/2], [piMultipleAtMost, 1]]\n output: =pi u - sin\n explain: "sin({u}) = sin(π - {u})."\n tags: [symmetry]\n\n - id: cos-second-quarter\n name: The second quarter turn\n pattern: u cos\n when:\n u: [[piMultipleAbove, 1/2], [piMultipleAtMost, 1]]\n output: =pi u - cos neg\n explain: "cos({u}) = -cos(π - {u})."\n tags: [symmetry]\n\n - id: tan-second-quarter\n name: The second quarter turn\n pattern: u tan\n when:\n u: [[piMultipleAbove, 1/2], [piMultipleBelow, 1]]\n output: =pi u - tan neg\n explain: "tan({u}) = -tan(π - {u})."\n tags: [symmetry]\n\n # ---- trigonometry: the standard angles -------------------------------------\n - { id: sin-0, name: Sine of 0, pattern: 0 sin, output: "0", tags: [value], explain: "sin 0 = 0." }\n - { id: sin-pi-6, name: Sine of π/6, pattern: =pi 6 / sin, output: 1 2 /, tags: [value], explain: "sin(π/6) = 1/2." }\n - { id: sin-pi-4, name: Sine of π/4, pattern: =pi 4 / sin, output: 2 sqrt 2 /, tags: [value], explain: "sin(π/4) = √2/2." }\n - { id: sin-pi-3, name: Sine of π/3, pattern: =pi 3 / sin, output: 3 sqrt 2 /, tags: [value], explain: "sin(π/3) = √3/2." }\n - { id: sin-pi-2, name: Sine of π/2, pattern: =pi 2 / sin, output: "1", tags: [value], explain: "sin(π/2) = 1." }\n - { id: sin-pi, name: Sine of π, pattern: =pi sin, output: "0", tags: [value], explain: "sin π = 0." }\n - { id: cos-0, name: Cosine of 0, pattern: 0 cos, output: "1", tags: [value], explain: "cos 0 = 1." }\n - { id: cos-pi-6, name: Cosine of π/6, pattern: =pi 6 / cos, output: 3 sqrt 2 /, tags: [value], explain: "cos(π/6) = √3/2." }\n - { id: cos-pi-4, name: Cosine of π/4, pattern: =pi 4 / cos, output: 2 sqrt 2 /, tags: [value], explain: "cos(π/4) = √2/2." }\n - { id: cos-pi-3, name: Cosine of π/3, pattern: =pi 3 / cos, output: 1 2 /, tags: [value], explain: "cos(π/3) = 1/2." }\n - { id: cos-pi-2, name: Cosine of π/2, pattern: =pi 2 / cos, output: "0", tags: [value], explain: "cos(π/2) = 0." }\n - { id: cos-pi, name: Cosine of π, pattern: =pi cos, output: "-1", tags: [value], explain: "cos π = -1." }\n - { id: tan-0, name: Tangent of 0, pattern: 0 tan, output: "0", tags: [value], explain: "tan 0 = 0." }\n - { id: tan-pi-6, name: Tangent of π/6, pattern: =pi 6 / tan, output: 3 sqrt 3 /, tags: [value], explain: "tan(π/6) = √3/3." }\n - { id: tan-pi-4, name: Tangent of π/4, pattern: =pi 4 / tan, output: "1", tags: [value], explain: "tan(π/4) = 1." }\n - { id: tan-pi-3, name: Tangent of π/3, pattern: =pi 3 / tan, output: 3 sqrt, tags: [value], explain: "tan(π/3) = √3." }\n - { id: arcsin-0, name: Arcsine of 0, pattern: 0 arcsin, output: "0", tags: [value], explain: "sin 0 = 0, so arcsin 0 = 0." }\n - { id: arcsin-half, name: Arcsine of 1/2, pattern: 1 2 / arcsin, output: =pi 6 /, tags: [value], explain: "sin(π/6) = 1/2, so arcsin(1/2) = π/6." }\n - { id: arcsin-1, name: Arcsine of 1, pattern: 1 arcsin, output: =pi 2 /, tags: [value], explain: "sin(π/2) = 1, so arcsin 1 = π/2." }\n - { id: arccos-0, name: Arccosine of 0, pattern: 0 arccos, output: =pi 2 /, tags: [value], explain: "cos(π/2) = 0, so arccos 0 = π/2." }\n - { id: arccos-half, name: Arccosine of 1/2, pattern: 1 2 / arccos, output: =pi 3 /, tags: [value], explain: "cos(π/3) = 1/2, so arccos(1/2) = π/3." }\n - { id: arccos-1, name: Arccosine of 1, pattern: 1 arccos, output: "0", tags: [value], explain: "cos 0 = 1, so arccos 1 = 0." }\n - { id: arccos-minus-1, name: Arccosine of -1, pattern: -1 arccos, output: =pi, tags: [value], explain: "cos π = -1, so arccos(-1) = π." }\n - { id: arctan-0, name: Arctangent of 0, pattern: 0 arctan, output: "0", tags: [value], explain: "tan 0 = 0, so arctan 0 = 0." }\n - { id: arctan-1, name: Arctangent of 1, pattern: 1 arctan, output: =pi 4 /, tags: [value], explain: "tan(π/4) = 1, so arctan 1 = π/4." }\n - { id: sinh-0, name: sinh of 0, pattern: 0 sinh, output: "0", tags: [value], explain: "sinh 0 = 0." }\n - { id: cosh-0, name: cosh of 0, pattern: 0 cosh, output: "1", tags: [value], explain: "cosh 0 = 1." }\n - { id: tanh-0, name: tanh of 0, pattern: 0 tanh, output: "0", tags: [value], explain: "tanh 0 = 0." }\n\n - { id: arctan-sqrt3, name: Arctangent of √3, pattern: 3 sqrt arctan, output: =pi 3 /, tags: [value], explain: "tan(π/3) = √3, so arctan √3 = π/3." }\n - { id: arctan-sqrt3-over-3, name: Arctangent of √3/3, pattern: 3 sqrt 3 / arctan, output: =pi 6 /, tags: [value], explain: "tan(π/6) = √3/3, so arctan(√3/3) = π/6." }\n\n # atan2(y, x): the angle of the point (x, y), in (-π, π]\n - id: atan2-right\n name: The angle of a point to the right\n pattern: y x atan2\n when:\n x: [isPositiveConstant]\n output: y x / arctan\n explain: "For x > 0, atan2(y, x) = arctan(y/x)."\n tags: [value]\n - id: atan2-left-up\n name: The angle of a point to the left\n pattern: y x atan2\n when:\n x: [isNegativeConstant]\n y: [isPositiveConstant]\n output: y x / arctan =pi +\n explain: "For x < 0 and y > 0, atan2(y, x) = arctan(y/x) + π."\n tags: [value]\n - id: atan2-left-down\n name: The angle of a point to the left\n pattern: y x atan2\n when:\n x: [isNegativeConstant]\n y: [isNegativeConstant]\n output: y x / arctan =pi -\n explain: "For x < 0 and y < 0, atan2(y, x) = arctan(y/x) - π."\n tags: [value]\n - { id: atan2-negative-axis, name: The angle of a point on the negative axis, pattern: 0 x atan2, when: { x: [isNegativeConstant] }, output: =pi, tags: [value], explain: "A point on the negative x-axis is at angle π." }\n - { id: atan2-up, name: Straight up, pattern: y 0 atan2, when: { y: [isPositiveConstant] }, output: =pi 2 /, tags: [value], explain: "A point straight up is at angle π/2." }\n - { id: atan2-down, name: Straight down, pattern: y 0 atan2, when: { y: [isNegativeConstant] }, output: =pi 2 / neg, tags: [value], explain: "A point straight down is at angle -π/2." }\n\n # the odd inverses take the sign out; arccos(-u) = π - arccos u\n - id: arcsin-odd\n name: Arcsine of a negative\n pattern: u arcsin\n when:\n u: [hasMinusSign]\n output: u neg arcsin neg\n explain: "arcsin(-x) = -arcsin x."\n tags: [symmetry]\n\n - id: arctan-odd\n name: Arctangent of a negative\n pattern: u arctan\n when:\n u: [hasMinusSign]\n output: u neg arctan neg\n explain: "arctan(-x) = -arctan x."\n tags: [symmetry]\n\n - id: arccos-negative\n name: Arccosine of a negative\n pattern: u arccos\n when:\n u: [hasMinusSign]\n output: =pi u neg arccos -\n explain: "arccos(-x) = π - arccos x."\n tags: [symmetry]\n\n # ---- trigonometry: identities --------------------------------------------\n - id: pythagorean\n name: sin² + cos² = 1\n pattern: u sin 2 ^ u cos 2 ^ +\n commutative: true\n output: "1"\n explain: "sin²{u} + cos²{u} = 1 for every angle."\n tags: [identity]\n\n - id: pythagorean-multiple\n name: sin² + cos² = 1\n pattern: a u sin 2 ^ * a u cos 2 ^ * +\n commutative: true\n output: a\n explain: "{a}·sin²{u} + {a}·cos²{u} = {a}(sin²{u} + cos²{u}) = {a}."\n tags: [identity]\n\n - id: one-minus-sin-squared\n name: 1 - sin² = cos²\n pattern: u sin 2 ^ neg 1 +\n output: u cos 2 ^\n explain: "1 - sin²{u} = cos²{u}."\n tags: [identity]\n\n - id: one-minus-cos-squared\n name: 1 - cos² = sin²\n pattern: u cos 2 ^ neg 1 +\n output: u sin 2 ^\n explain: "1 - cos²{u} = sin²{u}."\n tags: [identity]\n\n - id: sin-over-cos\n name: sin/cos is tan\n pattern: u sin u cos /\n output: u tan\n explain: "sin {u} / cos {u} = tan {u}."\n tags: [identity]\n\n - id: cos-over-sin\n name: cos/sin is cot\n pattern: u cos u sin /\n output: u cot\n explain: "cos {u} / sin {u} = cot {u}."\n tags: [identity]\n\n - id: sin-arcsin\n name: sin undoes arcsin\n pattern: u arcsin sin\n output: u\n explain: "sin(arcsin {u}) = {u}."\n tags: [inverse]\n\n - id: cos-arccos\n name: cos undoes arccos\n pattern: u arccos cos\n output: u\n explain: "cos(arccos {u}) = {u}."\n tags: [inverse]\n\n - id: tan-arctan\n name: tan undoes arctan\n pattern: u arctan tan\n output: u\n explain: "tan(arctan {u}) = {u}."\n tags: [inverse]\n\n - id: cosh-squared-minus-sinh-squared\n name: cosh² - sinh² = 1\n pattern: u cosh 2 ^ u sinh 2 ^ -\n output: "1"\n explain: "cosh²{u} - sinh²{u} = 1."\n tags: [identity]\n\n # ---- logs: opt-in rewrites (run with cas.rewrite(x, \'expand-log\') or \'combine-log\') ----\n - id: ln-product\n name: Log of a product\n mode: expand-log\n pattern: a b * ln\n output: a ln b ln +\n explain: "ln({a}·{b}) = ln {a} + ln {b} (for positive {a}, {b})."\n tags: [log]\n\n - id: ln-quotient\n name: Log of a quotient\n mode: expand-log\n pattern: a b / ln\n output: a ln b ln -\n explain: "ln({a}/{b}) = ln {a} - ln {b} (for positive {a}, {b})."\n tags: [log]\n\n - id: ln-power\n name: Log of a power\n mode: expand-log\n pattern: a n ^ ln\n output: n a ln *\n explain: "ln({a}^{n}) = {n}·ln {a} (for positive {a})."\n tags: [log]\n\n - id: ln-root\n name: Log of a square root\n mode: expand-log\n pattern: a sqrt ln\n output: a ln 2 /\n explain: "ln √{a} = ½ ln {a}."\n tags: [log]\n\n - id: ln-sum-combine\n name: Sum of logs\n mode: combine-log\n pattern: a ln b ln +\n commutative: true\n output: a b * ln\n explain: "ln {a} + ln {b} = ln({a}·{b})."\n tags: [log]\n\n - id: ln-difference-combine\n name: Difference of logs\n mode: combine-log\n pattern: a ln b ln -\n output: a b / ln\n explain: "ln {a} - ln {b} = ln({a}/{b})."\n tags: [log]\n\n - id: ln-multiple-combine\n name: A multiple of a log\n mode: combine-log\n pattern: n a ln *\n when:\n n: [isRational]\n output: a n ^ ln\n explain: "{n}·ln {a} = ln({a}^{n})."\n tags: [log]\n','name: Solving by undoing\n\n# mode: isolate. Each rule undoes the outermost function on the side with the\n# unknown: ln u = r → u = e^r. The predicates hasVariable and freeOfVariable mean\n# "mentions / doesn\'t mention the unknown being solved for".\n#\n# The CAS does the rest itself: it moves terms without the unknown to the other\n# side, divides by a coefficient, and when the unknown appears in several places\n# it uses the polynomial methods (factoring, the quadratic formula) or splits a\n# product equal to 0. Every answer is checked in the original equation, so a\n# rule may give extra candidates (squaring both sides does): the wrong ones are\n# dropped, with a step saying so.\n#\n# An output can give several answers: `pm` (±) splits into two, and so does\n# `|` (or): "u r arcsin = u =pi r arcsin - = |".\n\nrules:\n - id: iso-swap\n name: Unknown on the left\n mode: isolate\n pattern: l r =\n when:\n l: [freeOfVariable]\n r: [hasVariable]\n output: r l =\n priority: 20\n explain: "Swap the sides so the unknown is on the left."\n tags: [tidy]\n\n - id: iso-ln\n name: Undo the log\n mode: isolate\n pattern: u ln r =\n when:\n u: [hasVariable]\n output: u =e r ^ =\n explain: "Raise e to each side: e^(ln {u}) = {u}."\n tags: [inverse]\n\n - id: iso-log\n name: Undo the log\n mode: isolate\n pattern: b u log r =\n when:\n u: [hasVariable]\n b: [freeOfVariable]\n output: u b r ^ =\n explain: "Raise {b} to each side: {b}^(log base {b} of {u}) = {u}."\n tags: [inverse]\n\n - id: iso-exp\n name: Undo e to a power\n mode: isolate\n pattern: =e u ^ r =\n when:\n u: [hasVariable]\n output: u r ln =\n explain: "Take ln of each side: ln(e^{u}) = {u}."\n tags: [inverse]\n\n - id: iso-exponential\n name: Undo a power of a number\n mode: isolate\n pattern: b u ^ r =\n when:\n u: [hasVariable]\n b: [freeOfVariable]\n output: u b r log =\n explain: "Take the log to base {b} of each side."\n tags: [inverse]\n\n - id: iso-square\n name: Undo the square\n mode: isolate\n pattern: u 2 ^ r =\n when:\n u: [hasVariable]\n output: u r sqrt pm =\n priority: 1\n explain: "Take the square root of each side; {u} can be positive or negative."\n tags: [inverse]\n\n - id: iso-even-power\n name: Undo an even power\n mode: isolate\n pattern: u n ^ r =\n when:\n u: [hasVariable]\n n: [isEvenWhole]\n output: u r 1 n / ^ pm =\n explain: "Take the root of each side (the {n}th root); {u} can be positive or negative."\n tags: [inverse]\n\n - id: iso-odd-power\n name: Undo an odd power\n mode: isolate\n pattern: u n ^ r =\n when:\n u: [hasVariable]\n n: [isOddWhole]\n output: u r 1 n / ^ =\n explain: "Take the root of each side (the {n}th root)."\n tags: [inverse]\n\n - id: iso-fractional-power\n name: Undo a power\n mode: isolate\n pattern: u n ^ r =\n when:\n u: [hasVariable]\n n: [isRational]\n output: u r 1 n / ^ =\n priority: -1\n explain: "Raise each side to the power 1/{n}."\n tags: [inverse]\n\n - id: iso-sqrt\n name: Undo the square root\n mode: isolate\n pattern: u sqrt r =\n when:\n u: [hasVariable]\n output: u r 2 ^ =\n explain: "Square each side (this can add answers, so each one is checked at the end)."\n tags: [inverse]\n\n - id: iso-root\n name: Undo the root\n mode: isolate\n pattern: n u root r =\n when:\n u: [hasVariable]\n n: [freeOfVariable]\n output: u r n ^ =\n explain: "Raise each side to the power {n}."\n tags: [inverse]\n\n - id: iso-reciprocal\n name: Undo the fraction\n mode: isolate\n pattern: c u / r =\n when:\n u: [hasVariable]\n c: [freeOfVariable]\n output: u c r / =\n explain: "{c}/{u} = {r}, so {u} = {c}/{r}."\n tags: [inverse]\n\n - id: iso-abs\n name: Undo the absolute value\n mode: isolate\n pattern: u abs r =\n when:\n u: [hasVariable]\n output: u r pm =\n explain: "|{u}| = {r} means {u} is {r} or -{r}."\n tags: [inverse]\n\n - id: iso-sin\n name: Undo the sine\n mode: isolate\n pattern: u sin r =\n when:\n u: [hasVariable]\n output: u r arcsin = u =pi r arcsin - = |\n explain: "Two angles in a turn have sine {r}: arcsin {r} and π - arcsin {r} (add any whole number of turns, 2πk, for the rest)."\n tags: [inverse, trig]\n\n - id: iso-cos\n name: Undo the cosine\n mode: isolate\n pattern: u cos r =\n when:\n u: [hasVariable]\n output: u r arccos pm =\n explain: "Two angles in a turn have cosine {r}: ±arccos {r} (add 2πk for the rest)."\n tags: [inverse, trig]\n\n - id: iso-tan\n name: Undo the tangent\n mode: isolate\n pattern: u tan r =\n when:\n u: [hasVariable]\n output: u r arctan =\n explain: "Take arctan of each side (add πk for the rest)."\n tags: [inverse, trig]\n\n - { id: iso-arcsin, name: Undo arcsin, mode: isolate, pattern: u arcsin r =, when: { u: [hasVariable] }, output: u r sin =, tags: [inverse], explain: "Take sin of each side." }\n - { id: iso-arccos, name: Undo arccos, mode: isolate, pattern: u arccos r =, when: { u: [hasVariable] }, output: u r cos =, tags: [inverse], explain: "Take cos of each side." }\n - { id: iso-arctan, name: Undo arctan, mode: isolate, pattern: u arctan r =, when: { u: [hasVariable] }, output: u r tan =, tags: [inverse], explain: "Take tan of each side." }\n - { id: iso-sinh, name: Undo sinh, mode: isolate, pattern: u sinh r =, when: { u: [hasVariable] }, output: u r arcsinh =, tags: [inverse], explain: "Take arcsinh of each side." }\n - { id: iso-tanh, name: Undo tanh, mode: isolate, pattern: u tanh r =, when: { u: [hasVariable] }, output: u r arctanh =, tags: [inverse], explain: "Take arctanh of each side." }\n - { id: iso-cosh, name: Undo cosh, mode: isolate, pattern: u cosh r =, when: { u: [hasVariable] }, output: u r arccosh pm =, tags: [inverse], explain: "Two numbers have cosh {r}: ±arccosh {r}." }\n - { id: iso-arcsinh, name: Undo arcsinh, mode: isolate, pattern: u arcsinh r =, when: { u: [hasVariable] }, output: u r sinh =, tags: [inverse], explain: "Take sinh of each side." }\n - { id: iso-arccosh, name: Undo arccosh, mode: isolate, pattern: u arccosh r =, when: { u: [hasVariable] }, output: u r cosh =, tags: [inverse], explain: "Take cosh of each side." }\n - { id: iso-arctanh, name: Undo arctanh, mode: isolate, pattern: u arctanh r =, when: { u: [hasVariable] }, output: u r tanh =, tags: [inverse], explain: "Take tanh of each side." }\n'],Lr=['name: Complex numbers\n\n# Loaded only by createCAS({ complex: true }), where i is the imaginary unit.\n# The arithmetic (i² = -1, √-4 = 2i, (2 + 3i)(1 - i) = 5 + i, 1/(1 + i) = (1 - i)/2)\n# and Re, Im, conj, arg, |z| are the normal form\'s (src/cas/form.js); unknowns\n# count as real, so Re(x + 3i) = x. Write a complex unknown as a + bi.\n\noperators:\n - { symbol: re, arity: 1, label: real part }\n - { symbol: im, arity: 1, label: imaginary part }\n - { symbol: conj, arity: 1, label: complex conjugate }\n - { symbol: arg, arity: 1, label: argument }\n\nrules:\n - id: euler\n name: Euler\'s formula\n pattern: =e u ^\n when:\n u: [hasImaginaryPart, isConstant]\n output: =e u re ^ u im cos =i u im sin * + *\n explain: "e^(a + bi) = e^a (cos b + i sin b)."\n tags: [complex]\n\n - id: ln-negative\n name: Log of a negative number\n pattern: u ln\n when:\n u: [isNegativeConstant]\n output: u neg ln =i =pi * +\n explain: "{u} = |{u}|·e^(iπ), so ln {u} = ln |{u}| + iπ (the principal value)."\n tags: [complex]\n\n - id: ln-complex\n name: Log of a complex number\n pattern: u ln\n when:\n u: [hasImaginaryPart, isConstant]\n output: u abs ln u arg =i * +\n explain: "ln z = ln |z| + i arg z (the principal value)."\n tags: [complex]\n\n - id: i-to-the-i\n name: i to the power i\n pattern: =i =i ^\n output: =e =pi 2 / neg ^\n explain: "i = e^(iπ/2), so i^i = e^(i·iπ/2) = e^(-π/2) (the principal value)."\n tags: [complex]\n'],_r={normal:"Work out the numbers and collect like terms.","simplify.cancel":"Cancel the factors the top and bottom share.","simplify.expand":"Multiplying out gives something shorter.","simplify.factor":"Factoring gives something shorter.",expand:"Multiply out the brackets.",factor:"Write it as a product of factors.","factor.common":"Take out the common factor {common}.","factor.polynomial":"Factor what is left: {roots}.",together:"Write it as one fraction over a common denominator.",cancel:"Cancel the factors the top and bottom share: {cancelled}.","solve.move":"Keep the terms with {v} on the left and move the others to the right.","solve.divide":"Divide both sides by {by}.","solve.multiply":"Multiply both sides by {by}.","solve.one-side":"Move everything to one side, so the equation reads … = 0.","solve.factor":"Factor the left side.","solve.zero-product":"A product is 0 exactly when one of its factors is 0.","solve.split":"There are two cases; solve each.","solve.quadratic":"The quadratic formula with a = {a}, b = {b}, c = {c}: {v} = (-b ± √(b² - 4ac)) / 2a, and b² - 4ac = {D}.","solve.no-real":"b² - 4ac = {D} is negative, so there are no real solutions.","solve.quadratic-complex":"The quadratic formula with a = {a}, b = {b}, c = {c}: {v} = (-b ± √(b² - 4ac)) / 2a. b² - 4ac = {D} is negative, so its square root is imaginary: √({D}) = {root}.","solve.roots":"{v}^{n} = {r} has {n} solutions, spaced evenly round a circle: |{r}|^(1/{n})·(cos θ + i sin θ), with θ = (arg {r} + 2πk)/{n} for k = 0 … {last}.","solve.clear-denominator":"Multiply both sides by {den} (an answer that makes it 0 is not allowed).","solve.substitute":"Write {u} for {kernel}: this is a polynomial in {u}.","solve.reject":"{value} is not a solution: {reason}.","solve.always":"This is true for every {v}.","solve.never":"This is never true, so there is no solution.","solve.unsolved":"There is no exact method here for solving for {v}; try { approximate: true }.","solve.numeric":"Found {count} solution(s) numerically.","system.eliminate":"Use one equation to remove {v} from the others.","integrate.expand":"Multiply out, then integrate term by term.","integrate.substitute":"Let {u} = {inside}, so d{u} = {a} d{v}.","integrate.back":"Put {inside} back for {u}.","integrate.parts":"By parts with u = {u} and dv = {dv} d{v}: ∫ u dv = u·v - ∫ v du, where v = {V} and du = {du} d{v}.","integrate.constant":"The number {c} comes out of the integral.","integrate.divide":"The top has at least the degree of the bottom: divide first.","integrate.partial-fractions":"Split the fraction into simple fractions, one for each factor below.","integrate.evaluate":"Evaluate {F} at {b} and at {a}, and subtract.",substitute:"Put in the values."},Hr=["normal","rewrite","simplify","expand","factor","cancel","diff","differentiate","integrate","solve","solveSystem","substitute","approximate","equivalent"];class Jr{constructor(e,n,t,r,s){this.set=e,this.messages=n,this.format=t,this.read=r,this.complex=s;for(const e of Hr){const n=Jr.prototype[e];this[e]=(...e)=>ae(s,()=>n.apply(this,e))}}node(e){if(e&&"object"==typeof e&&!Array.isArray(e)&&e.type)return e;if(Array.isArray(e))return U(e);if("string"!=typeof e)throw new Q("expected an expression");if(this.read){const n=this.read(e);return Array.isArray(n)?U(n):"string"==typeof n?R(n):n}return R(e)}step(e,n,t,r,s,o={}){return function(e,n,t,r,s,o,i,a,u=[]){const l=(o??"").replace(/\{(\w+)\}/g,(e,n)=>{const t=i?.[n];return void 0===t?e:"string"==typeof t?t:a(t)});return{id:e,name:n,tags:t,from:r.s,to:s.s,path:u,before:r.s,after:s.s,explanation:l}}(e,n,t,r,s,this.messages[e]??"",o,this.format)}result(e,n,t,r={}){let s=e;if(t.approximate&&s){s=$t(s,{digits:"number"==typeof t.approximate?t.approximate:15})}return{result:s,text:s?this.format(s):"",steps:Rt(n,Vt(t.steps)),...r}}variable(e,n){if(n)return n;const t=[...Ke(e)];return 1===t.length?t[0]:t.includes("x")?"x":t[0]??"x"}tidyStep(e,n){return e.s===n.s?[]:[this.step("normal","Work out and collect",["tidy","arithmetic"],e,n)]}normal(e){return Le(this.node(e))}rewrite(e,n,t={}){const r=this.node(e),s=this.set.view(n);if(!s.size)throw new Q(`no rules in mode "${n}" (modes: ${this.set.modes().join(", ")})`);const o=Bt(r,s,{format:this.format,order:t.order,variable:t.variable});return this.result(o.node,[...this.tidyStep(r,Le(r)),...o.steps],t)}simplify(e,n={}){const t=this.node(e),r=[...this.tidyStep(t,Le(t))],s=Bt(t,this.set.view("simplify"),{format:this.format});r.push(...s.steps);let o=s.node,i=null;const a=We(o),u=[],l=0===Ke(o).size,c=l?null:cr(a);c&&u.push({node:ar(c),id:"simplify.cancel",name:"Cancel"});const f=Bt(Qe(Wt(a)),this.set.view("simplify"),{format:this.format});u.push({node:f.node,id:"simplify.expand",name:"Multiply out"}),"add"!==a.k||l||u.push({node:ar(nr(a)),id:"simplify.factor",name:"Factor"});for(const e of u)W(e.node)<W(o)&&(i=this.step(e.id,e.name,["shorter"],o,e.node),o=e.node);return i&&r.push(i),this.result(o,r,n)}expand(e,n={}){const t=this.node(e),r=Qe(Wt(We(t)));return this.result(r,t.s===r.s?[]:[this.step("expand","Multiply out",["expand"],t,r)],n)}factor(e,n={}){const t=this.node(e),r=nr(We(t)),s=ar(r),o=[],i=r.notes.find(e=>"factor.common"===e.id);return s.s!==Le(t).s&&o.push(this.step(i?"factor.common":"factor","Factor",["factor"],t,s,i?{common:Qe(i.values.common)}:{})),this.result(s,o,n)}cancel(e,n={}){const t=this.node(e),r=We(t),s=cr(r);if(!s)return this.result(Le(t),this.tidyStep(t,Le(t)),n);const o=ar(s),i=lr(r),a=C("/",[Qe(i.num),Qe(i.den)]),u=[];return"/"===t.op&&a.s===Le(t).s||u.push(this.step("together","One fraction",["together"],t,a)),o.s!==a.s&&u.push(this.step("cancel","Cancel",["cancel"],a,o,{cancelled:s.cancelled.length?s.cancelled.map(e=>this.format(Qe(e))).join(", "):"numbers"})),this.result(o,u,n)}diff(e,n,t={}){const r=this.node(e),s=this.variable(r,n);let o=r;const i=[];for(let e=0;e<(t.order??1);e++){const e=Bt(C("der",[o,Z(s)]),this.set.view("differentiate"),{format:this.format,order:"pre"}),n=Bt(e.node,this.set.view("simplify"),{format:this.format});i.push(...e.steps,...n.steps),o=n.node}return this.result(o,i,t,{variable:s})}differentiate(e,n){const t=Bt(C("der",[e,Z(n)]),this.set.view("differentiate"),{format:this.format,order:"pre"});return Bt(t.node,this.set.view("simplify"),{format:this.format}).node}integrate(e,n,t={}){let r=this.node(e);const s=e=>void 0===e?null:this.node("number"==typeof e?String(e):e);let o=s(t.from),i=s(t.to);if(V(r)&&"int"===r.op){const[e,t,s,a]=r.args;n=t.token,s&&a&&(o=s,i=a),r=e}const a=this.variable(r,n),u=Er(this,r,a),l=Bt(u.node,this.set.view("simplify"),{format:this.format}),c=[...u.steps,...l.steps];if(o&&i){const e=zr(this,l.node,a,o,i,r);c.push(e.step);const n=Bt(e.value,this.set.view("simplify"),{format:this.format});return c.push(...n.steps),this.result(n.node,c,t,{antiderivative:l.node,variable:a})}let f=l.node;return t.constant&&(f=C("+",[f,Z(String(t.constant))])),this.result(f,c,t,{variable:a})}solve(e,n,t={}){const r=this.node(e),s=this.variable(r,n),o=hr(this,r,s,t);let i=o.solutions;if(t.approximate){const e="number"==typeof t.approximate?t.approximate:15;i=i.map(n=>$t(n,{digits:e}))}const a=i.map(e=>C("=",[Z(s),e])),u=a.length?a.reduce((e,n)=>e?C("|",[e,n]):n,null):null;return{solutions:i,result:u,variable:s,text:o.always?`true for every ${s}`:u?this.format(u):o.unsolved.length?`no exact solution found for ${s}`:"no solution",unsolved:o.unsolved.filter(e=>!e.always),always:o.always,steps:Rt(o.steps,Vt(t.steps))}}solveSystem(e,n,t={}){const r=e.map(e=>this.node(e)),s=n??[...new Set(r.flatMap(e=>[...Ke(e)]))].sort(),o=function(e,n,t){const r=[],s=n.map(n=>{const r=dr(n)?Se([We(n.args[0]),Ce(We(n.args[1]))]):We(n),s=t.map(n=>{const t=_t(r,n);if(!t||Math.max(0,...t.keys())>1)throw new Q(`not linear in ${n}`);const s=t.get(1)??ce(ee.ZERO);if(!he(s))throw new Q(`the coefficient of ${n} must be a number (it is ${e.format(Qe(s))})`);return s.q});let o=r;for(let e=0;e<t.length;e++)o=Se([o,Ne([ce(s[e].neg()),We(Z(t[e]))])]);for(const e of t)if(Ht(o,e))throw new Q(`not linear in ${e}`);return{coeffs:s,rhs:Ce(o)}}),o=()=>s.map(e=>fr(Qe(Se(e.coeffs.map((e,n)=>Ne([ce(e),We(Z(t[n]))])))),Qe(e.rhs))).reduce((e,n)=>e?C("&",[e,n]):n,null);let i=0;const a=[];for(let n=0;n<t.length&&i<s.length;n++){const u=s.findIndex((e,t)=>t>=i&&!e.coeffs[n].isZero);if(u<0)continue;[s[i],s[u]]=[s[u],s[i]];const l=o(),c=s[i],f=c.coeffs[n];c.coeffs=c.coeffs.map(e=>e.div(f)),c.rhs=Ne([ce(f.inv()),c.rhs]);for(let e=0;e<s.length;e++){if(e===i||s[e].coeffs[n].isZero)continue;const t=s[e].coeffs[n];s[e].coeffs=s[e].coeffs.map((e,n)=>e.sub(t.mul(c.coeffs[n]))),s[e].rhs=Se([s[e].rhs,Ne([ce(t.neg()),c.rhs])])}r.push(e.step("system.eliminate","Eliminate",["eliminate"],l,o(),{v:Z(t[n])})),a.push(n),i++}for(const e of s.slice(i))if(!he(e.rhs)||!e.rhs.q.isZero)return{solution:null,steps:r,status:"none"};if(a.length<t.length)return{solution:null,steps:r,status:"many"};const u=new Map;return a.forEach((e,n)=>u.set(t[e],Qe(s[n].rhs))),{solution:u,steps:r,status:"one"}}(this,r,s),i=o.solution?Object.fromEntries([...o.solution].map(([e,n])=>[e,n])):null,a="one"===o.status?s.map(e=>`${e} = ${this.format(i[e])}`).join(", "):"none"===o.status?"no solution":"infinitely many solutions";return{solution:i,status:o.status,text:a,steps:Rt(o.steps,Vt(t.steps))}}substitute(e,n,t={}){const r=this.node(e);let s=r;for(const[e,t]of Object.entries(n))s=br(s,e,"number"==typeof t?this.node(String(t)):this.node(t));const o=this.simplify(s,t),i=[this.step("substitute","Substitute",["substitute"],r,s)];return{...o,steps:[...Rt(i,Vt(t.steps)),...o.steps]}}defined(e){const n=this.set.view("define");return n.size?Bt(e,n,{format:this.format}).node:e}approximate(e,n={}){const t=this.defined(this.node(e));if(Ke(t).size&&!n.scope){const e=$t(Le(t),n);return{result:e,text:this.format(e),number:null,exact:!1}}const r=xt(t,n);return{result:r.node,text:r.text,number:r.number,re:r.re,im:r.im,exact:r.exact}}equivalent(e,n){const t=this.node(e),r=this.node(n),s=this.defined(C("-",[t,r])),o=this.simplify(s,{steps:!1}).result;if("num"===o.type&&"0"===o.token)return{equal:!0,how:"exact"};const i=[...Ke(s)];if(!i.length)try{return{equal:Math.abs(xt(s,{digits:30}).number)<1e-25,how:"numeric"}}catch{return{equal:!1,how:"numeric"}}const a=[.31,1.7,2.9,-.83,.57];let u=0;for(let e=0;e<a.length;e++){const n=Object.fromEntries(i.map((n,t)=>[n,String(a[(e+t)%a.length]+t/7)]));let t;try{t=xt(s,{digits:30,scope:n}).number}catch{continue}if(u++,Math.abs(t)>1e-20)return{equal:!1,how:"numeric"}}return{equal:u>0,how:"numeric"}}modes(){return this.set.modes()}}function Qr(e={}){const n=!1===e.defaults?[]:[...Wr,...e.complex?Lr:[]],{specs:t,messages:r}=function(e){Et();const n=[],t={};for(const r of e){const e="string"==typeof r?Tn(r):r,s=Array.isArray(e)?e:e?.rules??[];for(const n of(Array.isArray(e)?[]:e?.operators)??[]){if(!n?.symbol)throw new Error("an operator needs a symbol");S(n.symbol)||q({symbol:String(n.symbol),arity:"any"===n.arity?y:Number(n.arity),label:n.label})}Object.assign(t,(Array.isArray(e)?null:e?.messages)??{});for(const e of s)n.push(e)}return{specs:n,messages:t}}([...n,...e.rules??[]]),s=ae(e.complex,()=>Tt(t));return new Jr(s,{..._r,...r},e.format??Cr,e.read??null,Boolean(e.complex))}function Yr(p){const d=p=>e("op"===p.type?function(e,o){const{op:p,args:d}=e,[h,m]=d,g=(e,n)=>i(p,a(e),n)?`(${o(e)})`:o(e),v=()=>d.map(o).join(", "),b=e=>f(p,e)?`(${o(e)})`:o(e);if("*"===p&&n(e))return"-"+o(m);if("+"===p&&n(m))return`${g(h,"left")} ${o(m)}`;if("-"===p&&n(m))return`${g(h,"left")} + ${o(m).slice(1)}`;if("^"===p){const e=g(h,"left");return`${e.startsWith("-")?`(${e})`:e}^${g(m,"right")}`}if(Gr[p])return`${g(h,"left")} ${Gr[p]} ${g(m,"right")}`;if(Kr[p])return Kr[p][0]+v()+Kr[p][1];if(t(p))return`${r(p)}(${v()})`;switch(p){case"neg":return"-"+b(h);case"pmod":return`${o(h)} (mod ${o(m)})`;case"pm":return"±"+b(h);case"!":return b(h)+"!";case"\\not":return"¬"+b(h);case"sqrt":return`√(${o(h)})`;case"root":{const e="number"===h.type?{3:"∛",4:"∜"}[h.value]:null;return e?`${e}(${o(m)})`:`root(${o(h)}, ${o(m)})`}case"abs":return`|${o(h)}|`;case"floor":return`⌊${o(h)}⌋`;case"ceil":return`⌈${o(h)}⌉`;case"log":return`log_${"op"===h.type?`(${o(h)})`:o(h)}(${o(m)})`;case"loglog":return`ln(ln(${o(h)}))`;case"logloglog":return`ln(ln(ln(${o(h)})))`;case"perm":return`perm(${o(h)}, ${o(m)})`;case"comb":return`comb(${o(h)}, ${o(m)})`;case"_":return`${o(h)}_${o(m)}`;case"?:":return`${o(h)} ? ${o(m)} : ${o(d[2])}`;case"sum":return d.map(o).join(" + ");case"prod":return d.map(o).join(" * ");case"der":{const{n:n,body:t,by:r,variable:i}=s(e),a=n>1?`^${n}`:"";return i?`d${a}${o(t)}/d${o(r)}${a}`:`d${a}/d${o(r)}${a}(${o(t)})`}case"int":return function(e,n){const[t,r,s,o]=e,i=e.length>=2&&l(r)?n(r):c(t)||"x",a=`${n(t)} d${i}`;switch(e.length){case 1:return`∫ ${a}`;case 2:return l(r)?`∫ ${a}`:`∫[${n(r)}] ${a}`;case 3:return l(r)?`∫[${n(s)}] ${a}`:`∫[${n(r)}, ${n(s)}] ${a}`;default:return`∫[${n(s)}, ${n(o)}] ${a}`}}(d,o);case"lim":return function(e,n){const[t,r,s,o]=e;switch(e.length){case 1:return`lim ${n(t)}`;case 2:return`lim[${n(r)}] ${n(t)}`;case 3:return`lim[${n(r)}→${n(s)}] ${n(t)}`;default:{const e=u(o).toLowerCase().startsWith("r")?"⁺":"⁻";return`lim[${n(r)}→${n(s)}${e}] ${n(t)}`}}}(d,o);case"\\sumidx":return Xr("∑",d,o);case"\\prodidx":return Xr("∏",d,o)}return`${p}(${v()})`}(p,d):function(e){const n=e.value;return"symbol"!==e.type?n:o[n]?o[n]:"\\+"===n||"\\-"===n?n[1]:n}(p));return d(p)}const Gr={"+":"+","-":"-","*":"*","/":"/","^":"^",mod:"mod","±":"±","=":"=","===":"===","≠":"≠","≠=":"≠","<":"<",">":">","≤":"≤","≥":"≥","∈":"∈","∉":"∉","→":"→","≈":"≈","∪":"∪","∩":"∩","≡":"≡","&":"∧","|":"∨","\\xor":"⊕","\\nand":"↑","\\nor":"↓"},Kr={"()":["(",")"],"[]":["[","]"],"{}":["{","}"],"(]":["(","]"],"[)":["[",")"]};function Xr(e,n,t){const[r,s,o]=n,i="∑"===e?"sum":"prod";return 3===n.length&&"op"===s.type&&"="===s.op?`${i}(${t(r)}, ${t(s)}, ${t(o)})`:2===n.length&&"op"===s.type&&"∈"===s.op?`${i}(${t(r)}, ${t(s)})`:1===n.length?`${e} ${t(r)}`:2===n.length?`${e}[${t(s)}] ${t(r)}`:`${e}[${t(s)}, ${t(o)}] ${t(r)}`}for(const e of[Gr,Kr])Object.setPrototypeOf(e,null);const es=new Map,ns={re:"Re",im:"Im",conj:"overline"},ts=["Re","Im","re","im","conj","arg"];function rs(e){const n=[],t=e=>{"op"===e.type?(e.args.forEach(t),m(e.op)?(-1===m(e.op).arity&&n.push(String(e.args.length)),n.push(e.op)):n.push(String(e.args.length),`\\:${ns[e.op]??e.op}`)):n.push(e.token)};return t(e),n}function ss(e={}){const n=e.rules||e.names?null:e.complex?"complex":"default";if(n&&es.has(n))return es.get(n);const t=[...e.names??[],...e.complex?ts:[]],r=Qr({...e,read:e=>h(e,t.length?{names:t}:{}),format:Cr});return n&&es.set(n,r),r}const os=new Set(["simplify","expand","factor","cancel","diff","integrate","solve","approx"]);function is(e={}){const n=e.cas??ss(),t=(e,r)=>{let s;try{s=n.read(e)}catch{return g(e,r)}const o=s[s.length-1],i=o?.startsWith("\\:")?o.slice(2):null,a=i&&os.has(i);if(!a&&!("der"===o||"int"===o))return g(e,r);const u=n.node(s),l=a?u.args:[u],c=e=>e?e.s:void 0;let f;try{switch(a?i:"der"===o?"derivative":"antiderivative"){case"simplify":f=n.simplify(l[0]);break;case"expand":f=n.expand(l[0]);break;case"factor":f=n.factor(l[0]);break;case"cancel":f=n.cancel(l[0]);break;case"diff":f=n.diff(l[0],c(l[1]),{order:l[2]?Number(l[2].s):1});break;case"integrate":f=n.integrate(l[0],c(l[1]),l[3]?{from:l[2].s,to:l[3].s}:{});break;case"solve":f=n.solve(l[0],c(l[1]));break;case"approx":f=n.approximate(l[0],{digits:l[1]?Number(l[1].s):15});break;case"derivative":f=n.diff(u.args[0],u.args[1].s);break;default:f=n.integrate(u)}}catch(n){return`(${e})`}if(t.last=f,!f.result)return`"${f.text}"`;const h=(m=rs(f.result),p(m)?"":Yr(d(m)));var m;return/^-?\d+(\.\d+)?$/.test(h)?h:`(${h})`};return t}const as=e=>String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;");function us(e,n={}){return`<ol class="mv-steps">${e.map(e=>{const t=rs(R(e.from)),r=v(t,{...n,highlight:e.path&&e.path.length?{path:e.path}:void 0}),s=e.to===e.from?"":`<span class="mv-step-arrow" aria-label="becomes">⟶</span>${v(rs(R(e.to)),n)}`,o=e.explanation?`<p class="mv-step-why">${as(e.explanation)}</p>`:"";return`<li class="mv-step" data-rule="${as(e.id)}"><span class="mv-step-name">${as(e.name)}</span><div class="mv-step-maths">${r}${s}</div>${o}</li>`}).join("")}</ol>`}export{is as casBlocks,ss as mathCAS,us as stepsHTML,rs as tokensOf};
1
+ /* Inline Math 0.2.0 — MIT licence; includes mathzetta (and @mathzetta/cas, for the CAS) */
2
+ import{q as e,r as n,M as t,u as r,v as s,w as o,x as i,G as a,y as u,z as l,A as c,B as f,m as p,C as d,E as h,h as m,F as g,H as v}from"./chunks/lite-3Fb-OHbt.js";import{c as b}from"./chunks/calculate-Cz87Lt0N.js";import{a as y}from"./chunks/html-CupluJSh.js";const w=new Map,x=-1,q="\\:",k=e=>"string"==typeof e&&e.startsWith(q)&&e.length>2;function $(e){if(!e||!e.symbol)throw new Error("operator needs a symbol");if(!Number.isInteger(e.arity)||e.arity<0&&e.arity!==x)throw new Error(`operator "${e.symbol}" needs an integer arity >= 0, or VARIADIC`);if(e.commutative&&2!==e.arity)throw new Error(`only binary operators can be commutative ("${e.symbol}")`);const n={symbol:e.symbol,arity:e.arity,commutative:!!e.commutative,fold:"function"==typeof e.fold?e.fold:null,label:e.label||e.symbol};return w.set(n.symbol,n),n}const S=Object.freeze({symbol:q,arity:x,commutative:!1,fold:null,label:"function"});function O(e){const n=w.get(e);return n||(k(e)?{...S,symbol:e,label:e.slice(2)}:null)}function N(e){return w.has(e)||k(e)}const A=e=>Number.isFinite(e)&&Number.isInteger(e)?e:null,I=e=>Number.isFinite(e)?e:null;!function(){$({symbol:"+",arity:2,commutative:!0,label:"add",fold:(e,n)=>I(e+n)}),$({symbol:"-",arity:2,label:"subtract",fold:(e,n)=>I(e-n)}),$({symbol:"*",arity:2,commutative:!0,label:"multiply",fold:(e,n)=>I(e*n)}),$({symbol:"/",arity:2,label:"divide",fold:(e,n)=>0===n?null:A(e/n)}),$({symbol:"^",arity:2,label:"power",fold:(e,n)=>Number.isInteger(n)&&Math.abs(n)<=64?I(e**n):null}),$({symbol:"neg",arity:1,label:"negate",fold:e=>I(-e)}),$({symbol:"pm",arity:1,label:"plus or minus"}),$({symbol:"±",arity:2,label:"plus or minus"}),$({symbol:"mod",arity:2,label:"modulo",fold:(e,n)=>0===n?null:A((e%n+n)%n)}),$({symbol:"!",arity:1,label:"factorial",fold:e=>Number.isInteger(e)&&e>=0&&e<=18?[...Array(e).keys()].reduce((e,n)=>e*(n+1),1):null}),$({symbol:"_",arity:2,label:"subscript"}),$({symbol:"der",arity:2,label:"derivative"}),$({symbol:"int",arity:x,label:"integral"}),$({symbol:"lim",arity:x,label:"limit"}),$({symbol:"\\sumidx",arity:x,label:"sum over an index"}),$({symbol:"\\prodidx",arity:x,label:"product over an index"}),$({symbol:"abs",arity:1,label:"absolute value",fold:e=>I(Math.abs(e))}),$({symbol:"floor",arity:1,label:"floor",fold:e=>I(Math.floor(e))}),$({symbol:"ceil",arity:1,label:"ceiling",fold:e=>I(Math.ceil(e))}),$({symbol:"round",arity:2,label:"round",fold:(e,n)=>Number.isInteger(n)?I(Math.round(e*10**n)/10**n):null}),$({symbol:"fixed",arity:2,label:"fixed",fold:()=>null}),$({symbol:"sqrt",arity:1,label:"square root",fold:e=>A(Math.sqrt(e))}),$({symbol:"root",arity:2,label:"nth root",fold:(e,n)=>A(Math.round(n**(1/e))**e===n?Math.round(n**(1/e)):NaN)});for(const e of["sin","cos","tan","csc","sec","cot","sinh","cosh","tanh","arcsin","arccos","arctan","arcsinh","arccosh","arctanh","ln","loglog","logloglog","expm1"])$({symbol:e,arity:1,label:e});$({symbol:"log",arity:2,label:"log to a base"}),$({symbol:"atan2",arity:2,label:"atan2"}),$({symbol:"perm",arity:2,label:"permutations"}),$({symbol:"comb",arity:2,label:"combinations"}),$({symbol:"random",arity:0,label:"random"});for(const e of["max","min","gcd","mean","sum","prod"])$({symbol:e,arity:x,label:e});for(const e of["()","[]","{}","(]","[)"])$({symbol:e,arity:x,label:"group"});for(const e of["pmatrix","bmatrix","vmatrix"])$({symbol:e,arity:x,label:"matrix"});$({symbol:"det",arity:1,label:"determinant"});for(const e of["=","===","≠","≠=","<",">","≤","≥","∈","∉","∪","∩","≈","≡","→","pmod","&","|","\\xor","\\nand","\\nor"])$({symbol:e,arity:2,label:e});$({symbol:"\\not",arity:1,label:"not"}),$({symbol:"?:",arity:3,label:"if then else"})}();const M="num",E="sym",T="op",j=Object.freeze([]);class Z extends Error{constructor(e){super(e),this.name="ExprError"}}function z(e){if("number"!=typeof e||!Number.isFinite(e))throw new Z(`not a finite number: ${e}`);const n=(t=e,Object.is(t,-0)?"0":String(t));var t;return Object.freeze({type:M,token:n,value:e,args:j,s:n})}function D(e){if("string"!=typeof e||""===e)throw new Z("symbol needs a non-empty token");return Object.freeze({type:E,token:e,value:null,args:j,s:e})}function B(e){const n=/^(-?)0*(\d+?)(?:\.(\d*?)0*)?$/.exec(String(e));if(!n)throw new Z(`not an exact decimal: ${e}`);const[,t,r,s=""]=n,o=s?`${r}.${s}`:r,i=/^0(\.0*)?$/.test(o)?"0":t+o;return Object.freeze({type:M,token:i,value:Number(i),args:j,s:i})}const C=/^-?\d+(\.\d+)?$/;function F(e){const n=String(e);if(C.test(n))return B(n);if(""!==n&&!/\s/.test(n)){const e=Number(n);if(Number.isFinite(e))return z(e)}return D(n)}function V(e,n){const t=O(e);if(!t)throw new Z(`unknown operator "${e}"`);if(t.arity!==x&&n.length!==t.arity)throw new Z(`"${e}" takes ${t.arity} operand(s), got ${n.length}`);const r=Object.freeze(n.slice()),s=t.arity===x?` ${r.length}`:"",o=`${r.length?r.map(e=>e.s).join(" "):""}${r.length,""}${s} ${e}`.trimStart();return Object.freeze({type:T,op:e,token:e,value:null,args:r,s:o})}const R=e=>e.type===M,U=e=>e.type===T;function P(e){return W(function(e){const n=String(e).trim();return""===n?[]:n.split(/\s+/)}(e))}function W(e){if(!Array.isArray(e))throw new Z("fromPostfix needs an array of tokens");if(0===e.length)throw new Z("empty expression");const n=[];for(let t=0;t<e.length;t++){const r=String(e[t]);if(N(r)){let e=O(r).arity;if(e===x){const s=n.pop();if(e=s&&s.type===M&&Number.isInteger(s.value)&&s.value>=0?s.value:-1,e<0)throw new Z(`"${r}" at position ${t+1} takes any number of operands, so a count must come before it`)}if(n.length<e)throw new Z(`"${r}" at position ${t+1} needs ${e} operand(s), only ${n.length} on the stack`);const s=n.splice(n.length-e,e);n.push(V(r,s))}else n.push(F(r))}if(1!==n.length){const t=[...new Set(e.filter(e=>!N(e)))];throw new Z(`expression leaves ${n.length} values on the stack; it should leave exactly 1. Read as operands: ${t.join(", ")} — is one of those meant to be an operator?`)}return n[0]}function L(e){if(e.type!==T)return 0;let n=0;for(const t of e.args)n=Math.max(n,L(t));return n+1}function _(e){if(e.type!==T)return 1;let n=1;for(const t of e.args)n+=_(t);return n}function H(e,n=[]){if(e.type!==T)n.push(e.token);else for(const t of e.args)H(t,n);return n}function J(e){return e.type===M||e.type!==E&&e.args.every(J)}function Q(e,n="pre",t=[],r=[]){"pre"===n&&r.push({node:e,path:t});for(let s=0;s<e.args.length;s++)Q(e.args[s],n,t.concat(s),r);return"post"===n&&r.push({node:e,path:t}),r}function Y(e,n,t){if(0===n.length)return t;const[r,...s]=n,o=e.args.slice();return o[r]=Y(o[r],s,t),V(e.op,o)}class G extends Error{constructor(e){super(e),this.name="CasError"}}const K=1e5,X=e=>e<0n?-e:e,ee=e=>0n===e?0:X(e).toString(2).length;function ne(e,n){for(e=X(e),n=X(n);n;)[e,n]=[n,e%n];return e}class te{constructor(e,n=1n){if(0n===n)throw new G("division by zero");n<0n&&(e=-e,n=-n);const t=ne(e,n)||1n;if(this.n=e/t,this.d=n/t,ee(this.n)>K||ee(this.d)>K)throw new G("a number too large to keep exactly")}static of(e){return new te(BigInt(e))}add(e){return new te(this.n*e.d+e.n*this.d,this.d*e.d)}sub(e){return new te(this.n*e.d-e.n*this.d,this.d*e.d)}mul(e){return new te(this.n*e.n,this.d*e.d)}div(e){if(0n===e.n)throw new G("division by zero");return new te(this.n*e.d,this.d*e.n)}neg(){return new te(-this.n,this.d)}abs(){return this.n<0n?this.neg():this}inv(){return te.ONE.div(this)}pow(e){if((e=BigInt(e))<0n)return this.inv().pow(-e);if((0n===this.n||1n===X(this.n))&&1n===this.d)return 0n===e||-1n===this.n&&e%2n==0n?te.ONE:this;if(BigInt(Math.max(ee(this.n),ee(this.d)))*e>BigInt(K))throw new G("a power too large to work out exactly");return new te(this.n**e,this.d**e)}get isZero(){return 0n===this.n}get isOne(){return 1n===this.n&&1n===this.d}get isInteger(){return 1n===this.d}get sign(){return this.n<0n?-1:this.n>0n?1:0}equals(e){return this.n===e.n&&this.d===e.d}compare(e){const n=this.n*e.d,t=e.n*this.d;return n<t?-1:n>t?1:0}floor(){const e=this.n/this.d;return new te(this.n<0n&&e*this.d!==this.n?e-1n:e)}ceil(){return this.neg().floor().neg()}toNumber(){const e=Number(this.n),n=Number(this.d);if(Number.isFinite(e)&&Number.isFinite(n))return e/n;const t=BigInt(Math.max(ee(this.n),ee(this.d))-1e3);return Number(this.n>>t)/Number(this.d>>t)}toString(){return 1n===this.d?String(this.n):`${this.n}/${this.d}`}}function re(e){const n=/^(-?)(\d*)(?:\.(\d*))?(?:[eE]([+-]?\d+))?$/.exec(String(e));if(!n||""===n[2]&&!n[3])return null;const[,t,r,s="",o="0"]=n;let i=new te(BigInt((r||"0")+s),10n**BigInt(s.length));const a=Number(o);return a&&(i=i.mul(te.of(10).pow(a))),t?i.neg():i}function se(e,n){if(e<2n)return e;if(n>=ee(e))return 1n;const t=BigInt(n);let r=1n<<BigInt(Math.ceil(ee(e)/n));for(;;){const n=((t-1n)*r+e/r**(t-1n))/t;if(n>=r)break;r=n}for(;r**t>e;)r--;for(;(r+1n)**t<=e;)r++;return r}te.ZERO=new te(0n),te.ONE=new te(1n),te.MINUS_ONE=new te(-1n),te.HALF=new te(1n,2n);const oe=(()=>{const e=[],n=new Uint8Array(1e4);for(let t=2;t<n.length;t++)if(!n[t]){e.push(BigInt(t));for(let e=t*t;e<n.length;e+=t)n[e]=1}return e})();function ie(e,n){const t=BigInt(n);let r=1n,s=1n,o=e;for(const e of oe){if(e*e>o)break;if(o%e)continue;let n=0n;for(;o%e===0n;)o/=e,n++;r*=e**(n/t),s*=e**(n%t)}if(o>1n){const e=function(e,n){if(e<0n)return null;if(e<2n)return e;const t=se(e,n);return t**BigInt(n)===e?t:null}(o,n);null!==e?r*=e:s*=o}return{outside:r,inside:s}}const ae=new Set(["pi","e","π"]),ue={complex:!1};function le(e,n){const t=ue.complex;ue.complex=Boolean(e);try{return n()}finally{ue.complex=t}}const ce=e=>ae.has(e)||ue.complex&&"i"===e,fe=e=>ue.complex&&"atom"===e.k&&"sym"===e.node.type&&"i"===e.node.token,pe=e=>({k:"num",q:e}),de=pe(te.ONE),he=pe(te.ZERO),me=pe(te.HALF),ge=e=>"num"===e.k,ve=e=>({k:"atom",node:e}),be=new WeakMap;function ye(e){let n=be.get(e);return void 0===n&&be.set(e,n=Ge(e).s),n}function we(e){if("num"===e.k)return 0;if("atom"===e.k)return"sym"===e.node.type&&ce(e.node.token)?0:1;if("add"===e.k)return Math.max(...e.terms.map(e=>we(e.x)));let n=0;for(const t of e.fs){const e=we(t.b);e&&(n+=e*(ge(t.e)?t.e.q.toNumber():1))}return n}function xe(e,n){return"num"===e.k?n&&!ge(n)?3:0:fe(e)?1.5:"atom"===e.k&&"sym"===e.node.type?ce(e.node.token)?n&&!ge(n)?3:1:2:"atom"===e.k?3:4}const qe=(e,n)=>e<n?-1:e>n?1:0;function ke(e){const n=new Map,t=(e,t)=>{"atom"!==e.k||"sym"!==e.node.type||ce(e.node.token)||n.set(e.node.token,(n.get(e.node.token)??0)+t)};if("mul"===e.k)for(const n of e.fs)t(n.b,ge(n.e)?n.e.q.toNumber():1);else t(e,1);return n}function $e(e,n){const t=we(n.x)-we(e.x);if(t)return t;const r=ke(e.x),s=ke(n.x);for(const e of[...new Set([...r.keys(),...s.keys()])].sort()){const n=(s.get(e)??0)-(r.get(e)??0);if(n)return n}return qe(ye(e.x),ye(n.x))}function Se(e,n){return e.isOne?n:e.isZero?he:Ie([pe(e),n])}function Oe(e){if("num"===e.k)return{coef:e.q,rest:null};if("mul"!==e.k||e.c.isOne)return{coef:te.ONE,rest:e};const n=1===e.fs.length&&ge(e.fs[0].e)&&e.fs[0].e.q.isOne?e.fs[0].b:{k:"mul",c:te.ONE,fs:e.fs};return{coef:e.c,rest:n}}function Ne(e){let n=te.ZERO;const t=new Map,r=(e,n)=>{const r=ye(n),s=t.get(r);s?s.coef=s.coef.add(e):t.set(r,{coef:e,x:n})};for(const t of e)if("num"===t.k)n=n.add(t.q);else if("add"===t.k){n=n.add(t.c);for(const e of t.terms)r(e.coef,e.x)}else{const{coef:e,rest:n}=Oe(t);r(e,n)}const s=[...t.values()].filter(e=>!e.coef.isZero);return s.length?n.isZero&&1===s.length?Se(s[0].coef,s[0].x):(s.sort($e),{k:"add",c:n,terms:s}):pe(n)}function Ae(e,n){if(!ge(n))return e.isOne?{coef:te.ONE,fs:[]}:{coef:te.ONE,fs:[{b:pe(e),e:n}]};const t=n.q;if(t.isInteger)return{coef:e.pow(t.n),fs:[]};if(e.isZero){if(t.sign<0)throw new G("division by zero");return{coef:te.ZERO,fs:[]}}if(e.isOne)return{coef:te.ONE,fs:[]};if(e.sign<0){if(t.d%2n==1n){const{coef:r,fs:s}=Ae(e.neg(),n);return{coef:t.n%2n==0n?r:r.neg(),fs:s}}if(ue.complex&&2n===t.d){const{coef:r,fs:s}=Ae(e.neg(),n);return{coef:r,fs:[...s,{b:Te,e:pe(new te(t.n))}]}}return{coef:te.ONE,fs:[{b:pe(e),e:n}]}}if(!e.isInteger){const r=Ae(new te(e.n),n),s=Ae(new te(e.d),pe(t.neg()));return{coef:r.coef.mul(s.coef),fs:[...r.fs,...s.fs]}}const r=t.floor(),s=t.sub(r);if(BigInt(ee(e.n))*s.n>BigInt(K)||s.d>1000n)return{coef:te.ONE,fs:[{b:pe(e),e:n}]};let o=r.isZero?te.ONE:e.pow(r.n);const{outside:i,inside:a}=ie(e.n**s.n,Number(s.d));o=o.mul(new te(i));return{coef:o,fs:a>1n?[{b:pe(new te(a)),e:pe(new te(1n,s.d))}]:[]}}function Ie(e){let n=te.ONE;const t=new Map,r=(e,n)=>{const r=ye(e),s=t.get(r);s?s.e=Ne([s.e,n]):t.set(r,{b:e,e:n})};for(const t of e)if("num"===t.k)n=n.mul(t.q);else if("mul"===t.k){n=n.mul(t.c);for(const e of t.fs)r(e.b,e.e)}else r(t,de);if(n.isZero)return he;const s=[],o=new Map;for(const e of t.values())if(!ge(e.e)||!e.e.q.isZero){if("num"===e.b.k){if(ge(e.e)&&!e.e.q.isInteger&&e.b.q.sign>0&&e.b.q.isInteger){const n=e.e.q.toString(),t=o.get(n);t?t.n*=e.b.q.n:o.set(n,{n:e.b.q.n,e:e.e});continue}const t=Ae(e.b.q,e.e);n=n.mul(t.coef),s.push(...t.fs);continue}if("mul"===e.b.k&&ge(e.e)&&e.e.q.isInteger){const t=Me(e.b,e.e);"mul"===t.k?(n=n.mul(t.c),s.push(...t.fs)):"num"===t.k?n=n.mul(t.q):s.push({b:t,e:de});continue}s.push(e)}for(const{n:e,e:t}of o.values()){const r=Ae(new te(e),t);n=n.mul(r.coef),s.push(...r.fs)}if(n.isZero)return he;const i=new Map;for(const e of s){const n=ye(e.b),t=i.get(n);t?t.e=Ne([t.e,e.e]):i.set(n,{...e})}let a=[...i.values()].filter(e=>!(ge(e.e)&&e.e.q.isZero));if(ue.complex){a=a.flatMap(e=>{if(!fe(e.b)||!ge(e.e)||!e.e.q.isInteger)return[e];const t=(e.e.q.n%4n+4n)%4n;return t>=2n&&(n=n.neg()),t%2n?[{b:e.b,e:de}]:[]});const e=a.filter(e=>"add"===e.b.k&&ge(e.e)&&e.e.q.isInteger&&Ze(e.b)),t=a.some(e=>fe(e.b)),r=e.every(e=>(e.e.q.sign<0?-e.e.q.n:e.e.q.n)<=60n);if(e.length&&r&&(e.length>1||t||!e[0].e.q.isOne)){const r=a.filter(n=>!e.includes(n)&&!fe(n.b));let s=t?[Te]:[de];for(const n of e){const e=n.e.q.sign<0?Be(n.b):n.b;for(let t=0n;t<(n.e.q.sign<0?-n.e.q.n:n.e.q.n);t++)s=ze(s,nn(e))}return Ie([pe(n),Ne(s),...r.map(e=>Ee(e.b,e.e))])}}if(a.some(e=>"num"===e.b.k&&ge(e.e)&&e.e.q.compare(te.ONE)>=0))return Ie([pe(n),...a.map(e=>"num"===e.b.k?Me(e.b,e.e):{k:"mul",c:te.ONE,fs:[e]})]);if(!a.length)return pe(n);if(1===a.length&&!n.isOne&&"add"===a[0].b.k&&ge(a[0].e)&&a[0].e.q.isOne){const e=a[0].b;return Ne([pe(n.mul(e.c)),...e.terms.map(e=>Se(n.mul(e.coef),e.x))])}return n.isOne&&1===a.length&&ge(a[0].e)&&a[0].e.q.isOne?a[0].b:(a=a.sort((e,n)=>xe(e.b,e.e)-xe(n.b,n.e)||qe(ye(e.b),ye(n.b))),{k:"mul",c:n,fs:a})}function Me(e,n){if(ue.complex&&ge(n)&&n.q.isInteger){if(fe(e))return Ie([{k:"mul",c:te.ONE,fs:[{b:e,e:n}]}]);if("add"===e.k&&Ze(e)&&!n.q.isOne)return Ie([{k:"mul",c:te.ONE,fs:[{b:e,e:n}]}])}if(ge(n)){if(n.q.isZero){if(ge(e)&&e.q.isZero)throw new G("0^0 is undefined");return de}if(n.q.isOne)return e}if(ge(e)){const t=Ae(e.q,n);if(!t.fs.length)return pe(t.coef);if(t.fs.some(e=>fe(e.b)))return Ie([pe(t.coef),...t.fs.map(e=>({k:"mul",c:te.ONE,fs:[e]}))]);const r={k:"mul",c:t.coef,fs:t.fs};return t.coef.isOne&&1===t.fs.length&&ge(t.fs[0].e)&&t.fs[0].e.q.isOne?t.fs[0].b:r}if(ue.complex&&ge(n)&&2n===n.q.d&&Ze(e)){const t=De(e);if(t&&ge(t.im)&&!t.im.q.isZero){const e=e=>Me(e,pe(te.of(2))),r=Me(Ne([e(t.re),e(t.im)]),me),s=Me(Ie([Ne([r,t.re]),pe(te.HALF)]),me),o=Me(Ie([Ne([r,Ve(t.re)]),pe(te.HALF)]),me);return Me(Ne([s,Ie([pe(te.of(t.im.q.sign)),o,Te])]),pe(new te(n.q.n)))}}if("mul"===e.k){if(ge(n)&&n.q.isInteger)return Ie([pe(e.c.pow(n.q.n)),...e.fs.map(e=>Ee(e.b,Ie([e.e,n])))]);if(!e.c.isOne&&e.c.sign>0)return Ie([Me(pe(e.c),n),Me({k:"mul",c:te.ONE,fs:e.fs},n)]);if(e.c.isOne&&1===e.fs.length){const[t]=e.fs;if(ge(t.e)&&ge(n)&&1n===t.e.q.n&&t.e.q.d%2n==1n)return Ee(t.b,Ie([t.e,n]))}}return{k:"mul",c:te.ONE,fs:[{b:e,e:n}]}}function Ee(e,n){return ge(n)&&n.q.isZero?de:ge(e)?Me(e,n):ge(n)&&n.q.isOne?e:{k:"mul",c:te.ONE,fs:[{b:e,e:n}]}}const Te=ve(D("i")),je=e=>ue.complex&&Ge(e).s.split(" ").includes("i");function Ze(e){return ue.complex&&je(e)&&0===en(Ge(e)).size}function ze(e,n){const t=[];for(const r of e)for(const e of n)t.push(Ie([r,e]));return nn(Ne(t))}function De(e){const n=[],t=[];for(const r of nn(e)){const{coef:e,rest:s}=Oe(r),o=s?tn(s):[],i=o.filter(e=>fe(e)),a=o.filter(e=>!fe(e));if(a.some(e=>je(e)))return null;(i.length?t:n).push(Ie([pe(e),...a]))}return{re:Ne(n),im:Ne(t)}}function Be(e){const n=De(e);if(!n)return Me(e,pe(te.MINUS_ONE));const t=Ne([Me(n.re,pe(te.of(2))),Me(n.im,pe(te.of(2)))]);return Ie([Ne([n.re,Ie([pe(te.MINUS_ONE),n.im,Te])]),Me(t,pe(te.MINUS_ONE))])}const Ce={re:([e])=>De(e)?.re??null,im:([e])=>De(e)?.im??null,conj:([e])=>{const n=De(e);return n?Ne([n.re,Ie([pe(te.MINUS_ONE),n.im,Te])]):null},arg:([e])=>{const n=De(e);return n?We("atan2",[n.im,n.re]):null},abs:([e])=>{const n=De(e);return!n||ge(n.im)&&n.im.q.isZero?null:Me(Ne([Me(n.re,pe(te.of(2))),Me(n.im,pe(te.of(2)))]),me)}},Fe={Re:"re",re:"re",Im:"im",im:"im",conj:"conj",overline:"conj",bar:"conj",arg:"arg"},Ve=e=>Ie([pe(te.MINUS_ONE),e]),Re=(e,n)=>Ie([e,Me(n,pe(te.MINUS_ONE))]),Ue=3000n,Pe={abs:([e])=>ge(e)?pe(e.q.abs()):"mul"!==e.k||e.c.isOne?null:Ie([pe(e.c.abs()),We("abs",[Oe(e).rest])]),floor:([e])=>ge(e)?pe(e.q.floor()):null,ceil:([e])=>ge(e)?pe(e.q.ceil()):null,"!":([e])=>{if(!ge(e)||!e.q.isInteger||e.q.sign<0||e.q.n>Ue)return null;let n=1n;for(let t=2n;t<=e.q.n;t++)n*=t;return pe(new te(n))},mod:([e,n])=>ge(e)&&ge(n)&&!n.q.isZero?pe(e.q.sub(n.q.mul(e.q.div(n.q).floor()))):null,max:e=>e.every(ge)&&e.length?e.reduce((e,n)=>n.q.compare(e.q)>0?n:e):null,min:e=>e.every(ge)&&e.length?e.reduce((e,n)=>n.q.compare(e.q)<0?n:e):null,gcd:e=>e.length&&e.every(e=>ge(e)&&e.q.isInteger)?pe(new te(e.reduce((e,n)=>ne(e,n.q.n),0n))):null,log:([e,n])=>{if(!ge(e)||!ge(n)||e.q.sign<=0||n.q.sign<=0||e.q.isOne)return null;if(n.q.isOne)return he;const t=Math.log(n.q.toNumber())/Math.log(e.q.toNumber());if(!Number.isFinite(t))return null;for(let r=1;r<=12;r++){const s=Math.round(t*r);if(!(Math.abs(t*r-s)>1e-9||0===s)&&(Math.abs(s)<=256&&e.q.pow(BigInt(s)).equals(n.q.pow(BigInt(r)))))return pe(new te(BigInt(s),BigInt(r)))}return null},comb:([e,n])=>ge(e)&&ge(n)&&e.q.isInteger&&n.q.isInteger&&e.q.sign>=0&&n.q.sign>=0&&e.q.n<=Ue?pe(function(e,n){if(n>e)return te.ZERO;n>e-n&&(n=e-n);let t=1n;for(let r=1n;r<=n;r++)t=t*(e-n+r)/r;return new te(t)}(e.q.n,n.q.n)):null,perm:([e,n])=>{if(!(ge(e)&&ge(n)&&e.q.isInteger&&n.q.isInteger&&e.q.sign>=0&&n.q.sign>=0&&e.q.n<=Ue))return null;if(n.q.n>e.q.n)return he;let t=1n;for(let r=0n;r<n.q.n;r++)t*=e.q.n-r;return pe(new te(t))}};function We(e,n){if(ue.complex&&Ce[e]){const t=Ce[e](n);if(t)return t}const t=Pe[e];if(t){const e=t(n);if(e)return e}return ve(V(e,n.map(Ge)))}const Le=new Map;function _e(e){const n=ue.complex?`ℂ ${e.s}`:e.s,t=Le.get(n);if(t)return t;const r=function(e){if("num"===e.type){const n=re(e.token);if(!n)throw new G(`not an exact number: ${e.token}`);return pe(n)}if("sym"===e.type)return"π"===e.token?ve(D("pi")):ve(e);const n=e.args.map(_e);switch(e.op){case"+":return Ne(n);case"-":return((e,n)=>Ne([e,Ve(n)]))(n[0],n[1]);case"neg":return Ve(n[0]);case"*":return Ie(n);case"/":return Re(n[0],n[1]);case"^":return Me(n[0],n[1]);case"sqrt":return Me(n[0],me);case"root":return Me(n[1],Me(n[0],pe(te.MINUS_ONE)));default:{const t=e.op.startsWith("\\:")?e.op.slice(2):null;return t&&ue.complex&&Fe[t]&&1===n.length?We(Fe[t],n):t&&N(t)&&O(t).arity===n.length?We(t,n):We(e.op,n)}}}(e);return Le.size>2e4&&Le.clear(),Le.set(n,r),r}const He=e=>Ge(_e(e)),Je=e=>B(String(e));function Qe(e){return e.isInteger?Je(e.n):V("/",[Je(e.n),Je(e.d)])}const Ye=new WeakMap;function Ge(e){let n=Ye.get(e);return n||Ye.set(e,n=function(e){switch(e.k){case"num":return Qe(e.q);case"atom":return e.node;case"mul":return function(e,n){const t=[],r=[];for(const e of n)ge(e.e)&&e.e.q.sign<0?r.push(Ke(e.b,pe(e.e.q.neg()))):t.push(Ke(e.b,e.e));let s=1n!==e.n&&-1n!==e.n||!t.length?Xe([Je(e.n),...t]):Xe(t);-1n===e.n&&t.length&&(s=V("neg",[s]));1n!==e.d&&r.unshift(Je(e.d));return r.length?V("/",[s,Xe(r)]):s}(e.c,e.fs);case"add":return function(e){let n=null;const t=e=>ue.complex&&je(e.x)&&0===en(Ge(e.x)).size,r=[...e.terms.filter(e=>!t(e)),...e.terms.filter(t)],s=e.c,o=()=>{s.isZero||(n=n?s.sign<0?V("-",[n,Qe(s.neg())]):V("+",[n,Qe(s)]):Qe(s))};let i=!1;for(const e of r)!i&&t(e)&&(o(),i=!0),n=n?e.coef.sign<0?V("-",[n,Ge(Se(e.coef.neg(),e.x))]):V("+",[n,Ge(Se(e.coef,e.x))]):Ge(Se(e.coef,e.x));i||o();return n}(e);default:throw new Error(`bad form ${e.k}`)}}(e)),n}function Ke(e,n){const t=Ge(e);if(ge(n)){const e=n.q;if(e.isOne)return t;if(1n===e.n&&2n===e.d)return V("sqrt",[t]);if(1n===e.n)return V("root",[Je(e.d),t])}return V("^",[t,Ge(n)])}const Xe=e=>e.reduce((e,n)=>e?V("*",[e,n]):n,null);function en(e,n=new Set){if("sym"===e.type)ce(e.token)||n.add(e.token);else if(U(e))for(const t of e.args)en(t,n);return n}function nn(e){if("add"!==e.k)return[e];const n=e.terms.map(e=>Se(e.coef,e.x));return e.c.isZero||n.push(pe(e.c)),n}function tn(e){if("num"===e.k)return[e];if("mul"!==e.k)return[e];const n=e.c.isOne?[]:[pe(e.c)];for(const t of e.fs)n.push(Ee(t.b,t.e));return n}const rn="_",sn=new WeakMap;function on(e,n){return[...n,...O(e.op)?.arity===x?[String(e.args.length)]:[],e.op].join(" ")}function an(e,n){let t=sn.get(e);t||sn.set(e,t=new Map);const r=t.get(n);if(r)return r;const s=function(e,n){const t={key:rn,slots:[e]};if(e.type!==T||n<=0)return[t];const r=e.args.map(e=>an(e,n-1)),s=[t],o=new Array(r.length).fill(0);for(;;){const n=[],t=[];for(let e=0;e<r.length;e++){const s=r[e][o[e]];n.push(s.key);for(const e of s.slots)t.push(e)}if(s.push({key:on(e,n),slots:t}),s.length>=4096)break;let i=r.length-1;for(;i>=0&&!(++o[i]<r[i].length);i--)o[i]=0;if(i<0)break}return s}(e,n);return t.set(n,s),s}function un(e){return e.type!==T?rn:on(e,e.args.map(un))}function ln(e,n=[]){if(e.type!==T)n.push(e);else for(const t of e.args)ln(t,n);return n}const cn=new Map,fn=new Map;class pn extends Error{constructor(e){super(e),this.name="RequirementError"}}function dn(e,n,t=""){cn.set(e,{name:e,fn:n,doc:t,arity:Math.max(0,n.length-1)})}function hn(e,n,t=""){fn.set(e,{name:e,fn:n,doc:t})}function mn(e){return cn.get(e)||null}function gn(e){return fn.get(e)||null}const vn=e=>e.type===M;function bn(e,n){return e.type===T&&(e.op===n||e.args.some(e=>bn(e,n)))}dn("always",()=>!0,"matches anything"),dn("never",()=>!1,"matches nothing"),dn("isLeaf",e=>e.type!==T,"a bare operand, not an operation"),dn("isCompound",e=>e.type===T,"an operation, not a bare operand"),dn("isSymbol",e=>e.type===E,"a non-numeric operand such as x"),dn("isOperation",(e,n)=>e.type===T&&e.op===n,"is this specific operation"),dn("notOperation",(e,n)=>!(e.type===T&&e.op===n),"is anything except this operation"),dn("isNumber",vn,"a numeric literal"),dn("isInteger",e=>vn(e)&&Number.isInteger(e.value),"a whole number"),dn("isPositive",e=>vn(e)&&e.value>0,"greater than zero"),dn("isNegative",e=>vn(e)&&e.value<0,"less than zero"),dn("isNonNegative",e=>vn(e)&&e.value>=0,"zero or greater"),dn("isZero",e=>vn(e)&&0===e.value,"exactly 0"),dn("isOne",e=>vn(e)&&1===e.value,"exactly 1"),dn("isNonZero",e=>vn(e)&&0!==e.value,"a number that is provably not 0"),dn("isNotZeroLiteral",e=>!(vn(e)&&0===e.value),"anything except a literal 0"),dn("isPositiveInteger",e=>vn(e)&&Number.isInteger(e.value)&&e.value>0,"a whole number above 0"),dn("isNegativeInteger",e=>vn(e)&&Number.isInteger(e.value)&&e.value<0,"a whole number below 0"),dn("isEven",e=>vn(e)&&Number.isInteger(e.value)&&e.value%2==0,"a whole even number"),dn("isOdd",e=>vn(e)&&Number.isInteger(e.value)&&1===Math.abs(e.value%2),"a whole odd number"),dn("greaterThan",(e,n)=>vn(e)&&e.value>Number(n),"above a given value"),dn("lessThan",(e,n)=>vn(e)&&e.value<Number(n),"below a given value"),dn("isValue",(e,n)=>vn(e)&&e.value===Number(n),"equals a given number"),dn("isNumeric",J,"contains no symbols: a constant (it need not fold to a number: 1 sin)"),dn("hasSymbol",e=>!J(e),"mentions a symbol somewhere, so it is not just a number"),dn("isVar",(e,n)=>e.type===E&&e.token===String(n),"is exactly this symbol"),dn("contains",(e,n)=>H(e).includes(String(n)),"mentions this operand somewhere"),dn("isFree",(e,n)=>!H(e).includes(String(n)),"never mentions this operand"),dn("hasOperation",(e,n)=>bn(e,String(n)),"uses this operation somewhere inside"),dn("equals",(e,n)=>e.s===String(n),"is exactly this postfix expression");const yn=e=>e.type===T?null:e.token;function wn(e){if("string"==typeof e)return{name:e,args:[]};if(Array.isArray(e)&&e.length>0&&"string"==typeof e[0])return{name:e[0],args:e.slice(1)};throw new pn(`bad requirement: ${JSON.stringify(e)}`)}hn("freeOf",(e,n)=>{const t=yn(n);return null!==t&&!H(e).includes(t)},"the first operand never mentions the second"),hn("dependsOn",(e,n)=>{const t=yn(n);return null!==t&&H(e).includes(t)},"the first operand does mention the second"),hn("sameAs",(...e)=>e.every(n=>n.s===e[0].s),"these operands are structurally identical"),hn("differs",(...e)=>new Set(e.map(e=>e.s)).size===e.length,"these operands are all different"),hn("sameValue",(...e)=>e.every(e=>vn(e))&&e.every(n=>n.value===e[0].value),"these operands are the same number");const xn="simplify";class qn extends Error{constructor(e,n){super(n?`rule "${n}": ${e}`:e),this.name="RuleError",this.ruleId=n}}const kn=/^[A-Za-z_][A-Za-z0-9_]*$/;function $n(e,n){if(R(e))return{literal:e.value};const t=e.token;if(t.startsWith("=")){const e=t.slice(1);if(""===e)throw new qn('"=" needs an operand after it',n);return{token:e}}if(!kn.test(t))throw new qn(`"${t}" is not a usable slot name; use letters, digits and _`,n);if(N(t))throw new qn(`slot name "${t}" collides with an operator`,n);return{name:t}}function Sn(e){if(!U(e))return[e];const n=e.args.map(Sn),t=O(e.op),r=[];for(const s of function(e){let n=[[]];for(const t of e){const e=[];for(const r of n)for(const n of t)e.push(r.concat([n]));if(n=e,n.length>64)return n.slice(0,64)}return n}(n))if(r.push(V(e.op,s)),t.commutative&&2===s.length&&s[0].s!==s[1].s&&r.push(V(e.op,[s[1],s[0]])),r.length>=64)break;return r}function On(e,n=[]){return"op"===e.kind?e.args.forEach(e=>On(e,n)):"const"===e.kind&&e.free&&n.push(e.node.token),n}function Nn(e){if(!e||"object"!=typeof e)throw new qn("rule must be a mapping");const n=e.id||e.name;if(!n)throw new qn("rule needs an id");if(!e.pattern)throw new qn("rule needs a pattern",n);if(void 0===e.output||null===e.output)throw new qn("rule needs an output",n);let t;try{t=P(String(e.pattern))}catch(e){if(e instanceof Z)throw new qn(`bad pattern: ${e.message}`,n);throw e}const r=ln(t).map(e=>$n(e,n)),s=new Set(r.filter(e=>e.name).map(e=>e.name)),o=function(e,n,t){const r=[],s=e.when||{};if("object"!=typeof s||Array.isArray(s))throw new qn('"when" must map slot names to lists of requirements',t);for(const[e,o]of Object.entries(s)){if(!n.has(e))throw new qn(`"when" mentions "${e}", which is not a slot in the pattern`,t);const s=Array.isArray(o)?o:[o];for(const n of s){const{name:s,args:o}=wn(n),i=mn(s);if(!i)throw new qn(`unknown requirement "${s}"`,t);r.push({slot:e,name:s,args:o,fn:i.fn})}}return r}(e,s,n),i=function(e,n,t){const r=[],s=e.require||[];if(!Array.isArray(s))throw new qn('"require" must be a list of relations',t);for(const e of s){const{name:s,args:o}=wn(e),i=gn(s);if(!i)throw new qn(`unknown relation "${s}"`,t);if(o.length<2)throw new qn(`relation "${s}" needs at least two operands`,t);for(const e of o)if("string"==typeof e&&!n.has(e)&&kn.test(e))throw new qn(`relation "${s}" mentions "${e}", which is not a slot in the pattern`,t);r.push({name:s,args:o,fn:i.fn})}return r}(e,s,n),a=function(e,n,t){let r;try{r=P(e)}catch(n){throw new qn(`bad output "${e}": ${n.message}`,t)}const s=e=>U(e)?{kind:"op",op:e.op,args:e.args.map(s)}:R(e)?{kind:"const",node:e}:n.has(e.token)?{kind:"slot",name:e.token}:e.token.startsWith("=")?{kind:"const",node:D(e.token.slice(1))}:{kind:"const",node:e,free:!0};return s(r)}(String(e.output),s,n),u=e.commutative?Sn(t):[t],l=[],c=new Set;for(const e of u){const t=un(e),r=ln(e).map(e=>$n(e,n)),s=t+"\0"+r.map(e=>e.name??(void 0!==e.literal?`#${e.literal}`:`=${e.token}`)).join(",");c.has(s)||(c.add(s),l.push({key:t,slots:r}))}const f={id:String(n),name:e.name?String(e.name):String(n),pattern:String(e.pattern),patternTree:t,output:String(e.output),outputTemplate:a,explain:e.explain?String(e.explain).trim():"",mode:e.mode?String(e.mode):xn,tags:Array.isArray(e.tags)?e.tags.map(String):[],priority:Number.isFinite(e.priority)?e.priority:0,fold:!!e.fold,commutative:!!e.commutative,enabled:void 0===e.enabled||!!e.enabled,when:o,require:i,slots:[...s],depth:L(t),bindings:l,freeSymbols:On(a),source:e};for(const e of l)e.rule=f;return f}function An(e){const n={};for(const t of e.when)(n[t.slot]||=[]).push(t.args.length?[t.name,...t.args]:t.name);const t={id:e.id};return e.name!==e.id&&(t.name=e.name),e.mode!==xn&&(t.mode=e.mode),t.pattern=e.pattern,Object.keys(n).length&&(t.when=n),e.require.length&&(t.require=e.require.map(e=>[e.name,...e.args])),t.output=e.output,e.explain&&(t.explain=e.explain),e.fold&&(t.fold=!0),e.commutative&&(t.commutative=!0),e.priority&&(t.priority=e.priority),e.tags.length&&(t.tags=e.tags),e.enabled||(t.enabled=!1),t}class In extends Error{constructor(e,n){super(null==n?e:`${e} (line ${n+1})`),this.name="YamlError",this.line=n}}class Mn{constructor(e){this.records=e,this.i=0,this.pushed=[]}peek(){if(this.pushed.length)return this.pushed[this.pushed.length-1];for(;this.i<this.records.length&&this.records[this.i].blank;)this.i++;return this.i<this.records.length?this.records[this.i]:null}next(){if(this.pushed.length)return this.pushed.pop();const e=this.peek();return e&&this.i++,e}push(e){this.pushed.push(e)}}const En=e=>"-"===e||e.startsWith("- ");function Tn(e){let n=null,t=0;for(let r=0;r<e.length;r++){const s=e[r];if(n)s===n?"'"===n&&"'"===e[r+1]?r++:n=null:'"'===n&&"\\"===s&&r++;else if('"'===s||"'"===s)n=s;else if("["===s||"{"===s)t++;else if("]"===s||"}"===s)t--;else if(":"===s&&0===t&&(r+1===e.length||" "===e[r+1])){const n=e.slice(0,r).trim();return""===n?null:{key:jn(n),rest:e.slice(r+1).trim()}}}return null}function jn(e){return e.length>=2&&'"'===e[0]&&'"'===e[e.length-1]?JSON.parse(e):e.length>=2&&"'"===e[0]&&"'"===e[e.length-1]?e.slice(1,-1).replace(/''/g,"'"):e}function Zn(e){const n=new Mn(function(e){return String(e).split(/\r?\n/).map((e,n)=>{const t=e.search(/\S/);if(-1===t)return{raw:e,n:n,indent:0,text:"",blank:!0};const r=function(e){let n=null;for(let t=0;t<e.length;t++){const r=e[t];if(n)r===n?"'"===n&&"'"===e[t+1]?t++:n=null:'"'===n&&"\\"===r&&t++;else if('"'===r||"'"===r)n=r;else if("#"===r&&(0===t||/\s/.test(e[t-1])))return e.slice(0,t)}return e}(e.slice(t)).trimEnd();return{raw:e,n:n,indent:t,text:r,blank:""===r}})}(e));let t=n.peek();if(t&&"---"===t.text&&(n.next(),t=n.peek()),!t)return null;const r=Dn(n,t.indent),s=n.peek();if(s&&"..."!==s.text&&"---"!==s.text)throw new In(`unexpected content "${s.text}"`,s.n);return r}const zn=/^[|>][-+]?\d*$/;function Dn(e,n){const t=e.peek();return!t||t.indent<n?null:En(t.text)?Bn(e,t.indent):Tn(t.text)?function(e,n){const t={};for(;;){const r=e.peek();if(!r||r.indent!==n)break;const s=Tn(r.text);if(!s)break;e.next();const{key:o,rest:i}=s;if(""===i){const r=e.peek();r&&r.indent>n?t[o]=Dn(e,r.indent):r&&r.indent===n&&En(r.text)?t[o]=Bn(e,n):t[o]=null}else zn.test(i)?t[o]=Cn(e,i,n):t[o]=Fn(i,r.n)}return t}(e,t.indent):(e.next(),zn.test(t.text)?Cn(e,t.text,t.indent-1):Fn(t.text,t.n))}function Bn(e,n){const t=[];for(;;){const r=e.peek();if(!r||r.indent!==n||!En(r.text))break;if(e.next(),"-"===r.text){const r=e.peek();t.push(r&&r.indent>n?Dn(e,r.indent):null);continue}if(zn.test(r.text.slice(2).trim())){t.push(Cn(e,r.text.slice(2).trim(),n));continue}const s=r.text.slice(2),o=n+2+(s.length-s.trimStart().length);e.push({raw:r.raw,n:r.n,indent:o,text:s.trim(),blank:!1}),t.push(Dn(e,o))}return t}function Cn(e,n,t){const r=n[0],s=(n.match(/[-+]/)||[""])[0],o=(n.match(/\d+/)||[null])[0];let i=o?t+Number(o):null;const a=[];for(;e.i<e.records.length;){const n=e.records[e.i];if(""===n.raw.trim()){a.push(""),e.i++;continue}const r=n.raw.search(/\S/);if(r<=t)break;if(null===i&&(i=r),r<i)break;a.push(n.raw.slice(i)),e.i++}for(;a.length&&""===a[a.length-1];)a.pop();let u;if("|"===r)u=a.join("\n");else{const e=[];for(const n of a)""===n?e.push("\n"):e.length&&"\n"!==e[e.length-1]?e[e.length-1]+=" "+n:e.push(n);u=e.join("").replace(/\n(?!$)/g,"\n")}return"-"===s?u:"+"===s?u+"\n":""===u?"":u+"\n"}function Fn(e,n){const t=e.trim();return""===t||"~"===t||"null"===t||"Null"===t||"NULL"===t?null:"true"===t||"True"===t||"TRUE"===t||"false"!==t&&"False"!==t&&"FALSE"!==t&&("["===t[0]||"{"===t[0]?function(e,n){const t={text:e,i:0,line:n},r=Rn(t);if(Vn(t),t.i<t.text.length)throw new In(`unexpected "${t.text.slice(t.i)}" in flow value`,n);return r}(t,n):'"'===t[0]||"'"===t[0]?jn(t):/^[-+]?(\d+\.?\d*|\.\d+)([eE][-+]?\d+)?$/.test(t)?Number(t):t)}const Vn=e=>{for(;e.i<e.text.length&&/\s/.test(e.text[e.i]);)e.i++};function Rn(e){Vn(e);const n=e.text[e.i];return"["===n?function(e){e.i++;const n=[];for(;;){if(Vn(e),e.i>=e.text.length)throw new In("unterminated [",e.line);if("]"===e.text[e.i])return e.i++,n;if(n.push(Rn(e)),Vn(e),","===e.text[e.i])e.i++;else if("]"!==e.text[e.i])throw new In(`expected , or ] near "${e.text.slice(e.i)}"`,e.line)}}(e):"{"===n?function(e){e.i++;const n={};for(;;){if(Vn(e),e.i>=e.text.length)throw new In("unterminated {",e.line);if("}"===e.text[e.i])return e.i++,n;const t=String(Rn(e));if(Vn(e),":"!==e.text[e.i])throw new In(`expected : after "${t}"`,e.line);if(e.i++,n[t]=Rn(e),Vn(e),","===e.text[e.i])e.i++;else if("}"!==e.text[e.i])throw new In(`expected , or } near "${e.text.slice(e.i)}"`,e.line)}}(e):Fn(function(e){const n=e.text[e.i];if('"'===n||"'"===n){const t=e.i;for(e.i++;e.i<e.text.length;)if("\\"===e.text[e.i]&&'"'===n)e.i+=2;else if(e.text[e.i]===n){if("'"!==n||"'"!==e.text[e.i+1])return e.i++,e.text.slice(t,e.i);e.i+=2}else e.i++;throw new In("unterminated quoted string",e.line)}const t=e.i;for(;e.i<e.text.length;){const n=e.text[e.i];if(","===n||"]"===n||"}"===n)break;if(":"===n){const n=e.text[e.i+1];if(void 0===n||/[\s,\]}]/.test(n))break}e.i++}return e.text.slice(t,e.i).trim()}(e),e.line)}const Un=/^(true|false|null|yes|no|on|off|~)$/i;function Pn(e){if(null==e)return"null";if("boolean"==typeof e)return e?"true":"false";if("number"==typeof e){if(!Number.isFinite(e))throw new In(`cannot serialise ${e}`);return String(e)}const n=String(e);return function(e){return!!(""===e||/^\s|\s$/.test(e)||/[\u0000-\u001f\u007f]/.test(e)||/^[-?:,[\]{}#&*!|>'"%@`]/.test(e)||/: |\s#/.test(e)||Un.test(e)||/^[-+]?(\d+\.?\d*|\.\d+)([eE][-+]?\d+)?$/.test(e))}(n)?JSON.stringify(n):n}const Wn=e=>null==e||"object"!=typeof e;function Ln(e){return Array.isArray(e)?`[${e.map(Ln).join(", ")}]`:e&&"object"==typeof e?`{${Object.entries(e).map(([e,n])=>`${Pn(e)}: ${Ln(n)}`).join(", ")}}`:Pn(e)}function _n(e){return Array.isArray(e)?!!e.every(e=>Wn(e)||Array.isArray(e)&&e.every(Wn))&&Ln(e).length<=72:!(!e||"object"!=typeof e)&&(Object.values(e).every(e=>Wn(e)||Array.isArray(e)&&e.every(Wn))&&Ln(e).length<=72)}function Hn(e){const n=[];return Jn(e,0,n),n.length?n.join("\n")+"\n":""}function Jn(e,n,t){const r=" ".repeat(n);if(Array.isArray(e)){if(0===e.length)return void t.push(r+"[]");for(const r of e)Qn(r,n,t)}else{if(e&&"object"==typeof e){const s=Object.entries(e).filter(([,e])=>void 0!==e);if(0===s.length)return void t.push(r+"{}");for(const[e,r]of s)Yn(e,r,n,t);return}!function(e,n,t){if("string"==typeof e&&e.includes("\n")){t.push(n+"|-");for(const r of e.replace(/\n+$/,"").split("\n"))t.push(n+" "+r);return}t.push(n+Pn(e))}(e,r,t)}}function Qn(e,n,t){const r=" ".repeat(n);if(null!==e&&"object"==typeof e&&!_n(e)){const s=[];if(Jn(e,n+2,s),0===s.length)return void t.push(r+"-");t.push(r+"- "+s[0].slice(n+2));for(let e=1;e<s.length;e++)t.push(s[e]);return}if(null===e||"object"!=typeof e)if("string"==typeof e&&e.includes("\n")){t.push(r+"- |-");for(const r of e.replace(/\n+$/,"").split("\n"))t.push(" ".repeat(n+4)+r)}else t.push(r+"- "+Pn(e));else t.push(r+"- "+Ln(e))}function Yn(e,n,t,r){const s=" ".repeat(t),o=Pn(e);if("string"==typeof n&&n.includes("\n")){r.push(`${s}${o}: |-`);for(const e of n.replace(/\n+$/,"").split("\n"))r.push(" ".repeat(t+2)+e)}else{if(null!==n&&"object"==typeof n)return _n(n)?void r.push(`${s}${o}: ${Ln(n)}`):(r.push(`${s}${o}:`),void Jn(n,Array.isArray(n)?t:t+2,r));r.push(`${s}${o}: ${Pn(n)}`)}}class Gn{constructor(e=[]){this.index=new Map,this.rules=[],this.maxDepth=0,this.name="",this.views=new Map;for(const n of e)this.add(n)}add(e){const n=e&&e.bindings?e:Nn(e);if(this.rules.some(e=>e.id===n.id))throw new qn(`duplicate rule id "${n.id}"`);return this.rules.push(n),n.enabled&&this.link(n),n.depth>this.maxDepth&&(this.maxDepth=n.depth),this.views.clear(),n}view(e){if(!e)return this;let n=this.views.get(e);return n||(n=new Gn(this.rules.filter(n=>n.mode===e)),n.name=this.name,this.views.set(e,n)),n}modes(){return[...new Set(this.rules.map(e=>e.mode))].sort((e,n)=>e===xn?-1:n===xn?1:e.localeCompare(n))}link(e){for(const n of e.bindings){let e=this.index.get(n.key);e||this.index.set(n.key,e=[]),e.push(n),e.sort((e,n)=>n.rule.priority-e.rule.priority||n.rule.depth-e.rule.depth)}}remove(e){const n=this.rules.findIndex(n=>n.id===e);return-1!==n&&(this.rules.splice(n,1),this.reindex(),!0)}setEnabled(e,n){const t=this.get(e);return!!t&&(t.enabled=!!n,this.reindex(),!0)}reindex(){this.index=new Map,this.maxDepth=0,this.views.clear();for(const e of this.rules)e.enabled&&this.link(e),e.depth>this.maxDepth&&(this.maxDepth=e.depth)}get(e){return this.rules.find(n=>n.id===e)||null}candidates(e){return this.index.get(e)||null}get size(){return this.rules.length}static fromYaml(e,{strict:n=!0}={}){const t=Zn(e);return Gn.fromSpecs(t,{strict:n})}static fromSpecs(e,{strict:n=!0}={}){let t=e,r="";if(e&&!Array.isArray(e)&&"object"==typeof e&&(t=e.rules,r=e.name?String(e.name):""),!Array.isArray(t))throw new qn('expected a list of rules, or a mapping with a "rules" list');const s=new Gn;s.name=r;const o=[];for(let e=0;e<t.length;e++)try{s.add(t[e])}catch(n){o.push(`#${e+1}: ${n.message}`)}if(o.length&&n)throw new qn(`${o.length} rule(s) failed to compile:\n ${o.join("\n ")}`);return s.errors=o,s}toSpecs(){return this.rules.map(An)}toYaml(){const e=this.toSpecs();return this.name?Hn({name:this.name,rules:e}):Hn(e)}keyReport(){return[...this.index.entries()].map(([e,n])=>({key:e,rules:n.map(e=>e.rule.id)})).sort((e,n)=>e.key.localeCompare(n.key))}}function Kn(e,n){const t=Object.create(null),r=e.slots;for(let e=0;e<r.length;e++){const s=r[e],o=n[e];if(void 0!==s.literal){if(!R(o)||o.value!==s.literal)return null;continue}if(void 0!==s.token){if(o.s!==s.token)return null;continue}const i=t[s.name];if(void 0!==i){if(i.s!==o.s)return null}else t[s.name]=o}return t}function Xn(e,n){for(const t of e.when){const e=n[t.slot];if(void 0===e)return!1;if(!t.fn(e,...t.args))return!1}for(const t of e.require){const e=t.args.map(e=>void 0!==n[e]?n[e]:e);if(!t.fn(...e))return!1}return!0}function et(e,n){return n.rule.priority-e.rule.priority||n.rule.depth-e.rule.depth}function nt(e,n){const t=[];if(0===n.maxDepth)return t;for(const{key:r,slots:s}of function(e,n){const t=an(e,n),r=[];for(const e of t)e.key!==rn&&r.push(e);return r}(e,n.maxDepth)){const e=n.candidates(r);if(e)for(const n of e){const e=Kn(n,s);e&&(Xn(n.rule,e)&&t.push({rule:n.rule,binding:n,key:r,bound:e}))}}return t.sort(et)}function tt(e,n){switch(e.kind){case"slot":{const t=n[e.name];if(!t)throw new Error(`output references unbound slot "${e.name}"`);return t}case"const":return e.node;case"op":return V(e.op,e.args.map(e=>tt(e,n)));default:throw new Error(`bad output template: ${JSON.stringify(e)}`)}}const rt=4e5,st=()=>new G("a number too large to approximate"),ot=e=>e<0n?-e:e;class it{constructor(e){this.P=e,this.S=10n**BigInt(e),this.cache=new Map}fromQ(e){return e.n*this.S/e.d}mul(e,n){return e*n/this.S}div(e,n){if(0n===n)throw new G("division by zero");return e*this.S/n}sqrt(e){if(e<0n)throw new G("the square root of a negative number is not real");return se(e*this.S,2)}series(e,n){let t=0n,r=e;for(let e=1;0n!==r;e++)if(t+=r,r=n(r,e),e>1e5)throw new G("a series did not converge");return t}atanhInv(e){const n=BigInt(e),t=n*n;let r=this.S/n,s=0n;for(let e=1n;0n!==r;e+=2n)s+=r/e,r/=t;return s}atanInv(e){const n=BigInt(e),t=n*n;let r=this.S/n,s=0n;for(let e=1n,n=1n;0n!==r;e+=2n,n=-n)s+=n*r/e,r/=t;return s}get pi(){return this.memo("pi",()=>16n*this.atanInv(5)-4n*this.atanInv(239))}get ln2(){return this.memo("ln2",()=>2n*this.atanhInv(3))}get e(){return this.memo("e",()=>this.exp(this.S))}memo(e,n){return this.cache.has(e)||this.cache.set(e,n()),this.cache.get(e)}exp(e){const n=(e+(e>=0n?this.ln2/2n:-this.ln2/2n))/this.ln2;if(n>BigInt(rt))throw st();if(n<-BigInt(rt))return 0n;const t=e-n*this.ln2,r=this.series(this.S,(e,n)=>e*t/this.S/BigInt(n));return n>=0n?r<<n:r>>-n}ln(e){if(e<=0n)throw new G("the log of a number that is not positive is not real");let n=0n,t=e;for(;t>=this.S;)t>>=1n,n++;for(;t<this.S/2n;)t<<=1n,n--;const r=this.div(t-this.S,t+this.S),s=this.mul(r,r);let o=r,i=0n;for(let e=1n;0n!==o;e+=2n)i+=o/e,o=this.mul(o,s);return 2n*i+n*this.ln2}sin(e){const n=2n*this.pi;let t=e%n;t>this.pi&&(t-=n),t<-this.pi&&(t+=n);const r=this.mul(t,t);return this.series(t,(e,n)=>-e*r/this.S/BigInt(2*n*(2*n+1)))}cos(e){return this.sin(e+this.pi/2n)}atan(e){if(ot(e)>this.S){const n=this.pi/2n;return(e>0n?n:-n)-this.atan(this.div(this.S,e))}let n=e;for(let e=0;e<2;e++)n=this.div(n,this.S+this.sqrt(this.S+this.mul(n,n)));const t=this.mul(n,n);let r=n,s=0n;for(let e=1n,n=1n;0n!==r;e+=2n,n=-n)s+=n*r/e,r=this.mul(r,t);return 4n*s}asin(e){if(ot(e)>this.S)throw new G("arcsin of a number beyond ±1 is not real");return ot(e)===this.S?e>0n?this.pi/2n:-this.pi/2n:this.atan(this.div(e,this.sqrt(this.S-this.mul(e,e))))}}function at(e,n,t){if(t>0n)return e.atan(e.div(n,t));if(t<0n)return e.atan(e.div(n,t))+(n>=0n?e.pi:-e.pi);if(0n===n)throw new G("the argument of 0 is undefined");return n>0n?e.pi/2n:-e.pi/2n}const ut={add:(e,n)=>[e[0]+n[0],e[1]+n[1]],sub:(e,n)=>[e[0]-n[0],e[1]-n[1]],mul:(e,n,t)=>[e.mul(n[0],t[0])-e.mul(n[1],t[1]),e.mul(n[0],t[1])+e.mul(n[1],t[0])],div(e,n,t){const r=e.mul(t[0],t[0])+e.mul(t[1],t[1]);if(0n===r)throw new G("division by zero");return[e.div(e.mul(n[0],t[0])+e.mul(n[1],t[1]),r),e.div(e.mul(n[1],t[0])-e.mul(n[0],t[1]),r)]},abs:(e,n)=>e.sqrt(e.mul(n[0],n[0])+e.mul(n[1],n[1])),exp(e,n){const t=e.exp(n[0]);return[e.mul(t,e.cos(n[1])),e.mul(t,e.sin(n[1]))]},ln(e,n){const t=ut.abs(e,n);if(0n===t)throw new G("the log of 0 is undefined");return[e.ln(t),at(e,n[1],n[0])]},pow(e,n,t,r){if(0n===n[0]&&0n===n[1])return[0n,0n];if(r&&r.isInteger){let t=r.n<0n?-r.n:r.n,s=[e.S,0n],o=n;for(;t>0n;)1n&t&&(s=ut.mul(e,s,o)),o=ut.mul(e,o,o),t>>=1n;return r.n<0n?ut.div(e,[e.S,0n],s):s}return ut.exp(e,ut.mul(e,t,ut.ln(e,n)))},sinh:(e,n)=>(e.exp(n)-e.exp(-n))/2n,cosh:(e,n)=>(e.exp(n)+e.exp(-n))/2n},lt={sin:(e,[n,t])=>[e.mul(e.sin(n),ut.cosh(e,t)),e.mul(e.cos(n),ut.sinh(e,t))],cos:(e,[n,t])=>[e.mul(e.cos(n),ut.cosh(e,t)),-e.mul(e.sin(n),ut.sinh(e,t))],tan:(e,n)=>ut.div(e,lt.sin(e,n),lt.cos(e,n)),ln:(e,n)=>ut.ln(e,n),sqrt:(e,n)=>ut.exp(e,ut.mul(e,[e.S/2n,0n],ut.ln(e,n))),sinh:(e,[n,t])=>[e.mul(ut.sinh(e,n),e.cos(t)),e.mul(ut.cosh(e,n),e.sin(t))],cosh:(e,[n,t])=>[e.mul(ut.cosh(e,n),e.cos(t)),e.mul(ut.sinh(e,n),e.sin(t))]},ct=e=>({q:e}),ft=([e,n])=>0n===n?{f:e}:{z:[e,n]};function pt(e,n,t){const r=e=>((e,n)=>n.z??[dt(e,n),0n])(t,n[e]);switch(e.op){case"+":return ft(ut.add(r(0),r(1)));case"-":return ft(ut.sub(r(0),r(1)));case"neg":return ft([-r(0)[0],-r(0)[1]]);case"*":return ft(ut.mul(t,r(0),r(1)));case"/":return ft(ut.div(t,r(0),r(1)));case"^":return ft(ut.pow(t,r(0),r(1),n[1].q));case"sqrt":return ft(lt.sqrt(t,r(0)));case"root":return ft(ut.pow(t,r(1),ut.div(t,[t.S,0n],r(0)),n[0].q?.inv()));case"abs":return{f:ut.abs(t,r(0))};case"arg":return{f:at(t,r(0)[1],r(0)[0])};case"re":return{f:r(0)[0]};case"im":return{f:r(0)[1]};case"conj":return ft([r(0)[0],-r(0)[1]]);case"log":return ft(ut.div(t,ut.ln(t,r(1)),ut.ln(t,r(0))));default:{const s=lt[e.op];if(!s||1!==n.length)throw new G(`no complex value for ${e.op}`);return ft(s(t,r(0)))}}}function dt(e,n){return n.q?e.fromQ(n.q):n.f}const ht={sin:(e,n)=>e.sin(n),cos:(e,n)=>e.cos(n),tan:(e,n)=>e.div(e.sin(n),e.cos(n)),sec:(e,n)=>e.div(e.S,e.cos(n)),csc:(e,n)=>e.div(e.S,e.sin(n)),cot:(e,n)=>e.div(e.cos(n),e.sin(n)),arcsin:(e,n)=>e.asin(n),arccos:(e,n)=>e.pi/2n-e.asin(n),arctan:(e,n)=>e.atan(n),sinh:(e,n)=>(e.exp(n)-e.exp(-n))/2n,cosh:(e,n)=>(e.exp(n)+e.exp(-n))/2n,tanh:(e,n)=>{const t=e.exp(n),r=e.exp(-n);return e.div(t-r,t+r)},arcsinh:(e,n)=>e.ln(n+e.sqrt(e.mul(n,n)+e.S)),arccosh:(e,n)=>{if(n<e.S)throw new G("arccosh of a number below 1 is not real");return e.ln(n+e.sqrt(e.mul(n,n)-e.S))},arctanh:(e,n)=>{if(ot(n)>=e.S)throw new G("arctanh of a number beyond ±1 is not real");return e.ln(e.div(e.S+n,e.S-n))/2n},ln:(e,n)=>e.ln(n),loglog:(e,n)=>e.ln(e.ln(n)),logloglog:(e,n)=>e.ln(e.ln(e.ln(n))),expm1:(e,n)=>e.exp(n)-e.S};function mt(e,n,t){if("num"===e.type)return ct(re(e.token));if("sym"===e.type){if("pi"===e.token||"π"===e.token)return{f:n.pi};if("e"===e.token)return{f:n.e};if("i"===e.token&&ue.complex)return{z:[0n,n.S]};if(t&&e.token in t){const n=t[e.token],r="number"==typeof n||"string"==typeof n||"bigint"==typeof n?re(String(n)):null;if(!r)throw new G(`the value of ${e.token} is not a number`);return ct(r)}throw new G(`${e.token} has no value`)}ue.complex&&e.op.startsWith("\\:")&&Fe[e.op.slice(2)]&&(e=V(Fe[e.op.slice(2)],e.args));const r=e.args.map(e=>mt(e,n,t));if(r.some(e=>e.z)||["re","im","conj","arg"].includes(e.op)||function(e,n){if(!ue.complex)return!1;const t=e=>e.q?e.q.sign<0:void 0!==e.f&&e.f<0n;return"sqrt"===e.op||"ln"===e.op||"log"===e.op?t(n["log"===e.op?1:0])||"log"===e.op&&t(n[0]):"^"===e.op?t(n[0])&&!(n[1].q&&n[1].q.d%2n==1n):"root"===e.op&&t(n[1])&&!(n[0].q&&n[0].q.isInteger&&n[0].q.n%2n==1n)}(e,r))return pt(e,r,n);const s=r.every(e=>e.q),o=e=>dt(n,r[e]);switch(e.op){case"+":return s?ct(r[0].q.add(r[1].q)):{f:o(0)+o(1)};case"-":return s?ct(r[0].q.sub(r[1].q)):{f:o(0)-o(1)};case"neg":return r[0].q?ct(r[0].q.neg()):{f:-r[0].f};case"*":return s?ct(r[0].q.mul(r[1].q)):{f:n.mul(o(0),o(1))};case"/":return s?ct(r[0].q.div(r[1].q)):{f:n.div(o(0),o(1))};case"^":return vt(n,r[0],r[1]);case"sqrt":return vt(n,r[0],ct(te.HALF));case"root":return vt(n,r[1],r[0].q?ct(r[0].q.inv()):{f:n.div(n.S,r[0].f)});case"abs":return r[0].q?ct(r[0].q.abs()):{f:ot(r[0].f)};case"floor":return ct(r[0].q?r[0].q.floor():new te(gt(r[0].f,n.S)));case"ceil":return ct(r[0].q?r[0].q.ceil():new te(-gt(-r[0].f,n.S)));case"log":return{f:n.div(n.ln(o(1)),n.ln(o(0)))};case"atan2":return{f:at(n,o(0),o(1))};case"max":case"min":if(!r.length)throw new G(`${e.op} of nothing`);return s?ct(r.map(e=>e.q).reduce((n,t)=>("max"===e.op?t.sub(n).sign>0:t.sub(n).sign<0)?t:n)):{f:r.map((e,n)=>o(n)).reduce((n,t)=>"max"===e.op?t>n?t:n:t<n?t:n)};case"sum":return s?ct(r.reduce((e,n)=>e.add(n.q),te.ZERO)):{f:r.reduce((e,n,t)=>e+o(t),0n)};case"prod":return s?ct(r.reduce((e,n)=>e.mul(n.q),te.ONE)):{f:r.reduce((e,t,r)=>n.mul(e,o(r)),n.S)};case"mean":if(!r.length)throw new G("mean of nothing");return s?ct(r.reduce((e,n)=>e.add(n.q),te.ZERO).div(new te(BigInt(r.length)))):{f:r.reduce((e,n,t)=>e+o(t),0n)/BigInt(r.length)};case"mod":{if(s){if(r[1].q.isZero)throw new G("mod 0 is undefined");return ct(r[0].q.sub(r[1].q.mul(r[0].q.div(r[1].q).floor())))}const e=o(1);if(0n===e)throw new G("mod 0 is undefined");return{f:o(0)-n.mul(e,gt(n.div(o(0),e),n.S)*n.S)}}case"round":{if(!r[1].q?.isInteger)throw new G("round needs a whole number of places");const e=10n**ot(r[1].q.n),t=r[0].q??new te(o(0),n.S),s=r[1].q.sign>=0,i=(s?t.mul(new te(e)):t.div(new te(e))).add(te.HALF).floor();return ct(s?i.div(new te(e)):i.mul(new te(e)))}case"!":{if(!r[0].q?.isInteger||r[0].q.sign<0)throw new G("factorial is only worked out for whole numbers");let e=1n;for(let n=2n;n<=r[0].q.n;n++)if(e*=n,0n==(255n&n)&&ee(e)>rt)throw st();return ct(new te(e))}default:{const t=ht[e.op];if(!t||1!==r.length)throw new G(`no numeric value for ${e.op}`);return{f:t(n,o(0))}}}}const gt=(e,n)=>{const t=e/n;return e<0n&&t*n!==e?t-1n:t};function vt(e,n,t){if(t.q&&t.q.isInteger){if(n.q)return ct(n.q.pow(t.q.n));let r=t.q.n;const s=r<0n;s&&(r=-r);let o=e.S,i=n.f;for(;r>0n;){if(1n&r&&(o=e.mul(o,i)),i=e.mul(i,i),ee(o)>rt+4*e.P||ee(i)>8e5){if(s)return{f:0n};throw st()}r>>=1n}return{f:s?e.div(e.S,o):o}}const r=dt(e,n);if(0n===r){if(t.q?t.q.sign>0:t.f>0n)return ct(te.ZERO);throw new G("0 to a power that is not positive is undefined")}if(r<0n){if(t.q&&t.q.d%2n==1n){const n=vt(e,{f:-r},t).f;return{f:t.q.n%2n==0n?n:-n}}throw new G("a negative number to a fractional power is not real")}if(t.q&&1n===ot(t.q.n)&&t.q.d<=64n){const n=se(r*e.S**(t.q.d-1n),Number(t.q.d));return{f:t.q.n<0n?e.div(e.S,n):n}}return{f:e.exp(e.mul(dt(e,t),e.ln(r)))}}function bt(e,n,t){const r=e<0n?"-":"",s=ot(e);if(0n===s)return{sign:"",digits:"0",point:1};const o=s.toString(),i=o.length-n.P;let a=o.slice(0,t);o.length>t&&o[t]>="5"&&(a=(BigInt(a)+1n).toString());let u=i;return a.length>t&&(a=a.slice(0,t),u++),{sign:r,digits:a.replace(/0+$/,"")||"0",point:u}}function yt({sign:e,digits:n,point:t}){if("0"===n)return"0";if(t>21||t<-6){return`${e}${n.length>1?`${n[0]}.${n.slice(1)}`:n}e${t-1}`}return t<=0?`${e}0.${"0".repeat(-t)}${n}`:t>=n.length?`${e}${n}${"0".repeat(t-n.length)}`:`${e}${n.slice(0,t)}.${n.slice(t)}`}function wt(e){let n=0n,t=0n,r=e.d;for(;r%2n==0n;)r/=2n,n++;for(;r%5n==0n;)r/=5n,t++;const s=n>t?n:t;let o=ot(e.n)*10n**s/e.d;if(0n===o)return 1;for(;o%10n==0n;)o/=10n;return o.toString().length}function xt(e){let n=e.d;for(;n%2n==0n;)n/=2n;for(;n%5n==0n;)n/=5n;return 1n===n}function qt(e){const n=/^(-?[\d.]+)e(-?\d+)$/.exec(e);return n?V("*",[B(n[1]),V("^",[B("10"),B(n[2])])]):B(e)}function kt(e,{digits:n=15,scope:t}={}){if(!Number.isInteger(n)||n<1||n>1e5)throw new G("digits must be a whole number from 1 to 100000");let r=n+25,s=null;for(let o=0;o<4;o++){const i=new it(r),a=mt(e,i,t);if(a.z){const e=St(a.z,i,n);if(e.retry&&o<3){r+=e.retry;continue}return void 0===e.real?e:$t(e.real,i,n,null)}if(a.q&&a.q.isInteger&&ot(a.q.n).toString().length<=n)return{text:a.q.n.toString(),node:B(a.q.n.toString()),number:Number(a.q.n),re:Number(a.q.n),im:0,exact:!0};const u=dt(i,a);if(0n===u&&(!a.q||!a.q.isZero)&&o<3){s=null,r*=4;continue}const l=bt(u,i,n);if(s&&l.point<-10&&s.point-l.point>=(r-s.P)/2)return{text:"0",node:B("0"),number:0,re:0,im:0,exact:!1};if(!(l.point<-10&&o<3)||s&&s.point===l.point)return $t(u,i,n,a.q);s={point:l.point,P:r},r+=10-l.point}throw new G("could not approximate")}function $t(e,n,t,r){const s=yt(bt(e,n,t));return{text:s,node:qt(s),number:Number(s),re:Number(s),im:0,exact:Boolean(r)&&xt(r)&&wt(r)<=t}}function St([e,n],t,r){const s=10n**BigInt(Math.max(0,t.P-r-12)),o=e=>ot(e)>s;if(!o(n))return{real:e};const i=bt(n,t,r);if(i.point<-10&&o(n))return{retry:10-i.point};const a=yt(i),u="1"===a?"i":"-1"===a?"-i":`${a}i`,l="1"===a?D("i"):V("*",[qt(a.replace(/^-/,"")),D("i")]);if(!o(e))return{text:u,node:a.startsWith("-")?V("neg",[l]):l,number:NaN,re:0,im:Number(a),exact:!1};const c=yt(bt(e,t,r)),f=a.startsWith("-"),p="1"===a.replace(/^-/,"")?D("i"):V("*",[qt(a.replace(/^-/,"")),D("i")]);return{text:`${c} ${f?"-":"+"} ${u.replace(/^-/,"")}`,node:V(f?"-":"+",[qt(c),p]),number:NaN,re:Number(c),im:Number(a),exact:!1}}function Ot(e,n={}){const t=e=>(e=>0===en(e).size)(e)?"num"===e.type&&/^-?\d+$/.test(e.token)?e:kt(e,n).node:U(e)?V(e.op,e.args.map(t)):e;return t(e)}const Nt={variable:null},At=(e,n)=>null!==n&&en(e).has(n);function It(e){if("num"===e.type)return re(e.token);if(U(e)&&"/"===e.op&&e.args.every(e=>"num"===e.type)){const n=re(e.args[0].token),t=re(e.args[1].token);return n&&t&&!t.isZero?n.div(t):null}return null}const Mt=e=>0===en(e).size;function Et(e,n,t){const r=function(e){const n=_e(e);return"num"===n.k?n.q.isZero?n.q:null:"atom"===n.k&&"sym"===n.node.type&&"pi"===n.node.token?re("1"):"mul"===n.k&&1===n.fs.length&&"atom"===n.fs[0].b.k&&"pi"===n.fs[0].b.node.token&&"num"===n.fs[0].e.k&&n.fs[0].e.q.isOne?n.c:null}(e);if(!r)return!1;const[s,o="1"]=String(n).split("/");return t(r.compare(re(s).div(re(o))))}function Tt(e){if(!Mt(e))return NaN;try{const{number:n}=kt(e,{digits:30});return Math.sign(n)}catch{return NaN}}function jt(){mn("hasVariable")||(dn("hasVariable",e=>At(e,Nt.variable),"mentions the variable being solved for"),dn("freeOfVariable",e=>null!==Nt.variable&&!At(e,Nt.variable),"does not mention the variable being solved for"),dn("isRational",e=>null!==It(e),"an exact number: 3, -2, 1/2"),dn("isWhole",e=>It(e)?.isInteger??!1,"a whole number (any size)"),dn("isEvenWhole",e=>{const n=It(e);return Boolean(n?.isInteger&&n.n%2n==0n)},"an even whole number"),dn("isOddWhole",e=>{const n=It(e);return Boolean(n?.isInteger&&n.n%2n!=0n)},"an odd whole number"),dn("isPositiveRational",e=>(It(e)?.sign??0)>0,"an exact number above 0"),dn("isNegativeRational",e=>(It(e)?.sign??0)<0,"an exact number below 0"),dn("isConstant",Mt,"has no unknowns (numbers, π and e only)"),dn("notOne",e=>{const n=It(e);return!n||!n.isOne},"anything except the number 1"),dn("notMinusOne",e=>{const n=It(e);return!n||!n.equals(re("-1"))},"anything except the number -1"),dn("hasMinusSign",e=>function(e){const n=_e(e);return"num"===n.k?n.q.sign<0:"mul"===n.k&&n.c.sign<0}(e),"written with a leading minus: -x, -2x, -π/6"),dn("piMultipleAtLeast",(e,n)=>Et(e,n,e=>e>=0),"a multiple of π, at least k·π"),dn("piMultipleAbove",(e,n)=>Et(e,n,e=>e>0),"a multiple of π, above k·π"),dn("piMultipleBelow",(e,n)=>Et(e,n,e=>e<0),"a multiple of π, below k·π"),dn("piMultipleAtMost",(e,n)=>Et(e,n,e=>e<=0),"a multiple of π, at most k·π"),dn("isPositiveConstant",e=>Tt(e)>0,"no unknowns, and above 0 (e, π, √2, 3)"),dn("isNegativeConstant",e=>Tt(e)<0,"no unknowns, and below 0"),dn("hasImaginaryPart",e=>{if(!ue.complex)return!1;const n=De(_e(e));return Boolean(n)&&!("num"===n.im.k&&n.im.q.isZero)},"complex mode: has a nonzero imaginary part (unknowns count as real)"),dn("isSymbolNode",e=>"sym"===e.type&&!ae.has(e.token),"a single unknown such as x"))}function Zt(e){const n=new Map;for(const t of e){const e=t.id??t.name;if(!e)throw new Error(`a rule needs an id (pattern ${t.pattern})`);n.set(String(e),{...n.get(String(e))??{},...t})}const t=[...n.values()].map(e=>{const n={...e};try{void 0!==n.pattern&&(n.pattern=function(e){const n=P(e),t=e=>"num"===e.type||("sym"===e.type?e.token.startsWith("="):e.args.every(t)),r=e=>"sym"===e.type?D(e.token.slice(1)):"num"===e.type?e:V(e.op,e.args.map(r)),s=e=>"sym"===e.type?D(`=${e.token}`):"num"===e.type?e:V(e.op,e.args.map(s)),o=e=>"op"!==e.type?e:t(e)?s(He(r(e))):V(e.op,e.args.map(o));return o(n).s}(String(n.pattern)))}catch(e){throw new Error(`rule "${n.id}": bad pattern "${n.pattern}": ${e.message}`)}return"hidden"===n.step&&(n.tags=[...n.tags??[],"hidden"]),n});return Gn.fromSpecs(t,{strict:!0})}function zt(e,n,t,r){return e.explain?e.explain.replace(/\{(\w+)\}/g,(e,s)=>"result"===s?t?r(t):e:n[s]?r(n[s]):e).trim():""}const Dt=e=>U(e)&&("+"===e.op||"-"===e.op),Bt=e=>U(e)&&("*"===e.op||"/"===e.op);function*Ct(e,n,{order:t="pre"}={}){for(const r of function(e,n,{order:t="post"}={}){const r=[];for(const{node:s,path:o}of Q(e,t))for(const e of nt(s,n))r.push({...e,node:s,path:o});return r}(e,n,{order:t})){const n=tt(r.rule.outputTemplate,r.bound);yield{rule:r.rule,bound:r.bound,path:r.path,before:r.node,after:n,next:()=>He(Y(e,r.path,n))}}for(const{node:r,path:s}of Q(e,t)){const t=Dt(r);if(!t&&!Bt(r))continue;const o=t?nn(_e(r)):tn(_e(r));if(o.length<3)continue;const i=t?Ne:Ie;for(let t=0;t<o.length;t++)for(let r=t+1;r<o.length;r++){const a=Ge(i([o[t],o[r]]));for(const u of nt(a,n)){const n=tt(u.rule.outputTemplate,u.bound),l=o.filter((e,n)=>n!==t&&n!==r);yield{rule:u.rule,bound:u.bound,path:s,before:a,after:n,next:()=>He(Y(e,s,Ge(i([_e(n),...l]))))}}}}}function Ft(e,n,{format:t,order:r="pre",maxSteps:s=200,variable:o=null}={}){const i=Nt.variable;Nt.variable=o;try{let o=He(e);const i=new Set([o.s]),a=[];for(let e=0;e<s;e++){let e=null;for(const t of Ct(o,n,{order:r})){const n=t.next();if(n.s!==o.s&&!i.has(n.s)){e={c:t,next:n};break}}if(!e)break;const{c:s,next:u}=e;a.push({id:s.rule.id,name:s.rule.name,tags:s.rule.tags,from:o.s,to:u.s,path:s.path,before:s.before.s,after:s.after.s,explanation:zt(s.rule,s.bound,He(s.after),t)}),o=u,i.add(o.s)}return{node:o,steps:a}}finally{Nt.variable=i}}const Vt={full:[],normal:["hidden"],brief:["hidden","tidy","identity","value","split","base","arithmetic"]},Rt=(e,n)=>"all"===n||"*"===n||Array.isArray(n)&&n.some(n=>n===e.id||e.tags?.includes(n));function Ut(e){if(!1===e)return null;if(void 0===e||!0===e)return{show:"all",hide:Vt.normal,explain:!0};if("string"==typeof e){if(!Vt[e])throw new Error(`steps: "${e}" is not one of ${Object.keys(Vt).join(", ")}`);return{show:"all",hide:Vt[e],explain:!0}}const n=e.detail??"normal";if(!Vt[n])throw new Error(`steps.detail: "${n}" is not one of ${Object.keys(Vt).join(", ")}`);return{show:e.show??"all",hide:[...Vt[n],...e.hide??[]],explain:e.explain??!0}}function Pt(e,n){if(!n)return[];const t=[];let r=null;for(const s of e){if(!(Rt(s,n.show)&&!Rt(s,n.hide))){r=r??{from:s.from,ids:[]},r.ids.push(s.id);continue}const e={...s};r&&(e.from=r.from,e.also=r.ids,e.path=null,r=null);!0===n.explain||!1!==n.explain&&Rt(s,n.explain)||delete e.explanation,t.push(e)}if(r&&t.length){const n=t[t.length-1];n.to=e[e.length-1].to,n.also=[...n.also??[],...r.ids]}return t}const Wt=pe(te.ONE),Lt=(e,n)=>"atom"===e.k&&"sym"===e.node.type&&e.node.token===n;function _t(e){switch(e.k){case"num":default:return e;case"atom":return"op"===e.node.type?We(e.node.op,e.node.args.map(e=>_t(_e(e)))):e;case"add":return Ne(nn(e).map(_t));case"mul":{let n=[pe(e.c)];for(const t of e.fs){const e=_t(t.b);if("add"===e.k&&ge(t.e)&&t.e.q.isInteger&&t.e.q.sign>0&&t.e.q.n<=BigInt(60))for(let r=0n;r<t.e.q.n;r++)n=Ht(n,nn(e));else n=Ht(n,[Ee(e,t.e)])}return Ne(n)}}}function Ht(e,n){const t=[];for(const r of e)for(const e of n)t.push(Ie([r,e]));return nn(Ne(t))}function Jt(e,n){const t=new Map;for(const r of nn(_t(e))){const{coef:e,rest:s}=Oe(r);let o=0;const i=[pe(e)];for(const e of s?tn(s):[]){const{b:t,e:r}="mul"===e.k&&1===e.fs.length&&e.c.isOne?e.fs[0]:{b:e,e:Wt};if(Lt(t,n)){if(!ge(r)||!r.q.isInteger||r.q.sign<0)return null;o+=Number(r.q.n)}else{if(Qt(t,n)||Qt(r,n))return null;i.push(e)}}t.set(o,Ne([t.get(o)??pe(te.ZERO),Ie(i)]))}for(const[e,n]of t)ge(n)&&n.q.isZero&&t.delete(e);return t}const Qt=(e,n)=>en(Ge(e)).has(n);function Yt(e){if(!e)return null;const n=Math.max(0,...e.keys());if(n>256)return null;const t=[];for(let r=0;r<=n;r++){const n=e.get(r)??pe(te.ZERO);if(!ge(n))return null;t.push(n.q)}return t}function Gt(e,n){const t=_e(D(n));return Ne(e.map((e,n)=>Ie([pe(e),Me(t,pe(te.of(n)))])))}const Kt=e=>{const n=e.slice();for(;n.length>1&&n[n.length-1].isZero;)n.pop();return n},Xt=(e,n)=>e.reduceRight((e,t)=>e.mul(n).add(t),te.ZERO);function er(e,n){const t=e.length-1,r=new Array(t);let s=te.ZERO;for(let o=t;o>=1;o--)s=e[o].add(s.mul(n)),r[o-1]=s;return r}function nr(e){if(0n===(e=(e=>e<0n?-e:e)(e)))return null;if(e>10n**14n)return null;const n=[];let t=e;for(let e=2n;e*e<=t;e+=2n===e?1n:2n){if(t%e)continue;let r=0;for(;t%e===0n;)t/=e,r++;n.push([e,r])}t>1n&&n.push([t,1]);let r=[1n];for(const[e,t]of n){const n=[];for(const s of r)for(let r=0,o=1n;r<=t;r++,o*=e)n.push(s*o);if(r=n,r.length>2e4)return null}return r.sort((e,n)=>e<n?-1:e>n?1:0)}function tr(e){let n=Kt(e);const t=[];for(;n.length>1&&n[0].isZero;)t.push(te.ZERO),n=n.slice(1);if(n.length<=1)return{roots:t,rest:n};const r=n.reduce((e,n)=>e*n.d/ne(e,n.d),1n),s=n.map(e=>e.n*r/e.d),o=nr(s[0]),i=nr(s[s.length-1]);if(!o||!i)return{roots:t,rest:n};const a=new Map;for(const e of o)for(const n of i)for(const t of[1n,-1n]){const r=new te(t*e,n);a.set(r.toString(),r)}const u=[...a.values()].sort((e,n)=>e.compare(n));for(const e of u)for(;n.length>1&&Xt(n,e).isZero;)t.push(e),n=er(n,e);return{roots:t.sort((e,n)=>e.compare(n)),rest:n}}function rr(e){if("num"===e.k)return{coef:e.q,factors:[],notes:[]};if("atom"===e.k)return{coef:te.ONE,factors:[{base:e,exp:Wt}],notes:[]};if("mul"===e.k){let n=e.c;const t=[],r=[];for(const s of e.fs)if("add"===s.b.k&&ge(s.e)&&s.e.q.isInteger){const e=rr(s.b);n=n.mul(e.coef.pow(s.e.q.n));for(const n of e.factors)t.push({base:n.base,exp:Ie([n.exp,s.e])});r.push(...e.notes)}else t.push({base:s.b,exp:s.e});return sr(n,t,r)}return function(e){const n=nn(e),t=[],r=n.map(e=>{const{coef:n,rest:t}=Oe(e);return{coef:n,fs:t?tn(t).map(ir):[]}}),s=r.reduce((e,n)=>({n:ne(e.n,n.coef.n),d:e.d*n.coef.d/ne(e.d,n.coef.d)}),{n:0n,d:1n});let o=new te(s.n||1n,s.d);or(e)<0&&(o=o.neg());const i=[];for(const e of r[0].fs){if(!ge(e.e)||e.e.q.sign<=0)continue;let n=e.e.q;const t=ye(e.b);let s=!0;for(const e of r.slice(1)){const r=e.fs.find(e=>ye(e.b)===t&&ge(e.e)&&e.e.q.sign>0);if(!r){s=!1;break}r.e.q.compare(n)<0&&(n=r.e.q)}s&&i.push({base:e.b,exp:pe(n)})}let a=e;if(!o.isOne||i.length){const e=Ie([pe(o),...i.map(e=>Ee(e.base,e.exp))]);a=Ne(n.map(n=>Ie([n,Me(e,pe(te.MINUS_ONE))]))),t.push({id:"factor.common",values:{common:e}})}const u="add"===a.k?function(e,n){const t=[...ar(e)];for(const r of t){const s=Yt(Jt(e,r));if(!s||s.length<3)continue;if(1!==t.length)break;const{roots:o,rest:i}=tr(s);if(!o.length)break;const a=[];let u=i[i.length-1]??te.ONE;const l=i.map(e=>e.div(u)),c=[...o].sort((e,n)=>e.abs().compare(n.abs())||n.sign-e.sign);for(const e of c){const t=Gt([new te(-e.n),new te(e.d)],r);a.push({base:t,exp:Wt}),u=u.div(new te(e.d)),n.push({id:"factor.root",values:{root:pe(e),factor:t}})}if(l.length>1){const e=l.reduce((e,n)=>e*n.d/ne(e,n.d),1n),n=l.map(n=>n.mul(new te(e))),t=n.reduce((e,n)=>ne(e,n.n),0n)||1n;u=u.mul(new te(t,e)),a.push({base:Gt(n.map(e=>e.div(new te(t))),r),exp:Wt})}return sr(u,a,[])}const r=nn(e);if(2===r.length){const[e,t]=r;for(const r of[2,3]){const s=ur(e,r),o=ur(Ve(t),r),i=3===r?ur(t,r):null;if(s&&o&&2===r){n.push({id:"factor.squares",values:{a:s,b:o}});const e=rr(Ne([s,Ve(o)])),t=rr(Ne([s,o]));return sr(e.coef.mul(t.coef),[...e.factors,...t.factors],[...e.notes,...t.notes])}if(3===r&&s&&(o||i)){const e=o??i,t=o?-1:1;n.push({id:t<0?"factor.cubes-difference":"factor.cubes-sum",values:{a:s,b:e}});const r=Ne(t<0?[s,Ve(e)]:[s,e]),a=Ne([Me(s,pe(te.of(2))),t<0?Ie([s,e]):Ve(Ie([s,e])),Me(e,pe(te.of(2)))]),u=rr(r);return sr(u.coef,[...u.factors,{base:a,exp:Wt}],u.notes)}}}return{coef:te.ONE,factors:[{base:e,exp:Wt}],notes:[]}}(a,t):rr(a);return sr(o.mul(u.coef),[...i,...u.factors],[...t,...u.notes.filter(e=>!t.includes(e))])}(e)}function sr(e,n,t){const r=new Map;for(const e of n){const n=ye(e.base),t=r.get(n);t?t.exp=Ne([t.exp,e.exp]):r.set(n,{...e})}return{coef:e,factors:[...r.values()].filter(e=>!(ge(e.exp)&&e.exp.q.isZero)),notes:t}}const or=e=>Oe(nn(e)[0]).coef.sign;const ir=e=>"mul"===e.k&&e.c.isOne&&1===e.fs.length?{b:e.fs[0].b,e:e.fs[0].e}:{b:e,e:Wt},ar=e=>en(Ge(e));function ur(e,n){const{coef:t,rest:r}=Oe(e);if(t.sign<0)return null;const s=function(e,n){const t=e=>{if(e<0n)return null;let t=0n,r=1n;for(;r**BigInt(n)<=e;)r*=2n;for(;t<r-1n;){const s=(t+r)/2n;s**BigInt(n)<=e?t=s:r=s}return t**BigInt(n)===e?t:null},r=t(e.n),s=t(e.d);return null!==r&&null!==s?new te(r,s):null}(t,n);if(!s)return null;const o=[pe(s)];for(const e of r?tn(r).map(ir):[]){if(!ge(e.e))return null;const t=e.e.q.div(te.of(n));if(!t.isInteger)return null;o.push(Ee(e.b,pe(t)))}return Ie(o)}function lr({coef:e,factors:n}){const t=[],r=[];for(const e of n){const n=ge(e.exp)&&e.exp.q.sign<0,s=n?pe(e.exp.q.neg()):e.exp,o=Ge(Ee(e.base,s));(n?r:t).push(o)}const s=e=>e.reduce((e,n)=>e?V("*",[e,n]):n,null),o=e.n<0n?-e.n:e.n;let i=t.length?s(1n===o?t:[Ge(pe(new te(o))),...t]):Ge(pe(new te(o)));return e.n<0n&&(i=V("neg",[i])),1n!==e.d&&r.unshift(Ge(pe(new te(e.d)))),r.length?V("/",[i,s(r)]):i}function cr(e){if("mul"!==e.k)return{num:e,den:Wt};const n=[pe(new te(e.c.n))],t=[pe(new te(e.c.d))];for(const r of e.fs)ge(r.e)&&r.e.q.sign<0?t.push(Ee(r.b,pe(r.e.q.neg()))):n.push(Ee(r.b,r.e));return{num:Ie(n),den:Ie(t)}}function fr(e){if("add"!==e.k)return cr(e);const n=nn(e).map(cr),t=new Map;let r=1n;for(const e of n){const{coef:n,rest:s}=Oe(e.den);r=r*n.n/ne(r,n.n);for(const e of s?tn(s).map(ir):[]){const n=ye(e.b),r=t.get(n);(!r||ge(e.e)&&ge(r.e)&&e.e.q.compare(r.e.q)>0)&&t.set(n,e)}}const s=Ie([pe(new te(r)),...[...t.values()].map(e=>Ee(e.b,e.e))]);if(ge(s)&&s.q.isOne)return{num:e,den:Wt};return{num:_t(Ne(n.map(e=>Ie([e.num,s,Me(e.den,pe(te.MINUS_ONE))])))),den:s}}function pr(e){const{num:n,den:t}=fr(e);if(ge(t)&&t.q.isOne)return null;const r=rr(n),s=rr(t),o=new Set(r.factors.map(e=>ye(e.base))),i=s.factors.filter(e=>o.has(ye(e.base))),a=[...r.factors,...s.factors.map(e=>({base:e.base,exp:Ve(e.exp)}))];return{...sr(r.coef.div(s.coef),a,[...r.notes,...s.notes]),cancelled:i.map(e=>e.base)}}const dr=(e,n)=>V("=",[e,n]),hr=He(V("+",[D("x"),V("neg",[D("x")])])),mr=e=>U(e)&&"="===e.op;function gr(e,n,t,r={}){const s=[],o=(n,t,r,o,i,a={})=>s.push(e.step(n,t,r,o,i,a));o.raw=e=>s.push(e);const i=mr(n)?n:dr(n,hr),a=dr(He(i.args[0]),He(i.args[1]));a.s!==i.s&&o("normal","Work out each side",["tidy","arithmetic"],i,a);const u=[],l=[],c=new Set;u.numeric=c,qr(e,a,t,r,o,u,l,0);const f=[],p=new Set;for(const n of u.map(n=>c.has(n)?n:(n=>Ft(n,e.set.view("simplify"),{format:e.format}).node)(n))){const e=n.s;if(p.has(e))continue;p.add(e);const r=c.has(n)?null:yr(i,t,n);r?o("solve.reject","Check the answer",["check"],dr(D(t),n),dr(D(t),n),{value:n,reason:r}):f.push(n)}return f.sort(vr),{solutions:f,unsolved:l,steps:s,always:l.some(e=>e.always)}}function vr(e,n){const t=br(e),r=br(n);return null===t||null===r?e.s<n.s?-1:1:(Math.abs(t.im)>0)-(Math.abs(r.im)>0)||t.re-r.re||t.im-r.im}function br(e){if(en(e).size)return null;try{const{re:n,im:t}=kt(e,{digits:20});return{re:n,im:t}}catch{return null}}function yr(e,n,t){const[r,s]=e.args,o=new Set([...en(r),...en(s),...en(t)]);if(o.delete(n),o.size)return null;const i=e=>wr(e,n,t);try{const e=kt(i(r),{digits:40}),n=kt(i(s),{digits:40}),t=Math.max(1,Math.hypot(e.re,e.im),Math.hypot(n.re,n.im));return Math.hypot(e.re-n.re,e.im-n.im)>1e-12*t?"it does not make the two sides equal":null}catch(e){return`the original equation has no value there (${e.message})`}}function wr(e,n,t){return"sym"===e.type?e.token===n?t:e:U(e)?V(e.op,e.args.map(e=>wr(e,n,t))):e}const xr=24;function qr(e,n,t,r,s,o,i,a){if(a>xr)return Ir(e,n,t,r,s,o,i);const u=function(e){const n=[],t=e=>{if(U(e)&&"|"===e.op)return void e.args.forEach(t);if(!mr(e))return void n.push(e);const r=e.args[1],s=Q(r,"pre").find(({node:e})=>U(e)&&"pm"===e.op);if(!s)return void n.push(e);const o=s.node.args[0],i=He(Y(r,s.path,o)),a=He(Y(r,s.path,V("neg",[o])));t(dr(e.args[0],i)),a.s!==i.s&&t(dr(e.args[0],a))};return t(e),n}(n);if(u.length>1){s("solve.split","Two cases",["split"],n,u.reduce((e,n)=>e?V("|",[e,n]):n,null));for(const n of u)qr(e,n,t,r,s,o,i,a+1);return}if(1===u.length&&u[0].s!==n.s)return qr(e,u[0],t,r,s,o,i,a+1);const[l,c]=n.args;if("sym"===l.type&&l.token===t&&!Qt(_e(c),t))return void o.push(c);const f=Ne([_e(l),Ve(_e(c))]);if(!Qt(f,t))return ge(f)&&f.q.isZero?(s("solve.always","Always true",["check"],n,n,{v:t}),void i.push(Object.assign(Object.create(n),{always:!0}))):void s("solve.never","No solution",["check"],n,n,{v:t});const p=nn(f).filter(e=>Qt(e,t)),d=nn(f).filter(e=>!Qt(e,t)),h=Ne(p),m=Ve(Ne(d));if(ue.complex){const u=Jt(f,t);if(u&&[...u.values()].every(e=>!Qt(e,t))&&Math.max(...u.keys())>=2){const l=dr(Ge(f),hr);return l.s!==n.s&&s("solve.one-side","Everything on one side",["move"],n,l,{v:t}),Nr(e,f,u,t,r,s,o,i,a,l)}}if(1===p.length)return kr(e,n,h,m,t,r,s,o,i,a);const g=dr(Ge(f),hr),v=Jt(f,t);if(v&&[...v.values()].every(e=>!Qt(e,t))&&Math.max(...v.keys())>=2)return g.s!==n.s&&s("solve.one-side","Everything on one side",["move"],n,g,{v:t}),Nr(e,f,v,t,r,s,o,i,a,g);const b=rr(f),y=b.factors.filter(e=>Qt(e.base,t)&&!(ge(e.exp)&&e.exp.q.sign<0));if(y.length>=2||1===y.length&&b.factors.length>1){const u=dr(lr(b),hr);g.s!==n.s&&s("solve.one-side","Everything on one side",["move"],n,g,{v:t}),u.s!==g.s&&s("solve.factor","Factor",["factor"],g,u,{});const l=y.map(e=>dr(Ge(e.base),hr));l.length>1&&s("solve.zero-product","A product is zero when a factor is",["split"],u,l.reduce((e,n)=>e?V("|",[e,n]):n,null),{});for(const n of l)qr(e,n,t,r,s,o,i,a+1);return}const w=fr(f);if(Qt(w.den,t)){const u=dr(Ge(w.num),hr);return s("solve.clear-denominator","Clear the denominator",["move"],n,u,{den:Ge(w.den)}),qr(e,u,t,r,s,o,i,a+1)}const x=p.filter(e=>!Or(e,t));if(1===x.length&&/\b(sqrt|root|abs)\b/.test(Ge(x[0]).s))return kr(e,n,x[0],Ve(Ne(nn(f).filter(e=>e!==x[0]))),t,r,s,o,i,a);const q=function(e,n){const t=Ge(e),r=new Map;for(const{node:e}of Q(t,"pre"))if(U(e)&&en(e).has(n))if("^"!==e.op||en(e.args[0]).has(n))["sin","cos","tan","ln","sqrt","abs"].includes(e.op)&&e.args[0].s===n&&r.set(e.s,e);else{const t=_e(e.args[1]),{coef:s,rest:o}=Oe(t);if(o&&s.isInteger&&Ge(o).s===n){const t=Ge(Me(_e(e.args[0]),_e(D(n))));r.set(t.s,t)}}const s="u"===n?"w":"u";for(const e of r.values()){const r=Ar(t,e,n,s);if(!r||en(r).has(n))continue;const o=_e(r),i=Jt(o,s);if(i&&Math.max(...i.keys())>=1)return{kernel:_e(e),poly:o,symbol:s}}return null}(f,t);if(q){const n=q.symbol;s("solve.substitute","Substitute",["substitute"],g,dr(Ge(q.poly),hr),{u:D(n),kernel:Ge(q.kernel)});const u=[];qr(e,dr(Ge(q.poly),hr),n,r,s,u,i,a+1);for(const n of u)qr(e,dr(Ge(q.kernel),n),t,r,s,o,i,a+1);return}return Ir(e,g,t,r,s,o,i)}function kr(e,n,t,r,s,o,i,a,u,l){let c=dr(Ge(t),Ge(r));c.s!==n.s&&i("solve.move","Move the terms",["move"],n,c,{v:s});const{coef:f,rest:p}=Oe(t),d=p?tn(p):[],h=Ie([pe(f),...d.filter(e=>!Qt(e,s))]);if(!ge(h)||!h.q.isOne){const e=Ie(d.filter(e=>Qt(e,s))),n=dr(Ge(e),Ge(Re(r,h))),t=ge(h)&&!h.q.isInteger&&(1n===h.q.n||-1n===h.q.n);i(t?"solve.multiply":"solve.divide",t?"Multiply both sides":"Divide both sides",["move"],c,n,{by:Ge(t?pe(h.q.inv()):h),v:s}),c=n}if("sym"===c.args[0].type&&c.args[0].token===s)return void a.push(c.args[1]);const m=_e(c.args[1]);if(ge(m)&&m.q.isZero){const n=_e(c.args[0]),t=tn(n).filter(e=>Qt(e,s)&&!$r(e));if(t.length>1||t.length<tn(n).filter(e=>Qt(e,s)).length){const n=t.map(e=>dr(Ge(Sr(e)),hr));i("solve.zero-product","A product is zero when a factor is",["split"],c,n.reduce((e,n)=>e?V("|",[e,n]):n,null),{});for(const t of n)qr(e,t,s,o,i,a,u,l+1);return}}const g=Ft(c,e.set.view("isolate"),{format:e.format,maxSteps:1,variable:s});return g.steps.length?(function(e,n){for(const t of n)e.raw(t)}(i,g.steps),qr(e,g.node,s,o,i,a,u,l+1)):Ir(e,c,s,o,i,a,u)}const $r=e=>"mul"===e.k&&e.c.isOne&&1===e.fs.length&&ge(e.fs[0].e)&&e.fs[0].e.q.sign<0,Sr=e=>"mul"===e.k&&e.c.isOne&&1===e.fs.length&&ge(e.fs[0].e)&&e.fs[0].e.q.sign>0?e.fs[0].b:e,Or=(e,n)=>{const t=Jt(e,n);return Boolean(t)&&[...t.values()].every(e=>!Qt(e,n))};function Nr(e,n,t,r,s,o,i,a,u,l){const c=Math.max(...t.keys()),f=Yt(t);if(ue.complex&&c>=3&&c<=64&&f&&f.every((e,n)=>0===n||n===c||e.isZero)&&!f[0].isZero){const n=f[0].neg().div(f[c]),t=Me(pe(n.abs()),pe(new te(1n,BigInt(c)))),s=[];for(let r=0;r<c;r++){const o=Ie([pe(new te(BigInt((n.sign<0?1:0)+2*r),BigInt(c))),_e(D("pi"))]),i=V("*",[Ge(t),V("+",[V("cos",[Ge(o)]),V("*",[D("i"),V("sin",[Ge(o)])])])]);s.push(Ft(i,e.set.view("simplify"),{format:e.format}).node)}return o("solve.roots","All n roots",["complex"],l,s.map(e=>dr(D(r),e)).reduce((e,n)=>e?V("|",[e,n]):n),{v:r,n:String(c),last:String(c-1),r:Ge(pe(n))}),void i.push(...s)}if(f){const{roots:t}=tr(f);if(t.length){const t=rr(n),c=dr(lr(t),hr);if(t.factors.length>1||t.factors.some(e=>!(ge(e.exp)&&e.exp.q.isOne))){o("solve.factor","Factor",["factor"],l,c,{});const n=t.factors.filter(e=>Qt(e.base,r)).map(e=>dr(Ge(e.base),hr));n.length>1&&o("solve.zero-product","A product is zero when a factor is",["split"],c,n.reduce((e,n)=>e?V("|",[e,n]):n,null),{});for(const t of n)qr(e,t,r,s,o,i,a,u+1);return}}}if(2===c){const e=t.get(2),n=t.get(1)??pe(te.ZERO),s=t.get(0)??pe(te.ZERO),a=Ne([Me(n,pe(te.of(2))),Ie([pe(te.of(-4)),e,s])]);if(ge(a)&&a.q.sign<0&&!ue.complex)return void o("solve.no-real","No real solutions",["quadratic"],l,l,{D:Ge(a)});const u=Ie([pe(te.of(2)),e]),c=Me(a,pe(te.HALF)),f=Ge(Re(Ne([Ve(n),c]),u)),p=Ge(Re(Ne([Ve(n),Ve(c)]),u)),d=f.s===p.s?dr(D(r),f):V("|",[dr(D(r),f),dr(D(r),p)]);return o(ue.complex&&ge(a)&&a.q.sign<0?"solve.quadratic-complex":"solve.quadratic","The quadratic formula",["quadratic"],l,d,{a:Ge(e),b:Ge(n),c:Ge(s),D:Ge(a),root:Ge(c),v:r}),i.push(f),void(p.s!==f.s&&i.push(p))}return Ir(e,l,r,s,o,i,a)}function Ar(e,n,t,r){if(e.s===n.s)return D(r);if(!U(e))return e;if("^"===e.op&&"^"===n.op&&e.args[0].s===n.args[0].s){const n=_e(e.args[1]),{coef:s,rest:o}=Oe(n);if(o&&Ge(o).s===t&&s.isInteger)return V("^",[D(r),Ge(pe(s))])}return V(e.op,e.args.map(e=>Ar(e,n,t,r)))}function Ir(e,n,t,r,s,o,i){if(r.approximate){const e="number"==typeof r.approximate?r.approximate:15,i=_e(V("-",[n.args[0],n.args[1]])),a=ue.complex?Yt(Jt(i,t)):null,u=a&&a.length>2?function(e,n){const t=e.length-1,r=e[t],s=e.map(e=>e/r),o=(e,n)=>{let r=1,o=0;for(let i=t-1;i>=0;i--)[r,o]=[r*e-o*n+s[i],r*n+o*e];return[r,o]};let i=Array.from({length:t},(e,n)=>[1.3*Math.cos(2*Math.PI*n/t+.4),1.3*Math.sin(2*Math.PI*n/t+.4)]);for(let e=0;e<500;e++){let e=0;if(i=i.map(([n,r],s)=>{let[a,u]=o(n,r);for(let e=0;e<t;e++){if(e===s)continue;const t=n-i[e][0],o=r-i[e][1],l=t*t+o*o;[a,u]=[(a*t+u*o)/l,(u*t-a*o)/l]}return e=Math.max(e,Math.hypot(a,u)),[n-a,r-u]}),e<1e-15)break}const a=e=>Math.abs(e)<1e-12?0:Number(e.toPrecision(n));return i.map(([e,n])=>[a(e),a(n)]).sort((e,n)=>(0!==e[1])-(0!==n[1])||e[0]-n[0]||e[1]-n[1]).map(([e,n])=>{const t=Mr(e);if(0===n)return t;const r=V("*",[Mr(Math.abs(n)),D("i")]);return 0===e?n<0?V("neg",[r]):r:V(n<0?"-":"+",[t,r])})}(a.map(e=>e.toNumber()),Math.min(e,14)):function(e,n,t){const r=_e(V("-",[e.args[0],e.args[1]])),s=Ge(r),o=e=>{try{return kt(wr(s,n,Er(e)),{digits:30}).number}catch{return NaN}},i=[],a=[];for(let e=-400;e<=400;e++)a.push(Math.sign(e)*(Math.abs(e)/20)**2);for(let e=0;e+1<a.length;e++){let n=a[e],r=a[e+1],s=o(n);const u=o(r);if(Number.isNaN(s)||Number.isNaN(u))continue;if(0===s){i.push(Er(n));continue}if(s*u>0)continue;for(let e=0;e<200&&r-n>1e-16*Math.abs(n);e++){const e=(n+r)/2,t=o(e);if(Number.isNaN(t))break;s*t<=0?r=e:(n=e,s=t)}const l=(n+r)/2;Math.abs(o(l))<1e-6&&i.push(Er(Number(l.toPrecision(Math.min(t,15)))))}return i}(n,t,e);for(const e of u)o.numeric?.add(e);return s("solve.numeric","Numeric solutions",["numeric"],n,u.length?u.map(e=>dr(D(t),e)).reduce((e,n)=>e?V("|",[e,n]):n):n,{v:t,count:String(u.length)}),void o.push(...u)}s("solve.unsolved","No exact method",["unsolved"],n,n,{v:t}),i.push(n)}const Mr=e=>B(String(e).includes("e")?e.toFixed(20):String(e)),Er=e=>B(Number.isInteger(e)?String(e):e.toFixed(17));const Tr=(e,n)=>V("int",[e,"string"==typeof n?D(n):n]);function jr(e,n,t,r=0){if(r>6)throw new G("integration went too deep");const s=[],o=e.set.view("integrate"),i=Ft(n,e.set.view("simplify"),{format:e.format});s.push(...i.steps);let a=He(Tr(i.node,t));for(let n=0;n<40;n++){const n=Ft(a,o,{format:e.format});s.push(...n.steps),a=n.node;const t=Q(a,"pre").find(({node:e})=>{return U(n=e)&&"int"===n.op&&2===n.args.length;var n});if(!t)return{node:a,steps:s};const i=Zr(e,t.node,r);if(!i)throw new G(`no rule for ∫ ${e.format(t.node.args[0])} d${t.node.args[1].token}`);s.push(...i.steps),a=He(Y(a,t.path,i.node))}throw new G("integration did not finish")}function Zr(e,n,t){const[r,s]=n.args,o=s.token,i=_e(r),a=function(e,n){const{num:t,den:r}=fr(e),s=rr(t),o=rr(r),i=s.coef.div(o.coef);if(i.isOne||!Qt(e,n))return null;const a=Ie([...s.factors.map(e=>Ee(e.base,e.exp)),...o.factors.map(e=>Ee(e.base,Ve(e.exp)))]);return{c:i,rest:a}}(i,o);if(a){const t=V("*",[Ge(pe(a.c)),Tr(Ge(a.rest),s)]);return{node:t,steps:[e.step("integrate.constant","Take the number out",["split"],n,t,{c:Ge(pe(a.c))})]}}const u=_t(i);if(Ge(u).s!==r.s&&"add"===u.k){const t=Tr(Ge(u),s);return{node:t,steps:[e.step("integrate.expand","Multiply out",["expand"],n,t,{})]}}const l=function(e,n){const t=new Map;for(const{node:r}of Q(e,"pre")){if(!U(r))continue;const e="^"===r.op?r.args:"/"===r.op?[r.args[1]]:"der"===r.op||"int"===r.op?[]:1===r.args.length||"root"===r.op?[r.args[r.args.length-1]]:[];for(const r of e){if("sym"===r.type||!en(r).has(n))continue;const e=Jt(_e(r),n);if(!e||1!==Math.max(...e.keys()))continue;const s=e.get(1);Qt(s,n)||ge(s)&&s.q.isZero||t.set(r.s,{node:r,a:s})}}for(const r of t.values()){if(!en(zr(e,r.node,D("§"))).has(n))return r}return null}(r,o);if(l){const s="u"===o?"t":"u",i=zr(r,l.node,D(s));if(!en(i).has(o)){const r=jr(e,He(i),s,t+1),a=He(wr(r.node,s,l.node)),u=Ge(Re(_e(a),l.a));return{node:u,steps:[e.step("integrate.substitute","Substitute",["substitute"],n,He(Tr(i,s)),{u:D(s),inside:l.node,a:Ge(l.a),v:o}),...r.steps,e.step("integrate.back","Substitute back",["substitute"],r.node,u,{u:D(s),inside:l.node})]}}}const c=function(e,n,t,r){const{num:s,den:o}=fr(t);if(!Qt(o,r))return null;const i=Yt(Jt(s,r)),a=Yt(Jt(o,r));if(!i||!a||a.length<2)return null;const u=_e(D(r)),l=e=>Gt(e,r);if(i.length>=a.length){const{q:t,r:s}=function(e,n){const t=Kt(n);let r=Kt(e);const s=t[t.length-1];if(s.isZero)throw new G("division by the zero polynomial");const o=new Array(Math.max(1,r.length-t.length+1)).fill(te.ZERO);for(;r.length>=t.length&&(1!==r.length||!r[0].isZero);){const e=r.length-t.length,n=r[r.length-1].div(s);if(o[e]=n,r=Kt(r.map((r,s)=>s>=e&&s-e<t.length?r.sub(n.mul(t[s-e])):r)),r.length-1<e+t.length-1&&r[r.length-1].isZero)break;if(r.length<t.length)break}return{q:Kt(o),r:r}}(i,a),o=Tr(Ge(Ne([l(t),Re(l(s),l(a))])),D(r));return{node:o,steps:[e.step("integrate.divide","Divide the polynomials",["divide"],n,o,{})]}}const{roots:c,rest:f}=tr(a),p=new Set(c.map(String)).size===c.length;if(!c.length||!p||1!==f.length)return null;const d=(e=>e.length<=1?[te.ZERO]:e.slice(1).map((e,n)=>e.mul(te.of(n+1))))(a),h=c.map(e=>Re(pe(Xt(i,e).div(Xt(d,e))),Ne([u,pe(e.neg())]))),m=Tr(Ge(Ne(h)),D(r));return{node:m,steps:[e.step("integrate.partial-fractions","Partial fractions",["partial-fractions"],n,m,{})]}}(e,n,i,o);return c||function(e,n,t,r,s){if(s>=6)return null;const o=tn(t),i=o.filter(e=>Dr(e,r)||!Qt(e,r)),a=o.filter(e=>!i.includes(e));if(1!==a.length)return null;const u=Ie(i),l=a[0];if(!Qt(u,r))return null;const c=Ge(l),f=U(c)?c.op:"";let p,d,h;"ln"===f||"arctan"===f||"arcsin"===f?(p=l,d=u):(p=u,d=l);try{h=jr(e,Ge(d),r,s+1)}catch{return null}const m=_e(e.differentiate(Ge(p),r)),g=Ie([p,_e(h.node)]),v=Tr(Ge(Ie([m,_e(h.node)])),D(r)),b=He(V("-",[Ge(g),v]));return{node:b,steps:[e.step("integrate.parts","Integration by parts",["parts"],n,b,{u:Ge(p),dv:Ge(d),V:h.node,du:Ge(m),v:r})]}}(e,n,i,o,t)}function zr(e,n,t){return e.s===n.s?t:U(e)?V(e.op,e.args.map(e=>zr(e,n,t))):e}const Dr=(e,n)=>{const t=Jt(e,n);return Boolean(t)&&[...t.values()].every(e=>!Qt(e,n))&&Math.max(...t.keys())>=1};function Br(e,n,t,r,s,o){for(const e of[r,s])if(en(e).has("∞")||/∞|infinity/.test(e.s))throw new G("integrals to infinity need limits, which this CAS does not do yet");if(o&&!en(r).size&&!en(s).size){const i=kt(r,{digits:20}).number,a=kt(s,{digits:20}).number,u=[...en(o)].filter(e=>e!==t);if(!u.length){const[r,s]=i<=a?[i,a]:[a,i];for(const i of function(e,n){const t=[],r={tan:"cos",sec:"cos",csc:"sin",cot:"sin"};return Q(e,"pre").forEach(({node:e})=>{if(!U(e))return;let s=null;"/"===e.op?s=e.args[1]:"^"===e.op&&"num"===e.args[1].type&&e.args[1].value<0||"^"===e.op&&U(e.args[1])&&"neg"===e.args[1].op?s=e.args[0]:r[e.op]&&(s=V(r[e.op],[e.args[0]])),s&&en(s).has(n)&&!t.some(e=>e.s===s.s)&&t.push(s)}),t}(o,t)){let o=[];try{o=e.solve(V("=",[i,B("0")]),t,{steps:!1}).solutions}catch{continue}for(const i of o){const o=kt(i,{digits:20});if(!Number.isFinite(o.number)||o.im||o.number<r||o.number>s)continue;if(o.number>r&&o.number<s)throw new G(`the integrand has no value at ${t} = ${e.format(i)}, between the limits, so F(b) - F(a) would be wrong`);let a=NaN;try{a=kt(He(wr(n,t,i)),{digits:15}).number}catch{}if(!Number.isFinite(a))throw new G(`the integral diverges at ${t} = ${e.format(i)}: F has no value at that limit`)}}}for(let e=0;!u.length&&e<=64;e++){const n=i+(a-i)*(e+.5)/65;try{const e=kt(wr(o,t,B(n.toFixed(15))),{digits:15}).number;if(!Number.isFinite(e))throw new G("not finite")}catch(e){throw new G(`the integrand has no value at ${t} = ${n.toPrecision(6)}, between the limits, so F(b) - F(a) would be wrong`)}}}const i=e=>He(wr(n,t,e)),a=He(V("-",[i(s),i(r)])),u=V("-",[i(s),i(r)]);return{value:a,step:e.step("integrate.evaluate","Between the limits",["evaluate"],n,u,{a:r,b:s,F:n,v:t})}}const Cr={"=":1,"≠":1,"<":1,">":1,"≤":1,"≥":1,"+":2,"-":2,"±":2,"*":3,"/":3,neg:4,pm:4,"^":5},Fr={pi:"π","≤":"≤","≥":"≥"};function Vr(e){return Lr(e).text}function Rr(e,n,t=!1){return e.prec<n||t&&e.prec===n?`(${e.text})`:e.text}const Ur=e=>"op"===e.type?e.op:null,Pr=e=>e.text.startsWith("-"),Wr={"()":["(",")"],"[]":["[","]"],"{}":["{","}"],"(]":["(","]"],"[)":["[",")"]};function Lr(e){if("num"===e.type)return{text:e.token,prec:e.token.startsWith("-")?4:9};if("sym"===e.type)return{text:Fr[e.token]??e.token,prec:9};const n=e.args.map(Lr),t=Cr[e.op];switch(e.op){case"+":case"-":case"±":{const r="+"===e.op&&["+","-"].includes(Ur(e.args[1])),s=Pr(n[1])?`(${n[1].text})`:r?n[1].text:Rr(n[1],t,!0);return{text:`${Rr(n[0],t)} ${"±"===e.op?"±":e.op} ${s}`,prec:t}}case"*":{const r=Rr(n[0],t),s=Pr(n[1])?`(${n[1].text})`:"*"===Ur(e.args[1])?n[1].text:Rr(n[1],t,!0);return{text:"num"===e.args[0].type&&"num"!==e.args[1].type&&!/^[\d(-]/.test(s)||"sym"===e.args[1].type&&"i"===e.args[1].token&&!/[\dA-Za-z]$/.test(r)?`${r}${s}`:`${r}·${s}`,prec:t}}case"/":return{text:`${Rr(n[0],t)}/${Rr(n[1],t,!0)}`,prec:t};case"^":return{text:`${Rr(n[0],t+1)}^${Rr(n[1],t)}`,prec:t};case"neg":return{text:`-${Rr(n[0],3)}`,prec:4};case"pm":return{text:`±${Rr(n[0],4)}`,prec:4};case"!":return{text:`${Rr(n[0],9)}!`,prec:6};case"abs":return{text:`|${n[0].text}|`,prec:9};case"root":return{text:`root(${n[0].text}, ${n[1].text})`,prec:9};case"der":return{text:`d/d${n[1].text} (${n[0].text})`,prec:6};case"int":return{text:4===n.length?`∫ from ${n[2].text} to ${n[3].text} of ${n[0].text} d${n[1].text}`:`∫ ${n[0].text} d${n[1].text}`,prec:1};case"|":return{text:`${n[0].text} or ${n[1].text}`,prec:0};case"_":return{text:`${Rr(n[0],9)}_${n[1].prec>=9&&!/\s/.test(n[1].text)?n[1].text:`(${n[1].text})`}`,prec:9};case"()":case"[]":case"{}":case"(]":case"[)":return{text:`${Wr[e.op][0]}${n.map(e=>e.text).join(", ")}${Wr[e.op][1]}`,prec:9};case"&":return{text:`${n[0].text} and ${n[1].text}`,prec:0};default:return void 0!==t?{text:`${Rr(n[0],t)} ${e.op} ${Rr(n[1],t,!0)}`,prec:t}:{text:`${e.op.replace(/^\\:?/,"")}(${n.map(e=>e.text).join(", ")})`,prec:9}}}const _r=['name: Differentiation\n\n# `u v der` means d(u)/dv (MathZetta\'s postfix: mathzetta/docs/postfix.md). Every rule here rewrites one derivative into smaller\n# derivatives, so differentiating always terminates: the expressions sitting\n# under a `D` get strictly smaller at every step.\n#\n# The variable is a slot, not a fixed letter, so these rules work for d/dx,\n# d/dt or anything else. That is what freeOf and dependsOn are for: they ask\n# whether one operand mentions whatever the variable slot bound to.\n#\n# Where two rules share a structure key, requirements keep them apart and\n# priority picks the one that reads better. The constant-multiple rule outranks\n# the product rule for exactly that reason.\n\nrules:\n # ---- the two base cases ----------------------------------------------\n - id: d-constant\n name: Derivative of a constant\n mode: differentiate\n pattern: c v der\n require:\n - [freeOf, c, v]\n output: "0"\n priority: 10\n explain: "{c} does not change when {v} changes, so its rate of change is 0."\n tags: [base]\n\n - id: d-variable\n name: Derivative of the variable\n mode: differentiate\n pattern: u v der\n require:\n - [sameAs, u, v]\n output: "1"\n priority: 10\n explain: "{v} changes exactly as fast as itself, so the rate is 1."\n tags: [base]\n\n # ---- splitting a derivative into smaller ones ------------------------\n - id: d-sum\n name: Sum rule\n mode: differentiate\n pattern: u w + v der\n output: u v der w v der +\n explain: "Differentiate {u} and {w} separately, then add the two results."\n tags: [split]\n\n - id: d-difference\n name: Difference rule\n mode: differentiate\n pattern: u w - v der\n output: u v der w v der -\n explain: "Differentiate {u} and {w} separately, then subtract the second from the first."\n tags: [split]\n\n - id: d-negate\n name: Derivative of a negative\n mode: differentiate\n pattern: u neg v der\n output: u v der neg\n explain: "The minus sign just carries through to the derivative of {u}."\n tags: [split]\n\n - id: d-constant-multiple\n name: Constant multiple rule\n mode: differentiate\n pattern: c u * v der\n commutative: true\n require:\n - [freeOf, c, v]\n - [dependsOn, u, v]\n output: c u v der *\n priority: 5\n explain: "{c} is only a scale factor, so it comes along unchanged while {u} is differentiated."\n tags: [split]\n\n - id: d-constant-divisor\n name: Dividing by a constant\n mode: differentiate\n pattern: u c / v der\n require:\n - [freeOf, c, v]\n output: u v der c /\n priority: 5\n explain: "Dividing by {c} is only a scale factor, so differentiate {u} and keep the division."\n tags: [split]\n\n - id: d-product\n name: Product rule\n mode: differentiate\n pattern: u w * v der\n require:\n - [dependsOn, u, v]\n - [dependsOn, w, v]\n output: u v der w * u w v der * +\n explain: "Differentiate {u} and keep {w}, then keep {u} and differentiate {w}, and add the two."\n tags: [split]\n\n - id: d-quotient\n name: Quotient rule\n mode: differentiate\n pattern: u w / v der\n output: u v der w * u w v der * - w 2 ^ /\n explain: "Bottom times the derivative of the top, minus top times the derivative of the bottom, all over {w} squared."\n tags: [split]\n\n # ---- powers -----------------------------------------------------------\n - id: d-power-of-variable\n name: Power rule\n mode: differentiate\n pattern: u n ^ v der\n require:\n - [sameAs, u, v]\n - [freeOf, n, v]\n output: n u n 1 - ^ *\n fold: true\n priority: 6\n explain: "Bring the {n} down in front and drop the power by one."\n tags: [power]\n\n - id: d-power-chain\n name: Power rule with the chain rule\n mode: differentiate\n pattern: u n ^ v der\n require:\n - [freeOf, n, v]\n - [dependsOn, u, v]\n output: n u n 1 - ^ * u v der *\n fold: true\n explain: "Bring the {n} down and drop the power by one, then multiply by the derivative of {u}."\n tags: [power, chain]\n\n - id: d-exponential-base\n name: Derivative of a constant to a power\n mode: differentiate\n pattern: a u ^ v der\n require:\n - [freeOf, a, v]\n - [dependsOn, u, v]\n output: a u ^ a ln * u v der *\n explain: "A constant base gives itself back, multiplied by the natural log of {a} and the derivative of {u}."\n tags: [power, chain]\n\n # ---- the standard functions, each with its chain-rule factor ---------\n # e^u is `=e u ^`: the base is the literal symbol e. Outranks the general\n # a^u rule (which would give e^u · ln e · u\').\n - id: d-exp\n name: Derivative of e to a power\n mode: differentiate\n pattern: =e u ^ v der\n require:\n - [dependsOn, u, v]\n output: =e u ^ u v der *\n priority: 7\n explain: "e to a power is its own derivative, times the derivative of {u}."\n tags: [chain]\n\n - id: d-ln\n name: Derivative of a natural log\n mode: differentiate\n pattern: u ln v der\n output: u v der u /\n explain: "The derivative of {u} over {u} itself."\n tags: [chain]\n\n - id: d-sqrt\n name: Derivative of a square root\n mode: differentiate\n pattern: u sqrt v der\n output: u v der 2 u sqrt * /\n explain: "The derivative of {u}, over twice the square root of {u}."\n tags: [chain]\n\n - id: d-sin\n name: Derivative of sine\n mode: differentiate\n pattern: u sin v der\n output: u cos u v der *\n explain: "Sine differentiates to cosine, times the derivative of {u}."\n tags: [chain, trig]\n\n - id: d-cos\n name: Derivative of cosine\n mode: differentiate\n pattern: u cos v der\n output: u sin u v der * neg\n explain: "Cosine differentiates to minus sine, times the derivative of {u}."\n tags: [chain, trig]\n\n - id: d-tan\n name: Derivative of tangent\n mode: differentiate\n pattern: u tan v der\n output: u v der u cos 2 ^ /\n explain: "The derivative of {u}, over cosine squared of {u}."\n tags: [chain, trig]\n\n # ---- the rest of the standard functions -----------------------------\n - id: d-csc\n name: Derivative of cosecant\n mode: differentiate\n pattern: u csc v der\n output: u csc u cot * u v der * neg\n explain: "Cosecant differentiates to minus cosecant times cotangent, times the derivative of {u}."\n tags: [chain, trig]\n\n - id: d-sec\n name: Derivative of secant\n mode: differentiate\n pattern: u sec v der\n output: u sec u tan * u v der *\n explain: "Secant differentiates to secant times tangent, times the derivative of {u}."\n tags: [chain, trig]\n\n - id: d-cot\n name: Derivative of cotangent\n mode: differentiate\n pattern: u cot v der\n output: u v der u sin 2 ^ / neg\n explain: "Minus the derivative of {u}, over sine squared of {u}."\n tags: [chain, trig]\n\n - id: d-arcsin\n name: Derivative of arcsine\n mode: differentiate\n pattern: u arcsin v der\n output: u v der 1 u 2 ^ - sqrt /\n explain: "The derivative of {u}, over the square root of 1 minus {u} squared."\n tags: [chain, trig]\n\n - id: d-arccos\n name: Derivative of arccosine\n mode: differentiate\n pattern: u arccos v der\n output: u v der 1 u 2 ^ - sqrt / neg\n explain: "Minus the derivative of {u}, over the square root of 1 minus {u} squared."\n tags: [chain, trig]\n\n - id: d-arctan\n name: Derivative of arctangent\n mode: differentiate\n pattern: u arctan v der\n output: u v der 1 u 2 ^ + /\n explain: "The derivative of {u}, over 1 plus {u} squared."\n tags: [chain, trig]\n\n - id: d-sinh\n name: Derivative of hyperbolic sine\n mode: differentiate\n pattern: u sinh v der\n output: u cosh u v der *\n explain: "Hyperbolic sine differentiates to hyperbolic cosine, times the derivative of {u}."\n tags: [chain, hyperbolic]\n\n - id: d-cosh\n name: Derivative of hyperbolic cosine\n mode: differentiate\n pattern: u cosh v der\n output: u sinh u v der *\n explain: "Hyperbolic cosine differentiates to hyperbolic sine — no minus sign, unlike cosine — times the derivative of {u}."\n tags: [chain, hyperbolic]\n\n - id: d-tanh\n name: Derivative of hyperbolic tangent\n mode: differentiate\n pattern: u tanh v der\n output: u v der u cosh 2 ^ /\n explain: "The derivative of {u}, over hyperbolic cosine squared of {u}."\n tags: [chain, hyperbolic]\n\n - id: d-arcsinh\n name: Derivative of inverse hyperbolic sine\n mode: differentiate\n pattern: u arcsinh v der\n output: u v der u 2 ^ 1 + sqrt /\n explain: "The derivative of {u}, over the square root of {u} squared plus 1."\n tags: [chain, hyperbolic]\n\n - id: d-arccosh\n name: Derivative of inverse hyperbolic cosine\n mode: differentiate\n pattern: u arccosh v der\n output: u v der u 2 ^ 1 - sqrt /\n explain: "The derivative of {u}, over the square root of {u} squared minus 1."\n tags: [chain, hyperbolic]\n\n - id: d-arctanh\n name: Derivative of inverse hyperbolic tangent\n mode: differentiate\n pattern: u arctanh v der\n output: u v der 1 u 2 ^ - /\n explain: "The derivative of {u}, over 1 minus {u} squared."\n tags: [chain, hyperbolic]\n\n # log base a: `a u log` in MathZetta\'s postfix\n - id: d-log\n name: Derivative of a logarithm\n mode: differentiate\n pattern: a u log v der\n require:\n - [freeOf, a, v]\n output: u v der u a ln * /\n explain: "The derivative of {u}, over {u} times the natural log of {a}."\n tags: [chain]\n\n - id: d-abs\n name: Derivative of an absolute value\n mode: differentiate\n pattern: u abs v der\n output: u u abs / u v der *\n explain: "The absolute value keeps the sign of {u}: {u} over its absolute value, times the derivative of {u}."\n tags: [chain]\n\n # n-th root: `n u root`\n - id: d-root\n name: Derivative of a root\n mode: differentiate\n pattern: n u root v der\n require:\n - [freeOf, n, v]\n output: u v der n n u root n 1 - ^ * /\n fold: true\n explain: "The derivative of {u}, over {n} times the {n}th root of {u} to the power {n} minus 1."\n tags: [chain]\n','name: More derivatives\n\n# Derivative rules the CAS adds to rules/calculus.yaml (which calcvidnew also uses).\n\nrules:\n - id: d-general-power\n name: A power with the variable in both places\n mode: differentiate\n pattern: u w ^ v der\n require:\n - [dependsOn, u, v]\n - [dependsOn, w, v]\n output: u w ^ w v der u ln * w u v der * u / + *\n explain: "Write {u}^{w} as e^({w} ln {u}) and use the chain rule: the derivative is {u}^{w} times the derivative of {w} ln {u}."\n tags: [chain]\n','name: Integrals\n\n# mode: integrate. `f v 2 int` is ∫ f dv (MathZetta\'s postfix; the 2 counts f and v).\n# Each rule turns one integral into smaller ones, or into an answer. The CAS also\n# tries, when no rule fits: multiplying out, a linear substitution (∫ f(ax + b) dx\n# from the rule for ∫ f(u) du), and integration by parts for polynomial × e^, sin,\n# cos, ln, arctan. Definite integrals are the antiderivative between the limits.\n#\n# Patterns see the normal form: 1/x is "1 x /", x^-2 is "1 x 2 ^ /", √x is "x sqrt",\n# 1/√(1 - x²) is "1 x 2 ^ neg 1 + sqrt /".\n\nrules:\n # ---- splitting -----------------------------------------------------------\n - id: i-sum\n name: Sum rule\n mode: integrate\n pattern: u w + v 2 int\n output: u v 2 int w v 2 int +\n explain: "Integrate {u} and {w} separately, and add."\n tags: [split]\n\n - id: i-difference\n name: Difference rule\n mode: integrate\n pattern: u w - v 2 int\n output: u v 2 int w v 2 int -\n explain: "Integrate {u} and {w} separately, and subtract."\n tags: [split]\n\n - id: i-negate\n name: A minus sign\n mode: integrate\n pattern: u neg v 2 int\n output: u v 2 int neg\n explain: "The minus sign comes out of the integral."\n tags: [split]\n\n - id: i-constant-multiple\n name: Constant multiple\n mode: integrate\n pattern: c u * v 2 int\n commutative: true\n require:\n - [freeOf, c, v]\n - [dependsOn, u, v]\n output: c u v 2 int *\n priority: 5\n explain: "{c} doesn\'t change with {v}, so it comes out of the integral."\n tags: [split]\n\n - id: i-constant-divisor\n name: Dividing by a constant\n mode: integrate\n pattern: u c / v 2 int\n require:\n - [freeOf, c, v]\n - [dependsOn, u, v]\n output: u v 2 int c /\n priority: 5\n explain: "Dividing by {c} comes out of the integral."\n tags: [split]\n\n - id: i-constant-over\n name: A constant over something\n mode: integrate\n pattern: c u / v 2 int\n require:\n - [freeOf, c, v]\n - [dependsOn, u, v]\n when:\n c: [notOne]\n output: c 1 u / v 2 int *\n priority: 4\n explain: "{c} comes out of the integral, leaving ∫ 1/{u}."\n tags: [split]\n\n # ---- the table -----------------------------------------------------------\n - id: i-constant\n name: Integral of a constant\n mode: integrate\n pattern: c v 2 int\n require:\n - [freeOf, c, v]\n output: c v *\n priority: 10\n explain: "A constant {c} integrates to {c}·{v}."\n tags: [base]\n\n - id: i-variable\n name: Integral of the variable\n mode: integrate\n pattern: u v 2 int\n require:\n - [sameAs, u, v]\n output: v 2 ^ 2 /\n priority: 10\n explain: "∫ {v} d{v} = {v}²/2."\n tags: [base]\n\n - id: i-power\n name: Power rule\n mode: integrate\n pattern: u n ^ v 2 int\n require:\n - [sameAs, u, v]\n - [freeOf, n, v]\n when:\n n: [notMinusOne]\n output: v n 1 + ^ n 1 + /\n explain: "Add 1 to the power and divide by the new power: {result}."\n tags: [power]\n\n - id: i-reciprocal\n name: Integral of 1/x\n mode: integrate\n pattern: 1 u / v 2 int\n require:\n - [sameAs, u, v]\n output: v abs ln\n explain: "∫ 1/{v} d{v} = ln|{v}| (the power rule can\'t divide by 0 here)."\n tags: [log]\n\n - id: i-reciprocal-power\n name: Power rule (a power below)\n mode: integrate\n pattern: 1 u n ^ / v 2 int\n require:\n - [sameAs, u, v]\n - [freeOf, n, v]\n when:\n n: [notOne]\n output: v 1 n - ^ 1 n - /\n explain: "1/{v}^{n} is {v}^(-{n}): add 1 to the power and divide by it."\n tags: [power]\n\n - id: i-sqrt\n name: Integral of a square root\n mode: integrate\n pattern: u sqrt v 2 int\n require:\n - [sameAs, u, v]\n output: 2 v 3 2 / ^ * 3 /\n explain: "√{v} is {v}^(1/2): add 1 to the power and divide by 3/2."\n tags: [power]\n\n - id: i-reciprocal-sqrt\n name: Integral of 1/√x\n mode: integrate\n pattern: 1 u sqrt / v 2 int\n require:\n - [sameAs, u, v]\n output: 2 v sqrt *\n explain: "1/√{v} is {v}^(-1/2): add 1 to the power and divide by 1/2."\n tags: [power]\n\n - id: i-root\n name: Integral of a root\n mode: integrate\n pattern: n u root v 2 int\n require:\n - [sameAs, u, v]\n - [freeOf, n, v]\n output: v 1 n / 1 + ^ 1 n / 1 + /\n explain: "The {n}th root of {v} is {v}^(1/{n}): add 1 to the power and divide by it."\n tags: [power]\n\n - id: i-exp\n name: Integral of e^x\n mode: integrate\n pattern: =e u ^ v 2 int\n require:\n - [sameAs, u, v]\n output: =e v ^\n explain: "e^{v} is its own integral."\n tags: [exp]\n\n - id: i-exponential\n name: Integral of a^x\n mode: integrate\n pattern: a u ^ v 2 int\n require:\n - [sameAs, u, v]\n - [freeOf, a, v]\n output: a v ^ a ln /\n explain: "∫ {a}^{v} d{v} = {a}^{v} / ln {a}."\n tags: [exp]\n\n - id: i-ln\n name: Integral of ln x\n mode: integrate\n pattern: u ln v 2 int\n require:\n - [sameAs, u, v]\n output: v v ln * v -\n explain: "By parts: ∫ ln {v} d{v} = {v} ln {v} - {v}."\n tags: [log]\n\n - { id: i-sin, name: Integral of sin, mode: integrate, pattern: u sin v 2 int, require: [[sameAs, u, v]], output: v cos neg, tags: [trig], explain: "The derivative of -cos {v} is sin {v}." }\n - { id: i-cos, name: Integral of cos, mode: integrate, pattern: u cos v 2 int, require: [[sameAs, u, v]], output: v sin, tags: [trig], explain: "The derivative of sin {v} is cos {v}." }\n - { id: i-tan, name: Integral of tan, mode: integrate, pattern: u tan v 2 int, require: [[sameAs, u, v]], output: v cos abs ln neg, tags: [trig], explain: "tan = sin/cos, and -ln|cos {v}| differentiates to it." }\n - { id: i-sec-squared, name: Integral of sec², mode: integrate, pattern: 1 u cos 2 ^ / v 2 int, require: [[sameAs, u, v]], output: v tan, tags: [trig], explain: "The derivative of tan {v} is 1/cos²{v}." }\n - { id: i-sec-squared-written, name: Integral of sec², mode: integrate, pattern: u sec 2 ^ v 2 int, require: [[sameAs, u, v]], output: v tan, tags: [trig], explain: "The derivative of tan {v} is sec²{v}." }\n - { id: i-csc-squared, name: Integral of csc², mode: integrate, pattern: 1 u sin 2 ^ / v 2 int, require: [[sameAs, u, v]], output: v cot neg, tags: [trig], explain: "The derivative of -cot {v} is 1/sin²{v}." }\n - { id: i-sin-squared, name: Integral of sin², mode: integrate, pattern: u sin 2 ^ v 2 int, require: [[sameAs, u, v]], output: v 2 / 2 v * sin 4 / -, tags: [trig], explain: "sin²{v} = (1 - cos 2{v})/2, which integrates term by term." }\n - { id: i-cos-squared, name: Integral of cos², mode: integrate, pattern: u cos 2 ^ v 2 int, require: [[sameAs, u, v]], output: v 2 / 2 v * sin 4 / +, tags: [trig], explain: "cos²{v} = (1 + cos 2{v})/2, which integrates term by term." }\n - { id: i-sinh, name: Integral of sinh, mode: integrate, pattern: u sinh v 2 int, require: [[sameAs, u, v]], output: v cosh, tags: [trig], explain: "The derivative of cosh {v} is sinh {v}." }\n - { id: i-cosh, name: Integral of cosh, mode: integrate, pattern: u cosh v 2 int, require: [[sameAs, u, v]], output: v sinh, tags: [trig], explain: "The derivative of sinh {v} is cosh {v}." }\n - { id: i-arctan, name: Integral of 1/(1 + x²), mode: integrate, pattern: 1 u 2 ^ 1 + / v 2 int, require: [[sameAs, u, v]], output: v arctan, tags: [trig], explain: "The derivative of arctan {v} is 1/(1 + {v}²)." }\n - { id: i-arcsin, name: Integral of 1/√(1 - x²), mode: integrate, pattern: 1 u 2 ^ neg 1 + sqrt / v 2 int, require: [[sameAs, u, v]], output: v arcsin, tags: [trig], explain: "The derivative of arcsin {v} is 1/√(1 - {v}²)." }\n','name: Values and identities\n\n# The CAS\'s simplify rules (mode: simplify). They see expressions in normal form\n# (src/cas/form.js), as drawn: x/2, 2x - 3, -x, √x is "x sqrt",\n# ∛x is "3 x root", π/6 is "=pi 6 /", 2π/3 is "2 =pi * 3 /", e^x is "=e x ^".\n#\n# - a word is a slot (u, v, n …); a fixed symbol is written =pi, =e\n# - a number is itself; "1 2 /" is ½\n# - arithmetic (2 + 3, x + x, √8 = 2√2) is done for you before and after every rule\n# - a rule for a sum or product of two parts also fires on any two parts of a longer one\n# - tags pick what a step list shows (steps: \'brief\' hides value, identity, tidy …)\n#\n# To change one: copy it into a file of your own with the same id and edit it;\n# to turn one off: give its id with enabled: false. createCAS({ rules: [yours] }).\n\nrules:\n # ---- logs and exponentials -------------------------------------------\n - id: ln-one\n name: Log of 1\n pattern: 1 ln\n output: "0"\n explain: "e^0 = 1, so ln 1 = 0."\n tags: [value]\n\n - id: ln-e\n name: Log of e\n pattern: =e ln\n output: "1"\n explain: "e^1 = e, so ln e = 1."\n tags: [value]\n\n - id: ln-exp\n name: Log undoes e to a power\n pattern: =e u ^ ln\n output: u\n explain: "ln and e^ undo each other: ln(e^{u}) = {u}."\n tags: [inverse]\n\n - id: exp-ln\n name: e to a power undoes the log\n pattern: =e u ln ^\n output: u\n explain: "e^ and ln undo each other: e^(ln {u}) = {u} (for {u} > 0)."\n tags: [inverse]\n\n - id: exp-multiple-ln\n name: A multiple of a log in a power\n pattern: =e n u ln * ^\n when:\n n: [isRational]\n output: u n ^\n explain: "e^({n} ln {u}) = (e^(ln {u}))^{n} = {result}."\n tags: [inverse]\n\n - id: log-same-base\n name: Log of its own base\n pattern: b b log\n output: "1"\n explain: "{b}^1 = {b}, so the log of {b} to base {b} is 1."\n tags: [value]\n\n - id: log-of-power\n name: Log undoes a power of its base\n pattern: b b u ^ log\n output: u\n explain: "log base {b} and {b}^ undo each other."\n tags: [inverse]\n\n - id: power-of-log\n name: A power undoes the log to its base\n pattern: b b u log ^\n output: u\n explain: "{b}^(log base {b} of {u}) = {u}."\n tags: [inverse]\n\n # ---- roots and absolute value --------------------------------------------\n - id: sqrt-of-square\n name: Square root of a square\n pattern: u 2 ^ sqrt\n output: u abs\n explain: "√({u}²) is the size of {u}, whatever its sign: |{u}|."\n tags: [identity]\n\n - id: abs-squared\n name: Absolute value squared\n pattern: u abs 2 ^\n output: u 2 ^\n explain: "Squaring removes the sign anyway: |{u}|² = {u}²."\n tags: [identity]\n\n - id: abs-of-abs\n name: Absolute value twice\n pattern: u abs abs\n output: u abs\n explain: "|{u}| is never negative, so its absolute value is itself."\n tags: [identity]\n\n - id: abs-positive\n name: Absolute value of a positive number\n pattern: u abs\n when:\n u: [isPositiveConstant]\n output: u\n explain: "{u} is positive, so |{u}| = {u}."\n tags: [value]\n\n - id: abs-negative\n name: Absolute value of a negative number\n pattern: u abs\n when:\n u: [isNegativeConstant]\n output: u neg\n explain: "{u} is negative, so |{u}| = -({u})."\n tags: [value]\n\n - id: abs-of-exp\n name: e to a power is positive\n pattern: =e u ^ abs\n output: =e u ^\n explain: "e to any power is positive, so the absolute value changes nothing."\n tags: [identity]\n\n # ---- trigonometry: signs and turns ---------------------------------------\n - id: sin-odd\n name: Sine of a negative angle\n pattern: u sin\n when:\n u: [hasMinusSign]\n output: u neg sin neg\n explain: "sin(-θ) = -sin θ."\n tags: [symmetry]\n\n - id: cos-even\n name: Cosine of a negative angle\n pattern: u cos\n when:\n u: [hasMinusSign]\n output: u neg cos\n explain: "cos(-θ) = cos θ."\n tags: [symmetry]\n\n - id: tan-odd\n name: Tangent of a negative angle\n pattern: u tan\n when:\n u: [hasMinusSign]\n output: u neg tan neg\n explain: "tan(-θ) = -tan θ."\n tags: [symmetry]\n\n - id: sin-full-turn\n name: A full turn\n pattern: u sin\n when:\n u: [[piMultipleAtLeast, 2]]\n output: u 2 =pi * - sin\n explain: "Turning a full 2π brings you back: sin({u}) = sin({u} - 2π)."\n tags: [symmetry]\n\n - id: cos-full-turn\n name: A full turn\n pattern: u cos\n when:\n u: [[piMultipleAtLeast, 2]]\n output: u 2 =pi * - cos\n explain: "Turning a full 2π brings you back: cos({u}) = cos({u} - 2π)."\n tags: [symmetry]\n\n - id: tan-half-turn\n name: Tangent repeats every π\n pattern: u tan\n when:\n u: [[piMultipleAtLeast, 1]]\n output: u =pi - tan\n explain: "tan repeats every π: tan({u}) = tan({u} - π)."\n tags: [symmetry]\n\n - id: sin-half-turn\n name: A half turn\n pattern: u sin\n when:\n u: [[piMultipleAbove, 1], [piMultipleBelow, 2]]\n output: u =pi - sin neg\n explain: "Half a turn flips the sign: sin({u}) = -sin({u} - π)."\n tags: [symmetry]\n\n - id: cos-half-turn\n name: A half turn\n pattern: u cos\n when:\n u: [[piMultipleAbove, 1], [piMultipleBelow, 2]]\n output: u =pi - cos neg\n explain: "Half a turn flips the sign: cos({u}) = -cos({u} - π)."\n tags: [symmetry]\n\n - id: sin-second-quarter\n name: The second quarter turn\n pattern: u sin\n when:\n u: [[piMultipleAbove, 1/2], [piMultipleAtMost, 1]]\n output: =pi u - sin\n explain: "sin({u}) = sin(π - {u})."\n tags: [symmetry]\n\n - id: cos-second-quarter\n name: The second quarter turn\n pattern: u cos\n when:\n u: [[piMultipleAbove, 1/2], [piMultipleAtMost, 1]]\n output: =pi u - cos neg\n explain: "cos({u}) = -cos(π - {u})."\n tags: [symmetry]\n\n - id: tan-second-quarter\n name: The second quarter turn\n pattern: u tan\n when:\n u: [[piMultipleAbove, 1/2], [piMultipleBelow, 1]]\n output: =pi u - tan neg\n explain: "tan({u}) = -tan(π - {u})."\n tags: [symmetry]\n\n # ---- trigonometry: the standard angles -------------------------------------\n - { id: sin-0, name: Sine of 0, pattern: 0 sin, output: "0", tags: [value], explain: "sin 0 = 0." }\n - { id: sin-pi-6, name: Sine of π/6, pattern: =pi 6 / sin, output: 1 2 /, tags: [value], explain: "sin(π/6) = 1/2." }\n - { id: sin-pi-4, name: Sine of π/4, pattern: =pi 4 / sin, output: 2 sqrt 2 /, tags: [value], explain: "sin(π/4) = √2/2." }\n - { id: sin-pi-3, name: Sine of π/3, pattern: =pi 3 / sin, output: 3 sqrt 2 /, tags: [value], explain: "sin(π/3) = √3/2." }\n - { id: sin-pi-2, name: Sine of π/2, pattern: =pi 2 / sin, output: "1", tags: [value], explain: "sin(π/2) = 1." }\n - { id: sin-pi, name: Sine of π, pattern: =pi sin, output: "0", tags: [value], explain: "sin π = 0." }\n - { id: cos-0, name: Cosine of 0, pattern: 0 cos, output: "1", tags: [value], explain: "cos 0 = 1." }\n - { id: cos-pi-6, name: Cosine of π/6, pattern: =pi 6 / cos, output: 3 sqrt 2 /, tags: [value], explain: "cos(π/6) = √3/2." }\n - { id: cos-pi-4, name: Cosine of π/4, pattern: =pi 4 / cos, output: 2 sqrt 2 /, tags: [value], explain: "cos(π/4) = √2/2." }\n - { id: cos-pi-3, name: Cosine of π/3, pattern: =pi 3 / cos, output: 1 2 /, tags: [value], explain: "cos(π/3) = 1/2." }\n - { id: cos-pi-2, name: Cosine of π/2, pattern: =pi 2 / cos, output: "0", tags: [value], explain: "cos(π/2) = 0." }\n - { id: cos-pi, name: Cosine of π, pattern: =pi cos, output: "-1", tags: [value], explain: "cos π = -1." }\n - { id: tan-0, name: Tangent of 0, pattern: 0 tan, output: "0", tags: [value], explain: "tan 0 = 0." }\n - { id: tan-pi-6, name: Tangent of π/6, pattern: =pi 6 / tan, output: 3 sqrt 3 /, tags: [value], explain: "tan(π/6) = √3/3." }\n - { id: tan-pi-4, name: Tangent of π/4, pattern: =pi 4 / tan, output: "1", tags: [value], explain: "tan(π/4) = 1." }\n - { id: tan-pi-3, name: Tangent of π/3, pattern: =pi 3 / tan, output: 3 sqrt, tags: [value], explain: "tan(π/3) = √3." }\n - { id: arcsin-0, name: Arcsine of 0, pattern: 0 arcsin, output: "0", tags: [value], explain: "sin 0 = 0, so arcsin 0 = 0." }\n - { id: arcsin-half, name: Arcsine of 1/2, pattern: 1 2 / arcsin, output: =pi 6 /, tags: [value], explain: "sin(π/6) = 1/2, so arcsin(1/2) = π/6." }\n - { id: arcsin-1, name: Arcsine of 1, pattern: 1 arcsin, output: =pi 2 /, tags: [value], explain: "sin(π/2) = 1, so arcsin 1 = π/2." }\n - { id: arccos-0, name: Arccosine of 0, pattern: 0 arccos, output: =pi 2 /, tags: [value], explain: "cos(π/2) = 0, so arccos 0 = π/2." }\n - { id: arccos-half, name: Arccosine of 1/2, pattern: 1 2 / arccos, output: =pi 3 /, tags: [value], explain: "cos(π/3) = 1/2, so arccos(1/2) = π/3." }\n - { id: arccos-1, name: Arccosine of 1, pattern: 1 arccos, output: "0", tags: [value], explain: "cos 0 = 1, so arccos 1 = 0." }\n - { id: arccos-minus-1, name: Arccosine of -1, pattern: -1 arccos, output: =pi, tags: [value], explain: "cos π = -1, so arccos(-1) = π." }\n - { id: arctan-0, name: Arctangent of 0, pattern: 0 arctan, output: "0", tags: [value], explain: "tan 0 = 0, so arctan 0 = 0." }\n - { id: arctan-1, name: Arctangent of 1, pattern: 1 arctan, output: =pi 4 /, tags: [value], explain: "tan(π/4) = 1, so arctan 1 = π/4." }\n - { id: sinh-0, name: sinh of 0, pattern: 0 sinh, output: "0", tags: [value], explain: "sinh 0 = 0." }\n - { id: cosh-0, name: cosh of 0, pattern: 0 cosh, output: "1", tags: [value], explain: "cosh 0 = 1." }\n - { id: tanh-0, name: tanh of 0, pattern: 0 tanh, output: "0", tags: [value], explain: "tanh 0 = 0." }\n\n - { id: arctan-sqrt3, name: Arctangent of √3, pattern: 3 sqrt arctan, output: =pi 3 /, tags: [value], explain: "tan(π/3) = √3, so arctan √3 = π/3." }\n - { id: arctan-sqrt3-over-3, name: Arctangent of √3/3, pattern: 3 sqrt 3 / arctan, output: =pi 6 /, tags: [value], explain: "tan(π/6) = √3/3, so arctan(√3/3) = π/6." }\n\n # atan2(y, x): the angle of the point (x, y), in (-π, π]\n - id: atan2-right\n name: The angle of a point to the right\n pattern: y x atan2\n when:\n x: [isPositiveConstant]\n output: y x / arctan\n explain: "For x > 0, atan2(y, x) = arctan(y/x)."\n tags: [value]\n - id: atan2-left-up\n name: The angle of a point to the left\n pattern: y x atan2\n when:\n x: [isNegativeConstant]\n y: [isPositiveConstant]\n output: y x / arctan =pi +\n explain: "For x < 0 and y > 0, atan2(y, x) = arctan(y/x) + π."\n tags: [value]\n - id: atan2-left-down\n name: The angle of a point to the left\n pattern: y x atan2\n when:\n x: [isNegativeConstant]\n y: [isNegativeConstant]\n output: y x / arctan =pi -\n explain: "For x < 0 and y < 0, atan2(y, x) = arctan(y/x) - π."\n tags: [value]\n - { id: atan2-negative-axis, name: The angle of a point on the negative axis, pattern: 0 x atan2, when: { x: [isNegativeConstant] }, output: =pi, tags: [value], explain: "A point on the negative x-axis is at angle π." }\n - { id: atan2-up, name: Straight up, pattern: y 0 atan2, when: { y: [isPositiveConstant] }, output: =pi 2 /, tags: [value], explain: "A point straight up is at angle π/2." }\n - { id: atan2-down, name: Straight down, pattern: y 0 atan2, when: { y: [isNegativeConstant] }, output: =pi 2 / neg, tags: [value], explain: "A point straight down is at angle -π/2." }\n\n # the odd inverses take the sign out; arccos(-u) = π - arccos u\n - id: arcsin-odd\n name: Arcsine of a negative\n pattern: u arcsin\n when:\n u: [hasMinusSign]\n output: u neg arcsin neg\n explain: "arcsin(-x) = -arcsin x."\n tags: [symmetry]\n\n - id: arctan-odd\n name: Arctangent of a negative\n pattern: u arctan\n when:\n u: [hasMinusSign]\n output: u neg arctan neg\n explain: "arctan(-x) = -arctan x."\n tags: [symmetry]\n\n - id: arccos-negative\n name: Arccosine of a negative\n pattern: u arccos\n when:\n u: [hasMinusSign]\n output: =pi u neg arccos -\n explain: "arccos(-x) = π - arccos x."\n tags: [symmetry]\n\n # ---- trigonometry: identities --------------------------------------------\n - id: pythagorean\n name: sin² + cos² = 1\n pattern: u sin 2 ^ u cos 2 ^ +\n commutative: true\n output: "1"\n explain: "sin²{u} + cos²{u} = 1 for every angle."\n tags: [identity]\n\n - id: pythagorean-multiple\n name: sin² + cos² = 1\n pattern: a u sin 2 ^ * a u cos 2 ^ * +\n commutative: true\n output: a\n explain: "{a}·sin²{u} + {a}·cos²{u} = {a}(sin²{u} + cos²{u}) = {a}."\n tags: [identity]\n\n - id: one-minus-sin-squared\n name: 1 - sin² = cos²\n pattern: u sin 2 ^ neg 1 +\n output: u cos 2 ^\n explain: "1 - sin²{u} = cos²{u}."\n tags: [identity]\n\n - id: one-minus-cos-squared\n name: 1 - cos² = sin²\n pattern: u cos 2 ^ neg 1 +\n output: u sin 2 ^\n explain: "1 - cos²{u} = sin²{u}."\n tags: [identity]\n\n - id: sin-over-cos\n name: sin/cos is tan\n pattern: u sin u cos /\n output: u tan\n explain: "sin {u} / cos {u} = tan {u}."\n tags: [identity]\n\n - id: cos-over-sin\n name: cos/sin is cot\n pattern: u cos u sin /\n output: u cot\n explain: "cos {u} / sin {u} = cot {u}."\n tags: [identity]\n\n - id: sin-arcsin\n name: sin undoes arcsin\n pattern: u arcsin sin\n output: u\n explain: "sin(arcsin {u}) = {u}."\n tags: [inverse]\n\n - id: cos-arccos\n name: cos undoes arccos\n pattern: u arccos cos\n output: u\n explain: "cos(arccos {u}) = {u}."\n tags: [inverse]\n\n - id: tan-arctan\n name: tan undoes arctan\n pattern: u arctan tan\n output: u\n explain: "tan(arctan {u}) = {u}."\n tags: [inverse]\n\n - id: cosh-squared-minus-sinh-squared\n name: cosh² - sinh² = 1\n pattern: u cosh 2 ^ u sinh 2 ^ -\n output: "1"\n explain: "cosh²{u} - sinh²{u} = 1."\n tags: [identity]\n\n # ---- logs: opt-in rewrites (run with cas.rewrite(x, \'expand-log\') or \'combine-log\') ----\n - id: ln-product\n name: Log of a product\n mode: expand-log\n pattern: a b * ln\n output: a ln b ln +\n explain: "ln({a}·{b}) = ln {a} + ln {b} (for positive {a}, {b})."\n tags: [log]\n\n - id: ln-quotient\n name: Log of a quotient\n mode: expand-log\n pattern: a b / ln\n output: a ln b ln -\n explain: "ln({a}/{b}) = ln {a} - ln {b} (for positive {a}, {b})."\n tags: [log]\n\n - id: ln-power\n name: Log of a power\n mode: expand-log\n pattern: a n ^ ln\n output: n a ln *\n explain: "ln({a}^{n}) = {n}·ln {a} (for positive {a})."\n tags: [log]\n\n - id: ln-root\n name: Log of a square root\n mode: expand-log\n pattern: a sqrt ln\n output: a ln 2 /\n explain: "ln √{a} = ½ ln {a}."\n tags: [log]\n\n - id: ln-sum-combine\n name: Sum of logs\n mode: combine-log\n pattern: a ln b ln +\n commutative: true\n output: a b * ln\n explain: "ln {a} + ln {b} = ln({a}·{b})."\n tags: [log]\n\n - id: ln-difference-combine\n name: Difference of logs\n mode: combine-log\n pattern: a ln b ln -\n output: a b / ln\n explain: "ln {a} - ln {b} = ln({a}/{b})."\n tags: [log]\n\n - id: ln-multiple-combine\n name: A multiple of a log\n mode: combine-log\n pattern: n a ln *\n when:\n n: [isRational]\n output: a n ^ ln\n explain: "{n}·ln {a} = ln({a}^{n})."\n tags: [log]\n','name: Solving by undoing\n\n# mode: isolate. Each rule undoes the outermost function on the side with the\n# unknown: ln u = r → u = e^r. The predicates hasVariable and freeOfVariable mean\n# "mentions / doesn\'t mention the unknown being solved for".\n#\n# The CAS does the rest itself: it moves terms without the unknown to the other\n# side, divides by a coefficient, and when the unknown appears in several places\n# it uses the polynomial methods (factoring, the quadratic formula) or splits a\n# product equal to 0. Every answer is checked in the original equation, so a\n# rule may give extra candidates (squaring both sides does): the wrong ones are\n# dropped, with a step saying so.\n#\n# An output can give several answers: `pm` (±) splits into two, and so does\n# `|` (or): "u r arcsin = u =pi r arcsin - = |".\n\nrules:\n - id: iso-swap\n name: Unknown on the left\n mode: isolate\n pattern: l r =\n when:\n l: [freeOfVariable]\n r: [hasVariable]\n output: r l =\n priority: 20\n explain: "Swap the sides so the unknown is on the left."\n tags: [tidy]\n\n - id: iso-ln\n name: Undo the log\n mode: isolate\n pattern: u ln r =\n when:\n u: [hasVariable]\n output: u =e r ^ =\n explain: "Raise e to each side: e^(ln {u}) = {u}."\n tags: [inverse]\n\n - id: iso-log\n name: Undo the log\n mode: isolate\n pattern: b u log r =\n when:\n u: [hasVariable]\n b: [freeOfVariable]\n output: u b r ^ =\n explain: "Raise {b} to each side: {b}^(log base {b} of {u}) = {u}."\n tags: [inverse]\n\n - id: iso-exp\n name: Undo e to a power\n mode: isolate\n pattern: =e u ^ r =\n when:\n u: [hasVariable]\n output: u r ln =\n explain: "Take ln of each side: ln(e^{u}) = {u}."\n tags: [inverse]\n\n - id: iso-exponential\n name: Undo a power of a number\n mode: isolate\n pattern: b u ^ r =\n when:\n u: [hasVariable]\n b: [freeOfVariable]\n output: u b r log =\n explain: "Take the log to base {b} of each side."\n tags: [inverse]\n\n - id: iso-square\n name: Undo the square\n mode: isolate\n pattern: u 2 ^ r =\n when:\n u: [hasVariable]\n output: u r sqrt pm =\n priority: 1\n explain: "Take the square root of each side; {u} can be positive or negative."\n tags: [inverse]\n\n - id: iso-even-power\n name: Undo an even power\n mode: isolate\n pattern: u n ^ r =\n when:\n u: [hasVariable]\n n: [isEvenWhole]\n output: u r 1 n / ^ pm =\n explain: "Take the root of each side (the {n}th root); {u} can be positive or negative."\n tags: [inverse]\n\n - id: iso-odd-power\n name: Undo an odd power\n mode: isolate\n pattern: u n ^ r =\n when:\n u: [hasVariable]\n n: [isOddWhole]\n output: u r 1 n / ^ =\n explain: "Take the root of each side (the {n}th root)."\n tags: [inverse]\n\n - id: iso-fractional-power\n name: Undo a power\n mode: isolate\n pattern: u n ^ r =\n when:\n u: [hasVariable]\n n: [isRational]\n output: u r 1 n / ^ =\n priority: -1\n explain: "Raise each side to the power 1/{n}."\n tags: [inverse]\n\n - id: iso-sqrt\n name: Undo the square root\n mode: isolate\n pattern: u sqrt r =\n when:\n u: [hasVariable]\n output: u r 2 ^ =\n explain: "Square each side (this can add answers, so each one is checked at the end)."\n tags: [inverse]\n\n - id: iso-root\n name: Undo the root\n mode: isolate\n pattern: n u root r =\n when:\n u: [hasVariable]\n n: [freeOfVariable]\n output: u r n ^ =\n explain: "Raise each side to the power {n}."\n tags: [inverse]\n\n - id: iso-reciprocal\n name: Undo the fraction\n mode: isolate\n pattern: c u / r =\n when:\n u: [hasVariable]\n c: [freeOfVariable]\n output: u c r / =\n explain: "{c}/{u} = {r}, so {u} = {c}/{r}."\n tags: [inverse]\n\n - id: iso-abs\n name: Undo the absolute value\n mode: isolate\n pattern: u abs r =\n when:\n u: [hasVariable]\n output: u r pm =\n explain: "|{u}| = {r} means {u} is {r} or -{r}."\n tags: [inverse]\n\n - id: iso-sin\n name: Undo the sine\n mode: isolate\n pattern: u sin r =\n when:\n u: [hasVariable]\n output: u r arcsin = u =pi r arcsin - = |\n explain: "Two angles in a turn have sine {r}: arcsin {r} and π - arcsin {r} (add any whole number of turns, 2πk, for the rest)."\n tags: [inverse, trig]\n\n - id: iso-cos\n name: Undo the cosine\n mode: isolate\n pattern: u cos r =\n when:\n u: [hasVariable]\n output: u r arccos pm =\n explain: "Two angles in a turn have cosine {r}: ±arccos {r} (add 2πk for the rest)."\n tags: [inverse, trig]\n\n - id: iso-tan\n name: Undo the tangent\n mode: isolate\n pattern: u tan r =\n when:\n u: [hasVariable]\n output: u r arctan =\n explain: "Take arctan of each side (add πk for the rest)."\n tags: [inverse, trig]\n\n - { id: iso-arcsin, name: Undo arcsin, mode: isolate, pattern: u arcsin r =, when: { u: [hasVariable] }, output: u r sin =, tags: [inverse], explain: "Take sin of each side." }\n - { id: iso-arccos, name: Undo arccos, mode: isolate, pattern: u arccos r =, when: { u: [hasVariable] }, output: u r cos =, tags: [inverse], explain: "Take cos of each side." }\n - { id: iso-arctan, name: Undo arctan, mode: isolate, pattern: u arctan r =, when: { u: [hasVariable] }, output: u r tan =, tags: [inverse], explain: "Take tan of each side." }\n - { id: iso-sinh, name: Undo sinh, mode: isolate, pattern: u sinh r =, when: { u: [hasVariable] }, output: u r arcsinh =, tags: [inverse], explain: "Take arcsinh of each side." }\n - { id: iso-tanh, name: Undo tanh, mode: isolate, pattern: u tanh r =, when: { u: [hasVariable] }, output: u r arctanh =, tags: [inverse], explain: "Take arctanh of each side." }\n - { id: iso-cosh, name: Undo cosh, mode: isolate, pattern: u cosh r =, when: { u: [hasVariable] }, output: u r arccosh pm =, tags: [inverse], explain: "Two numbers have cosh {r}: ±arccosh {r}." }\n - { id: iso-arcsinh, name: Undo arcsinh, mode: isolate, pattern: u arcsinh r =, when: { u: [hasVariable] }, output: u r sinh =, tags: [inverse], explain: "Take sinh of each side." }\n - { id: iso-arccosh, name: Undo arccosh, mode: isolate, pattern: u arccosh r =, when: { u: [hasVariable] }, output: u r cosh =, tags: [inverse], explain: "Take cosh of each side." }\n - { id: iso-arctanh, name: Undo arctanh, mode: isolate, pattern: u arctanh r =, when: { u: [hasVariable] }, output: u r tanh =, tags: [inverse], explain: "Take tanh of each side." }\n'],Hr=['name: Complex numbers\n\n# Loaded only by createCAS({ complex: true }), where i is the imaginary unit.\n# The arithmetic (i² = -1, √-4 = 2i, (2 + 3i)(1 - i) = 5 + i, 1/(1 + i) = (1 - i)/2)\n# and Re, Im, conj, arg, |z| are the normal form\'s (src/cas/form.js); unknowns\n# count as real, so Re(x + 3i) = x. Write a complex unknown as a + bi.\n\noperators:\n - { symbol: re, arity: 1, label: real part }\n - { symbol: im, arity: 1, label: imaginary part }\n - { symbol: conj, arity: 1, label: complex conjugate }\n - { symbol: arg, arity: 1, label: argument }\n\nrules:\n - id: euler\n name: Euler\'s formula\n pattern: =e u ^\n when:\n u: [hasImaginaryPart, isConstant]\n output: =e u re ^ u im cos =i u im sin * + *\n explain: "e^(a + bi) = e^a (cos b + i sin b)."\n tags: [complex]\n\n - id: ln-negative\n name: Log of a negative number\n pattern: u ln\n when:\n u: [isNegativeConstant]\n output: u neg ln =i =pi * +\n explain: "{u} = |{u}|·e^(iπ), so ln {u} = ln |{u}| + iπ (the principal value)."\n tags: [complex]\n\n - id: ln-complex\n name: Log of a complex number\n pattern: u ln\n when:\n u: [hasImaginaryPart, isConstant]\n output: u abs ln u arg =i * +\n explain: "ln z = ln |z| + i arg z (the principal value)."\n tags: [complex]\n\n - id: i-to-the-i\n name: i to the power i\n pattern: =i =i ^\n output: =e =pi 2 / neg ^\n explain: "i = e^(iπ/2), so i^i = e^(i·iπ/2) = e^(-π/2) (the principal value)."\n tags: [complex]\n'],Jr={normal:"Work out the numbers and collect like terms.","simplify.cancel":"Cancel the factors the top and bottom share.","simplify.expand":"Multiplying out gives something shorter.","simplify.factor":"Factoring gives something shorter.",expand:"Multiply out the brackets.",factor:"Write it as a product of factors.","factor.common":"Take out the common factor {common}.","factor.polynomial":"Factor what is left: {roots}.",together:"Write it as one fraction over a common denominator.",cancel:"Cancel the factors the top and bottom share: {cancelled}.","solve.move":"Keep the terms with {v} on the left and move the others to the right.","solve.divide":"Divide both sides by {by}.","solve.multiply":"Multiply both sides by {by}.","solve.one-side":"Move everything to one side, so the equation reads … = 0.","solve.factor":"Factor the left side.","solve.zero-product":"A product is 0 exactly when one of its factors is 0.","solve.split":"There are two cases; solve each.","solve.quadratic":"The quadratic formula with a = {a}, b = {b}, c = {c}: {v} = (-b ± √(b² - 4ac)) / 2a, and b² - 4ac = {D}.","solve.no-real":"b² - 4ac = {D} is negative, so there are no real solutions.","solve.quadratic-complex":"The quadratic formula with a = {a}, b = {b}, c = {c}: {v} = (-b ± √(b² - 4ac)) / 2a. b² - 4ac = {D} is negative, so its square root is imaginary: √({D}) = {root}.","solve.roots":"{v}^{n} = {r} has {n} solutions, spaced evenly round a circle: |{r}|^(1/{n})·(cos θ + i sin θ), with θ = (arg {r} + 2πk)/{n} for k = 0 … {last}.","solve.clear-denominator":"Multiply both sides by {den} (an answer that makes it 0 is not allowed).","solve.substitute":"Write {u} for {kernel}: this is a polynomial in {u}.","solve.reject":"{value} is not a solution: {reason}.","solve.always":"This is true for every {v}.","solve.never":"This is never true, so there is no solution.","solve.unsolved":"There is no exact method here for solving for {v}; try { approximate: true }.","solve.numeric":"Found {count} solution(s) numerically.","system.eliminate":"Use one equation to remove {v} from the others.","integrate.expand":"Multiply out, then integrate term by term.","integrate.substitute":"Let {u} = {inside}, so d{u} = {a} d{v}.","integrate.back":"Put {inside} back for {u}.","integrate.parts":"By parts with u = {u} and dv = {dv} d{v}: ∫ u dv = u·v - ∫ v du, where v = {V} and du = {du} d{v}.","integrate.constant":"The number {c} comes out of the integral.","integrate.divide":"The top has at least the degree of the bottom: divide first.","integrate.partial-fractions":"Split the fraction into simple fractions, one for each factor below.","integrate.evaluate":"Evaluate {F} at {b} and at {a}, and subtract.",substitute:"Put in the values."},Qr=["normal","rewrite","simplify","expand","factor","cancel","diff","differentiate","integrate","solve","solveSystem","substitute","approximate","equivalent"];class Yr{constructor(e,n,t,r,s){this.set=e,this.messages=n,this.format=t,this.read=r,this.complex=s;for(const e of Qr){const n=Yr.prototype[e];this[e]=(...e)=>le(s,()=>n.apply(this,e))}}node(e){if(e&&"object"==typeof e&&!Array.isArray(e)&&e.type)return e;if(Array.isArray(e))return W(e);if("string"!=typeof e)throw new G("expected an expression");if(this.read){const n=this.read(e);return Array.isArray(n)?W(n):"string"==typeof n?P(n):n}return P(e)}step(e,n,t,r,s,o={}){return function(e,n,t,r,s,o,i,a,u=[]){const l=(o??"").replace(/\{(\w+)\}/g,(e,n)=>{const t=i?.[n];return void 0===t?e:"string"==typeof t?t:a(t)});return{id:e,name:n,tags:t,from:r.s,to:s.s,path:u,before:r.s,after:s.s,explanation:l}}(e,n,t,r,s,this.messages[e]??"",o,this.format)}result(e,n,t,r={}){let s=e;if(t.approximate&&s){s=Ot(s,{digits:"number"==typeof t.approximate?t.approximate:15})}return{result:s,text:s?this.format(s):"",steps:Pt(n,Ut(t.steps)),...r}}variable(e,n){if(n)return n;const t=[...en(e)];return 1===t.length?t[0]:t.includes("x")?"x":t[0]??"x"}tidyStep(e,n){return e.s===n.s?[]:[this.step("normal","Work out and collect",["tidy","arithmetic"],e,n)]}normal(e){return He(this.node(e))}rewrite(e,n,t={}){const r=this.node(e),s=this.set.view(n);if(!s.size)throw new G(`no rules in mode "${n}" (modes: ${this.set.modes().join(", ")})`);const o=Ft(r,s,{format:this.format,order:t.order,variable:t.variable});return this.result(o.node,[...this.tidyStep(r,He(r)),...o.steps],t)}simplify(e,n={}){const t=this.node(e),r=[...this.tidyStep(t,He(t))],s=Ft(t,this.set.view("simplify"),{format:this.format});r.push(...s.steps);let o=s.node,i=null;const a=_e(o),u=[],l=0===en(o).size,c=l?null:pr(a);c&&u.push({node:lr(c),id:"simplify.cancel",name:"Cancel"});const f=Ft(Ge(_t(a)),this.set.view("simplify"),{format:this.format});u.push({node:f.node,id:"simplify.expand",name:"Multiply out"}),"add"!==a.k||l||u.push({node:lr(rr(a)),id:"simplify.factor",name:"Factor"});for(const e of u)_(e.node)<_(o)&&(i=this.step(e.id,e.name,["shorter"],o,e.node),o=e.node);return i&&r.push(i),this.result(o,r,n)}expand(e,n={}){const t=this.node(e),r=Ge(_t(_e(t)));return this.result(r,t.s===r.s?[]:[this.step("expand","Multiply out",["expand"],t,r)],n)}factor(e,n={}){const t=this.node(e),r=rr(_e(t)),s=lr(r),o=[],i=r.notes.find(e=>"factor.common"===e.id);return s.s!==He(t).s&&o.push(this.step(i?"factor.common":"factor","Factor",["factor"],t,s,i?{common:Ge(i.values.common)}:{})),this.result(s,o,n)}cancel(e,n={}){const t=this.node(e),r=_e(t),s=pr(r);if(!s)return this.result(He(t),this.tidyStep(t,He(t)),n);const o=lr(s),i=fr(r),a=V("/",[Ge(i.num),Ge(i.den)]),u=[];return"/"===t.op&&a.s===He(t).s||u.push(this.step("together","One fraction",["together"],t,a)),o.s!==a.s&&u.push(this.step("cancel","Cancel",["cancel"],a,o,{cancelled:s.cancelled.length?s.cancelled.map(e=>this.format(Ge(e))).join(", "):"numbers"})),this.result(o,u,n)}diff(e,n,t={}){const r=this.node(e),s=this.variable(r,n);let o=r;const i=[];for(let e=0;e<(t.order??1);e++){const e=Ft(V("der",[o,D(s)]),this.set.view("differentiate"),{format:this.format,order:"pre"}),n=Ft(e.node,this.set.view("simplify"),{format:this.format});i.push(...e.steps,...n.steps),o=n.node}return this.result(o,i,t,{variable:s})}differentiate(e,n){const t=Ft(V("der",[e,D(n)]),this.set.view("differentiate"),{format:this.format,order:"pre"});return Ft(t.node,this.set.view("simplify"),{format:this.format}).node}integrate(e,n,t={}){let r=this.node(e);const s=e=>void 0===e?null:this.node("number"==typeof e?String(e):e);let o=s(t.from),i=s(t.to);if(U(r)&&"int"===r.op){const[e,t,s,a]=r.args;n=t.token,s&&a&&(o=s,i=a),r=e}const a=this.variable(r,n),u=jr(this,r,a),l=Ft(u.node,this.set.view("simplify"),{format:this.format}),c=[...u.steps,...l.steps];if(o&&i){const e=Br(this,l.node,a,o,i,r);c.push(e.step);const n=Ft(e.value,this.set.view("simplify"),{format:this.format});return c.push(...n.steps),this.result(n.node,c,t,{antiderivative:l.node,variable:a})}let f=l.node;return t.constant&&(f=V("+",[f,D(String(t.constant))])),this.result(f,c,t,{variable:a})}solve(e,n,t={}){const r=this.node(e),s=this.variable(r,n),o=gr(this,r,s,t);let i=o.solutions;if(t.approximate){const e="number"==typeof t.approximate?t.approximate:15;i=i.map(n=>Ot(n,{digits:e}))}const a=i.map(e=>V("=",[D(s),e])),u=a.length?a.reduce((e,n)=>e?V("|",[e,n]):n,null):null;return{solutions:i,result:u,variable:s,text:o.always?`true for every ${s}`:u?this.format(u):o.unsolved.length?`no exact solution found for ${s}`:"no solution",unsolved:o.unsolved.filter(e=>!e.always),always:o.always,steps:Pt(o.steps,Ut(t.steps))}}solveSystem(e,n,t={}){const r=e.map(e=>this.node(e)),s=n??[...new Set(r.flatMap(e=>[...en(e)]))].sort(),o=function(e,n,t){const r=[],s=n.map(n=>{const r=mr(n)?Ne([_e(n.args[0]),Ve(_e(n.args[1]))]):_e(n),s=t.map(n=>{const t=Jt(r,n);if(!t||Math.max(0,...t.keys())>1)throw new G(`not linear in ${n}`);const s=t.get(1)??pe(te.ZERO);if(!ge(s))throw new G(`the coefficient of ${n} must be a number (it is ${e.format(Ge(s))})`);return s.q});let o=r;for(let e=0;e<t.length;e++)o=Ne([o,Ie([pe(s[e].neg()),_e(D(t[e]))])]);for(const e of t)if(Qt(o,e))throw new G(`not linear in ${e}`);return{coeffs:s,rhs:Ve(o)}}),o=()=>s.map(e=>dr(Ge(Ne(e.coeffs.map((e,n)=>Ie([pe(e),_e(D(t[n]))])))),Ge(e.rhs))).reduce((e,n)=>e?V("&",[e,n]):n,null);let i=0;const a=[];for(let n=0;n<t.length&&i<s.length;n++){const u=s.findIndex((e,t)=>t>=i&&!e.coeffs[n].isZero);if(u<0)continue;[s[i],s[u]]=[s[u],s[i]];const l=o(),c=s[i],f=c.coeffs[n];c.coeffs=c.coeffs.map(e=>e.div(f)),c.rhs=Ie([pe(f.inv()),c.rhs]);for(let e=0;e<s.length;e++){if(e===i||s[e].coeffs[n].isZero)continue;const t=s[e].coeffs[n];s[e].coeffs=s[e].coeffs.map((e,n)=>e.sub(t.mul(c.coeffs[n]))),s[e].rhs=Ne([s[e].rhs,Ie([pe(t.neg()),c.rhs])])}r.push(e.step("system.eliminate","Eliminate",["eliminate"],l,o(),{v:D(t[n])})),a.push(n),i++}for(const e of s.slice(i))if(!ge(e.rhs)||!e.rhs.q.isZero)return{solution:null,steps:r,status:"none"};if(a.length<t.length)return{solution:null,steps:r,status:"many"};const u=new Map;return a.forEach((e,n)=>u.set(t[e],Ge(s[n].rhs))),{solution:u,steps:r,status:"one"}}(this,r,s),i=o.solution?Object.fromEntries([...o.solution].map(([e,n])=>[e,n])):null,a="one"===o.status?s.map(e=>`${e} = ${this.format(i[e])}`).join(", "):"none"===o.status?"no solution":"infinitely many solutions";return{solution:i,status:o.status,text:a,steps:Pt(o.steps,Ut(t.steps))}}substitute(e,n,t={}){const r=this.node(e);let s=r;for(const[e,t]of Object.entries(n))s=wr(s,e,"number"==typeof t?this.node(String(t)):this.node(t));const o=this.simplify(s,t),i=[this.step("substitute","Substitute",["substitute"],r,s)];return{...o,steps:[...Pt(i,Ut(t.steps)),...o.steps]}}defined(e){const n=this.set.view("define");return n.size?Ft(e,n,{format:this.format}).node:e}approximate(e,n={}){const t=this.defined(this.node(e));if(en(t).size&&!n.scope){const e=Ot(He(t),n);return{result:e,text:this.format(e),number:null,exact:!1}}const r=kt(t,n);return{result:r.node,text:r.text,number:r.number,re:r.re,im:r.im,exact:r.exact}}equivalent(e,n){const t=this.node(e),r=this.node(n),s=this.defined(V("-",[t,r])),o=this.simplify(s,{steps:!1}).result;if("num"===o.type&&"0"===o.token)return{equal:!0,how:"exact"};const i=[...en(s)];if(!i.length)try{return{equal:Math.abs(kt(s,{digits:30}).number)<1e-25,how:"numeric"}}catch{return{equal:!1,how:"numeric"}}const a=[.31,1.7,2.9,-.83,.57];let u=0;for(let e=0;e<a.length;e++){const n=Object.fromEntries(i.map((n,t)=>[n,String(a[(e+t)%a.length]+t/7)]));let t;try{t=kt(s,{digits:30,scope:n}).number}catch{continue}if(u++,Math.abs(t)>1e-20)return{equal:!1,how:"numeric"}}return{equal:u>0,how:"numeric"}}modes(){return this.set.modes()}}function Gr(e={}){const n=!1===e.defaults?[]:[..._r,...e.complex?Hr:[]],{specs:t,messages:r}=function(e){jt();const n=[],t={};for(const r of e){const e="string"==typeof r?Zn(r):r,s=Array.isArray(e)?e:e?.rules??[];for(const n of(Array.isArray(e)?[]:e?.operators)??[]){if(!n?.symbol)throw new Error("an operator needs a symbol");N(n.symbol)||$({symbol:String(n.symbol),arity:"any"===n.arity?x:Number(n.arity),label:n.label})}Object.assign(t,(Array.isArray(e)?null:e?.messages)??{});for(const e of s)n.push(e)}return{specs:n,messages:t}}([...n,...e.rules??[]]),s=le(e.complex,()=>Zt(t));return new Yr(s,{...Jr,...r},e.format??Vr,e.read??null,Boolean(e.complex))}function Kr(h){const m=h=>e("op"===h.type?function(e,a){const{op:h,args:m}=e,[g,v]=m,b=(e,n)=>u(h,l(e),n)?`(${a(e)})`:a(e),y=()=>m.map(a).join(", "),w=e=>d(h,e)?`(${a(e)})`:a(e);if("*"===h&&n(e))return"-"+a(v);if("+"===h&&n(v))return`${b(g,"left")} ${a(v)}`;if("-"===h&&n(v))return`${b(g,"left")} + ${a(v).slice(1)}`;if("^"===h){const e=b(g,"left");return`${e.startsWith("-")?`(${e})`:e}^${b(v,"right")}`}if(Xr[h])return`${b(g,"left")} ${Xr[h]} ${b(v,"right")}`;if(t[h])return`${h}(${r(e).map(e=>`[${e.map(a).join(", ")}]`).join(", ")})`;if(es[h])return es[h][0]+y()+es[h][1];if(s(h))return`${o(h)}(${y()})`;switch(h){case"neg":return"-"+w(g);case"pmod":return`${a(g)} (mod ${a(v)})`;case"pm":return"±"+w(g);case"!":return w(g)+"!";case"\\not":return"¬"+w(g);case"sqrt":return`√(${a(g)})`;case"root":{const e="number"===g.type?{3:"∛",4:"∜"}[g.value]:null;return e?`${e}(${a(v)})`:`root(${a(g)}, ${a(v)})`}case"abs":return`|${a(g)}|`;case"floor":return`⌊${a(g)}⌋`;case"ceil":return`⌈${a(g)}⌉`;case"log":return`log_${"op"===g.type?`(${a(g)})`:a(g)}(${a(v)})`;case"loglog":return`ln(ln(${a(g)}))`;case"logloglog":return`ln(ln(ln(${a(g)})))`;case"perm":return`perm(${a(g)}, ${a(v)})`;case"comb":return`comb(${a(g)}, ${a(v)})`;case"_":return`${a(g)}_${a(v)}`;case"?:":return`${a(g)} ? ${a(v)} : ${a(m[2])}`;case"sum":return m.map(a).join(" + ");case"prod":return m.map(a).join(" * ");case"der":{const{n:n,body:t,by:r,variable:s}=i(e),o=n>1?`^${n}`:"";return s?`d${o}${a(t)}/d${a(r)}${o}`:`d${o}/d${a(r)}${o}(${a(t)})`}case"int":return function(e,n){const[t,r,s,o]=e,i=e.length>=2&&f(r)?n(r):p(t)||"x",a=`${n(t)} d${i}`;switch(e.length){case 1:return`∫ ${a}`;case 2:return f(r)?`∫ ${a}`:`∫[${n(r)}] ${a}`;case 3:return f(r)?`∫[${n(s)}] ${a}`:`∫[${n(r)}, ${n(s)}] ${a}`;default:return`∫[${n(s)}, ${n(o)}] ${a}`}}(m,a);case"lim":return function(e,n){const[t,r,s,o]=e;switch(e.length){case 1:return`lim ${n(t)}`;case 2:return`lim[${n(r)}] ${n(t)}`;case 3:return`lim[${n(r)}→${n(s)}] ${n(t)}`;default:{const e=c(o).toLowerCase().startsWith("r")?"⁺":"⁻";return`lim[${n(r)}→${n(s)}${e}] ${n(t)}`}}}(m,a);case"\\sumidx":return ns("∑",m,a);case"\\prodidx":return ns("∏",m,a)}return`${h}(${y()})`}(h,m):function(e){const n=e.value;return"symbol"!==e.type?n:a[n]?a[n]:"\\+"===n||"\\-"===n?n[1]:n}(h));return m(h)}const Xr={"+":"+","-":"-","*":"*","/":"/","^":"^",mod:"mod","±":"±","=":"=","===":"===","≠":"≠","≠=":"≠","<":"<",">":">","≤":"≤","≥":"≥","∈":"∈","∉":"∉","→":"→","≈":"≈","∪":"∪","∩":"∩","≡":"≡","&":"∧","|":"∨","\\xor":"⊕","\\nand":"↑","\\nor":"↓"},es={"()":["(",")"],"[]":["[","]"],"{}":["{","}"],"(]":["(","]"],"[)":["[",")"]};function ns(e,n,t){const[r,s,o]=n,i="∑"===e?"sum":"prod";return 3===n.length&&"op"===s.type&&"="===s.op?`${i}(${t(r)}, ${t(s)}, ${t(o)})`:2===n.length&&"op"===s.type&&"∈"===s.op?`${i}(${t(r)}, ${t(s)})`:1===n.length?`${e} ${t(r)}`:2===n.length?`${e}[${t(s)}] ${t(r)}`:`${e}[${t(s)}, ${t(o)}] ${t(r)}`}for(const e of[Xr,es])Object.setPrototypeOf(e,null);const ts=Symbol.for("inlinemath.expressions"),rs=new Map,ss={re:"Re",im:"Im",conj:"overline"},os=["Re","Im","re","im","conj","arg"];function is(e){const n=[],t=e=>{"op"===e.type?(e.args.forEach(t),v(e.op)?(-1===v(e.op).arity&&n.push(String(e.args.length)),n.push(e.op)):n.push(String(e.args.length),`\\:${ss[e.op]??e.op}`)):n.push(e.token)};return t(e),n}function as(e={}){const n=e.rules||e.names?null:e.complex?"complex":"default";if(n&&rs.has(n))return rs.get(n);const t=[...e.names??[],...e.complex?os:[]],r=Gr({...e,read:e=>g(e,t.length?{names:t}:{}),format:Vr});return n&&rs.set(n,r),r}const us=new Set(["simplify","expand","factor","cancel","diff","integrate","solve","approx"]),ls={integral:"integrate",differentiate:"diff",approximate:"approx",simp:"simplify"};function cs(e={}){const n=e.cas??as(),t=void 0===e.steps?{}:{steps:e.steps},r=(e,s)=>{let o;try{o=n.read(e)}catch{return b(e,s)}const i=s&&s[ts];i&&(o=o.flatMap(e=>Object.hasOwn(i,e)?i[e]:[e]));const a=o[o.length-1],u=a?.startsWith("\\:")?ls[a.slice(2)]??a.slice(2):null,l=u&&us.has(u);if(!l&&!("der"===a||"int"===a))return b(e,s);const c=n.node(o),f=l?c.args:[c],p=e=>e?e.s:void 0;let d;try{switch(l?u:"der"===a?"derivative":"antiderivative"){case"simplify":d=n.simplify(f[0],t);break;case"expand":d=n.expand(f[0],t);break;case"factor":d=n.factor(f[0],t);break;case"cancel":d=n.cancel(f[0],t);break;case"diff":d=n.diff(f[0],p(f[1]),{...t,order:f[2]?Number(f[2].s):1});break;case"integrate":d=n.integrate(f[0],p(f[1]),{...t,...f[3]?{from:f[2].s,to:f[3].s}:{}});break;case"solve":d=n.solve(f[0],p(f[1]),t);break;case"approx":d=n.approximate(f[0],{...t,digits:f[1]?Number(f[1].s):15});break;case"derivative":d=n.diff(c.args[0],c.args[1].s,t);break;default:d=n.integrate(c,void 0,t)}}catch(n){return`(${e})`}if(r.last=d,!d.result)return`"${d.text}"`;const g=(v=is(d.result),h(v)?"":Kr(m(v)));var v;return/^-?\d+(\.\d+)?$/.test(g)?g:`(${g})`};return r}const fs=e=>String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;");function ps(e,n={}){return`<ol class="mv-steps">${e.map(e=>{const t=is(P(e.from)),r=y(t,{...n,highlight:e.path&&e.path.length?{path:e.path}:void 0}),s=e.to===e.from?"":`<span class="mv-step-arrow" aria-label="becomes">⟶</span>${y(is(P(e.to)),n)}`,o=e.explanation?`<p class="mv-step-why">${fs(e.explanation)}</p>`:"";return`<li class="mv-step" data-rule="${fs(e.id)}"><span class="mv-step-name">${fs(e.name)}</span><div class="mv-step-maths">${r}${s}</div>${o}</li>`}).join("")}</ol>`}export{cs as casBlocks,as as mathCAS,ps as stepsHTML,is as tokensOf};