@cortex-js/compute-engine 0.55.5 → 0.56.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/compile.esm.js +912 -770
- package/dist/compile.min.esm.js +300 -523
- package/dist/compile.min.umd.cjs +301 -524
- package/dist/compile.umd.cjs +912 -770
- package/dist/compute-engine.esm.js +1517 -902
- package/dist/compute-engine.min.esm.js +300 -522
- package/dist/compute-engine.min.umd.cjs +300 -522
- package/dist/compute-engine.umd.cjs +1517 -902
- package/dist/core.esm.js +1516 -901
- package/dist/core.min.esm.js +299 -521
- package/dist/core.min.umd.cjs +299 -521
- package/dist/core.umd.cjs +1516 -901
- package/dist/interval.esm.js +268 -63
- package/dist/interval.min.esm.js +7 -7
- package/dist/interval.min.umd.cjs +7 -7
- package/dist/interval.umd.cjs +268 -63
- package/dist/latex-syntax.esm.js +371 -77
- package/dist/latex-syntax.min.esm.js +7 -6
- package/dist/latex-syntax.min.umd.cjs +7 -6
- package/dist/latex-syntax.umd.cjs +371 -77
- package/dist/math-json.esm.js +2 -2
- package/dist/math-json.min.esm.js +2 -2
- package/dist/math-json.min.umd.cjs +2 -2
- package/dist/math-json.umd.cjs +2 -2
- package/dist/numerics.esm.js +4 -2
- package/dist/numerics.min.esm.js +3 -3
- package/dist/numerics.min.umd.cjs +3 -3
- package/dist/numerics.umd.cjs +4 -2
- package/dist/types/big-decimal/big-decimal.d.ts +1 -1
- package/dist/types/big-decimal/index.d.ts +1 -1
- package/dist/types/big-decimal/transcendentals.d.ts +1 -1
- package/dist/types/big-decimal/utils.d.ts +1 -1
- package/dist/types/common/ansi-codes.d.ts +1 -1
- package/dist/types/common/configuration-change.d.ts +1 -1
- package/dist/types/common/fuzzy-string-match.d.ts +1 -1
- package/dist/types/common/grapheme-splitter.d.ts +1 -1
- package/dist/types/common/interruptible.d.ts +1 -1
- package/dist/types/common/one-of.d.ts +1 -1
- package/dist/types/common/signals.d.ts +1 -1
- package/dist/types/common/type/ast-nodes.d.ts +1 -1
- package/dist/types/common/type/boxed-type.d.ts +1 -1
- package/dist/types/common/type/lexer.d.ts +1 -1
- package/dist/types/common/type/parse.d.ts +1 -1
- package/dist/types/common/type/parser.d.ts +1 -1
- package/dist/types/common/type/primitive.d.ts +1 -1
- package/dist/types/common/type/reduce.d.ts +1 -1
- package/dist/types/common/type/serialize.d.ts +1 -1
- package/dist/types/common/type/subtype.d.ts +1 -1
- package/dist/types/common/type/type-builder.d.ts +1 -1
- package/dist/types/common/type/types.d.ts +2 -2
- package/dist/types/common/type/utils.d.ts +1 -1
- package/dist/types/common/utils.d.ts +1 -1
- package/dist/types/compile.d.ts +1 -1
- package/dist/types/compute-engine/assume.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/abstract-boxed-expression.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/apply.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/arithmetic-add.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/arithmetic-mul-div.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/arithmetic-power.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/ascii-math.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/box.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-dictionary.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-function.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-number.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-operator-definition.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-patterns.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-string.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-symbol.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-tensor.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/boxed-value-definition.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/cache.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/canonical-utils.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/canonical.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/compare.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/constants.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/expand.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/expression-map.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/factor.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/flatten.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/hold.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/inequality-bounds.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/init-lazy-refs.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/invisible-operator.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/match.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/negate.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/numerics.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/order.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/pattern-utils.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/polynomial-degree.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/polynomials.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/predicates.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/rules.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/serialize.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/sgn.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/simplify.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/solve-linear-system.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/solve.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/stochastic-equal.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/trigonometry.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/type-guards.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/utils.d.ts +1 -1
- package/dist/types/compute-engine/boxed-expression/validate.d.ts +1 -1
- package/dist/types/compute-engine/collection-utils.d.ts +1 -1
- package/dist/types/compute-engine/compilation/base-compiler.d.ts +1 -1
- package/dist/types/compute-engine/compilation/compile-expression.d.ts +2 -3
- package/dist/types/compute-engine/compilation/constant-folding.d.ts +1 -1
- package/dist/types/compute-engine/compilation/glsl-target.d.ts +1 -1
- package/dist/types/compute-engine/compilation/gpu-target.d.ts +15 -58
- package/dist/types/compute-engine/compilation/interval-javascript-target.d.ts +1 -1
- package/dist/types/compute-engine/compilation/javascript-target.d.ts +25 -3
- package/dist/types/compute-engine/compilation/python-target.d.ts +1 -1
- package/dist/types/compute-engine/compilation/types.d.ts +1 -67
- package/dist/types/compute-engine/compilation/wgsl-target.d.ts +1 -1
- package/dist/types/compute-engine/cost-function.d.ts +1 -1
- package/dist/types/compute-engine/engine-assumptions.d.ts +1 -1
- package/dist/types/compute-engine/engine-cache.d.ts +1 -1
- package/dist/types/compute-engine/engine-common-symbols.d.ts +1 -1
- package/dist/types/compute-engine/engine-compilation-targets.d.ts +1 -1
- package/dist/types/compute-engine/engine-configuration-lifecycle.d.ts +1 -1
- package/dist/types/compute-engine/engine-declarations.d.ts +1 -1
- package/dist/types/compute-engine/engine-expression-entrypoints.d.ts +1 -1
- package/dist/types/compute-engine/engine-extension-contracts.d.ts +1 -1
- package/dist/types/compute-engine/engine-library-bootstrap.d.ts +1 -1
- package/dist/types/compute-engine/engine-numeric-configuration.d.ts +1 -1
- package/dist/types/compute-engine/engine-runtime-state.d.ts +1 -1
- package/dist/types/compute-engine/engine-scope.d.ts +1 -1
- package/dist/types/compute-engine/engine-sequences.d.ts +1 -1
- package/dist/types/compute-engine/engine-simplification-rules.d.ts +1 -1
- package/dist/types/compute-engine/engine-startup-coordinator.d.ts +1 -1
- package/dist/types/compute-engine/engine-type-resolver.d.ts +1 -1
- package/dist/types/compute-engine/engine-validation-entrypoints.d.ts +1 -1
- package/dist/types/compute-engine/free-functions.d.ts +1 -1
- package/dist/types/compute-engine/function-utils.d.ts +1 -1
- package/dist/types/compute-engine/global-types.d.ts +1 -1
- package/dist/types/compute-engine/index.d.ts +23 -3
- package/dist/types/compute-engine/interval/arithmetic.d.ts +1 -1
- package/dist/types/compute-engine/interval/comparison.d.ts +1 -1
- package/dist/types/compute-engine/interval/elementary.d.ts +1 -1
- package/dist/types/compute-engine/interval/index.d.ts +1 -1
- package/dist/types/compute-engine/interval/trigonometric.d.ts +1 -1
- package/dist/types/compute-engine/interval/types.d.ts +1 -1
- package/dist/types/compute-engine/interval/util.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/default-dictionary.d.ts +4 -3
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-algebra.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-arithmetic.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-calculus.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-colors.d.ts +10 -0
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-complex.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-core.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-linear-algebra.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-logic.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-other.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-relational-operators.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-sets.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-statistics.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-symbols.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-trigonometry.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions-units.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/definitions.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/dictionary/indexed-types.d.ts +9 -1
- package/dist/types/compute-engine/latex-syntax/latex-syntax.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/parse-number.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/parse-symbol.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/parse.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/serialize-dms.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/serialize-number.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/serializer-style.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/serializer.d.ts +4 -2
- package/dist/types/compute-engine/latex-syntax/tokenizer.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/types.d.ts +1 -1
- package/dist/types/compute-engine/latex-syntax/utils.d.ts +1 -1
- package/dist/types/compute-engine/library/arithmetic.d.ts +1 -1
- package/dist/types/compute-engine/library/calculus.d.ts +1 -1
- package/dist/types/compute-engine/library/collections.d.ts +1 -1
- package/dist/types/compute-engine/library/colors.d.ts +1 -1
- package/dist/types/compute-engine/library/combinatorics.d.ts +1 -1
- package/dist/types/compute-engine/library/complex.d.ts +1 -1
- package/dist/types/compute-engine/library/control-structures.d.ts +1 -1
- package/dist/types/compute-engine/library/core.d.ts +1 -1
- package/dist/types/compute-engine/library/fractals.d.ts +1 -1
- package/dist/types/compute-engine/library/library.d.ts +1 -1
- package/dist/types/compute-engine/library/linear-algebra.d.ts +1 -1
- package/dist/types/compute-engine/library/logic-analysis.d.ts +1 -1
- package/dist/types/compute-engine/library/logic.d.ts +1 -1
- package/dist/types/compute-engine/library/number-theory.d.ts +1 -1
- package/dist/types/compute-engine/library/polynomials.d.ts +1 -1
- package/dist/types/compute-engine/library/quantity-arithmetic.d.ts +1 -1
- package/dist/types/compute-engine/library/random-expression.d.ts +1 -1
- package/dist/types/compute-engine/library/relational-operator.d.ts +1 -1
- package/dist/types/compute-engine/library/sets.d.ts +1 -1
- package/dist/types/compute-engine/library/statistics.d.ts +1 -1
- package/dist/types/compute-engine/library/trigonometry.d.ts +1 -1
- package/dist/types/compute-engine/library/type-handlers.d.ts +1 -1
- package/dist/types/compute-engine/library/unit-data.d.ts +1 -1
- package/dist/types/compute-engine/library/units.d.ts +1 -1
- package/dist/types/compute-engine/library/utils.d.ts +1 -1
- package/dist/types/compute-engine/numeric-value/big-numeric-value.d.ts +1 -1
- package/dist/types/compute-engine/numeric-value/exact-numeric-value.d.ts +1 -1
- package/dist/types/compute-engine/numeric-value/machine-numeric-value.d.ts +1 -1
- package/dist/types/compute-engine/numeric-value/types.d.ts +1 -1
- package/dist/types/compute-engine/numerics/bigint.d.ts +1 -1
- package/dist/types/compute-engine/numerics/expression.d.ts +1 -1
- package/dist/types/compute-engine/numerics/interval.d.ts +1 -1
- package/dist/types/compute-engine/numerics/linear-algebra.d.ts +1 -1
- package/dist/types/compute-engine/numerics/monte-carlo.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric-bigint.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric-bignum.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric-complex.d.ts +1 -1
- package/dist/types/compute-engine/numerics/numeric.d.ts +1 -1
- package/dist/types/compute-engine/numerics/primes.d.ts +1 -1
- package/dist/types/compute-engine/numerics/rationals.d.ts +1 -1
- package/dist/types/compute-engine/numerics/richardson.d.ts +1 -1
- package/dist/types/compute-engine/numerics/special-functions.d.ts +1 -1
- package/dist/types/compute-engine/numerics/statistics.d.ts +1 -1
- package/dist/types/compute-engine/numerics/strings.d.ts +1 -1
- package/dist/types/compute-engine/numerics/types.d.ts +1 -1
- package/dist/types/compute-engine/numerics/unit-data.d.ts +1 -1
- package/dist/types/compute-engine/oeis.d.ts +1 -1
- package/dist/types/compute-engine/sequence.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/antiderivative.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/derivative.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/distribute.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/fu-cost.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/fu-transforms.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/fu.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/logic-utils.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-abs.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-divide.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-factorial.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-hyperbolic.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-infinity.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-log.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-logic.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-power.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-product.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-rules.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-sum.d.ts +1 -1
- package/dist/types/compute-engine/symbolic/simplify-trig.d.ts +1 -1
- package/dist/types/compute-engine/tensor/tensor-fields.d.ts +1 -1
- package/dist/types/compute-engine/tensor/tensors.d.ts +1 -1
- package/dist/types/compute-engine/types-definitions.d.ts +1 -1
- package/dist/types/compute-engine/types-engine.d.ts +6 -2
- package/dist/types/compute-engine/types-evaluation.d.ts +1 -1
- package/dist/types/compute-engine/types-expression.d.ts +1 -1
- package/dist/types/compute-engine/types-kernel-evaluation.d.ts +1 -1
- package/dist/types/compute-engine/types-kernel-serialization.d.ts +1 -1
- package/dist/types/compute-engine/types-serialization.d.ts +1 -1
- package/dist/types/compute-engine/types.d.ts +1 -1
- package/dist/types/compute-engine.d.ts +2 -3
- package/dist/types/core.d.ts +1 -1
- package/dist/types/interval.d.ts +1 -1
- package/dist/types/latex-syntax.d.ts +2 -2
- package/dist/types/math-json/symbols.d.ts +1 -1
- package/dist/types/math-json/types.d.ts +1 -1
- package/dist/types/math-json/utils.d.ts +1 -1
- package/dist/types/math-json.d.ts +2 -2
- package/dist/types/numerics.d.ts +1 -1
- package/package.json +2 -2
- package/dist/types/compute-engine/compilation/fractal-orbit.d.ts +0 -19
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/** Compute Engine 0.
|
|
1
|
+
/** Compute Engine 0.56.0 */
|
|
2
2
|
(function(global,factory){typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'],factory):(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ComputeEngine = {}));})(this, (function (exports) { 'use strict';
|
|
3
3
|
var ComputeEngine = (() => {
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -2316,6 +2316,7 @@ var ComputeEngine = (() => {
|
|
|
2316
2316
|
];
|
|
2317
2317
|
var VALUE_TYPES = [
|
|
2318
2318
|
"value",
|
|
2319
|
+
"color",
|
|
2319
2320
|
...COLLECTION_TYPES,
|
|
2320
2321
|
...SCALAR_TYPES
|
|
2321
2322
|
];
|
|
@@ -4015,6 +4016,7 @@ var ComputeEngine = (() => {
|
|
|
4015
4016
|
symbol: [],
|
|
4016
4017
|
boolean: [],
|
|
4017
4018
|
string: [],
|
|
4019
|
+
color: [],
|
|
4018
4020
|
expression: EXPRESSION_TYPES
|
|
4019
4021
|
};
|
|
4020
4022
|
function isPrimitiveSubtype(lhs, rhs) {
|
|
@@ -7898,9 +7900,10 @@ var ComputeEngine = (() => {
|
|
|
7898
7900
|
if (!materialized.isLazyCollection) return materialized.latex;
|
|
7899
7901
|
}
|
|
7900
7902
|
const syntax = this.engine._requireLatexSyntax();
|
|
7901
|
-
|
|
7902
|
-
|
|
7903
|
-
);
|
|
7903
|
+
const json = this.toMathJson({ prettify: true, fractionalDigits: "auto" });
|
|
7904
|
+
const latexOpts = this.engine.latexOptions;
|
|
7905
|
+
if (Object.keys(latexOpts).length === 0) return syntax.serialize(json);
|
|
7906
|
+
return syntax.serialize(json, { ...latexOpts });
|
|
7904
7907
|
}
|
|
7905
7908
|
/**
|
|
7906
7909
|
* Return a LaTeX representation of this expression with custom
|
|
@@ -7924,9 +7927,13 @@ var ComputeEngine = (() => {
|
|
|
7924
7927
|
fractionalDigits: "auto"
|
|
7925
7928
|
});
|
|
7926
7929
|
const syntax = this.engine._requireLatexSyntax();
|
|
7927
|
-
|
|
7928
|
-
|
|
7929
|
-
|
|
7930
|
+
const latexOpts = this.engine.latexOptions;
|
|
7931
|
+
const haveEngineOpts = Object.keys(latexOpts).length > 0;
|
|
7932
|
+
const haveCallOpts = options && Object.keys(options).length > 0;
|
|
7933
|
+
if (!haveEngineOpts && !haveCallOpts) return syntax.serialize(json);
|
|
7934
|
+
if (!haveEngineOpts) return syntax.serialize(json, options);
|
|
7935
|
+
if (!haveCallOpts) return syntax.serialize(json, { ...latexOpts });
|
|
7936
|
+
return syntax.serialize(json, { ...latexOpts, ...options });
|
|
7930
7937
|
}
|
|
7931
7938
|
/** Called by `JSON.stringify()` when serializing to json.
|
|
7932
7939
|
*
|
|
@@ -7970,11 +7977,13 @@ var ComputeEngine = (() => {
|
|
|
7970
7977
|
"number",
|
|
7971
7978
|
"dictionary"
|
|
7972
7979
|
];
|
|
7973
|
-
}
|
|
7974
|
-
if (Array.isArray(options.shorthands))
|
|
7980
|
+
} else if (Array.isArray(options.shorthands)) {
|
|
7975
7981
|
defaultOptions.shorthands = options.shorthands;
|
|
7982
|
+
}
|
|
7976
7983
|
if (typeof options.metadata === "string" && options.metadata === "all" || options.metadata?.includes("all")) {
|
|
7977
7984
|
defaultOptions.metadata = ["latex", "wikidata"];
|
|
7985
|
+
} else if (Array.isArray(options.metadata)) {
|
|
7986
|
+
defaultOptions.metadata = options.metadata;
|
|
7978
7987
|
}
|
|
7979
7988
|
if (options.fractionalDigits === "auto")
|
|
7980
7989
|
defaultOptions.fractionalDigits = -this.engine.precision;
|
|
@@ -11113,10 +11122,6 @@ var ComputeEngine = (() => {
|
|
|
11113
11122
|
// Lagrange notation
|
|
11114
11123
|
{
|
|
11115
11124
|
name: "Derivative",
|
|
11116
|
-
// @todo: Leibniz notation: {% latex " \\frac{d^n}{dx^n} f(x)" %}
|
|
11117
|
-
// @todo: Euler modified notation: This notation is used by Mathematica. The Euler notation uses `D` instead of
|
|
11118
|
-
// `\partial`: `\partial_{x} f`, `\partial_{x,y} f`
|
|
11119
|
-
// Newton notation (\dot{v}, \ddot{v}) is implemented below
|
|
11120
11125
|
serialize: (serializer, expr2) => {
|
|
11121
11126
|
const degree = machineValue(operand(expr2, 2)) ?? 1;
|
|
11122
11127
|
const base = serializer.serialize(operand(expr2, 1));
|
|
@@ -12154,14 +12159,18 @@ var ComputeEngine = (() => {
|
|
|
12154
12159
|
return ["Complement", lhs];
|
|
12155
12160
|
}
|
|
12156
12161
|
// precedence: 240,
|
|
12157
|
-
// @todo: serialize for the multiple argument case
|
|
12158
12162
|
},
|
|
12159
12163
|
{
|
|
12160
12164
|
name: "Complement",
|
|
12161
12165
|
latexTrigger: ["^", "<{>", "\\complement", "<}>"],
|
|
12162
|
-
kind: "postfix"
|
|
12166
|
+
kind: "postfix",
|
|
12163
12167
|
// precedence: 240,
|
|
12164
|
-
|
|
12168
|
+
serialize: (serializer, expr2) => {
|
|
12169
|
+
return joinLatex([
|
|
12170
|
+
serializer.serialize(operand(expr2, 1)),
|
|
12171
|
+
"^\\complement"
|
|
12172
|
+
]);
|
|
12173
|
+
}
|
|
12165
12174
|
},
|
|
12166
12175
|
{
|
|
12167
12176
|
name: "Intersection",
|
|
@@ -12248,7 +12257,6 @@ var ComputeEngine = (() => {
|
|
|
12248
12257
|
// commands like \rbrack a, b \rbrack which are unambiguous.
|
|
12249
12258
|
{
|
|
12250
12259
|
name: "Multiple",
|
|
12251
|
-
// @todo: parse
|
|
12252
12260
|
serialize: serializeSet
|
|
12253
12261
|
},
|
|
12254
12262
|
{
|
|
@@ -12257,14 +12265,28 @@ var ComputeEngine = (() => {
|
|
|
12257
12265
|
kind: "infix",
|
|
12258
12266
|
precedence: 350
|
|
12259
12267
|
},
|
|
12268
|
+
// \mid as a separator/operator (used in set-builder notation: {x \mid x > 0})
|
|
12269
|
+
// Low precedence so it binds loosely — everything on each side is parsed first
|
|
12270
|
+
{
|
|
12271
|
+
name: "Divides",
|
|
12272
|
+
latexTrigger: ["\\mid"],
|
|
12273
|
+
kind: "infix",
|
|
12274
|
+
precedence: 160
|
|
12275
|
+
},
|
|
12260
12276
|
{
|
|
12261
12277
|
name: "Set",
|
|
12262
12278
|
kind: "matchfix",
|
|
12263
12279
|
openTrigger: "{",
|
|
12264
12280
|
closeTrigger: "}",
|
|
12265
|
-
// @todo: the set syntax can also include conditions...
|
|
12266
12281
|
parse: (_parser, body) => {
|
|
12267
12282
|
if (isEmptySequence(body)) return "EmptySet";
|
|
12283
|
+
const h = operator(body);
|
|
12284
|
+
if (h === "Divides" || h === "Colon") {
|
|
12285
|
+
const expr2 = operand(body, 1);
|
|
12286
|
+
const condition = operand(body, 2);
|
|
12287
|
+
if (expr2 !== null && condition !== null)
|
|
12288
|
+
return ["Set", expr2, ["Condition", condition]];
|
|
12289
|
+
}
|
|
12268
12290
|
if (operator(body) == "Delimiter" && stringValue(operand(body, 2)) === ",") {
|
|
12269
12291
|
body = operand(body, 1);
|
|
12270
12292
|
}
|
|
@@ -12272,6 +12294,17 @@ var ComputeEngine = (() => {
|
|
|
12272
12294
|
return ["Set", ...operands(body)];
|
|
12273
12295
|
},
|
|
12274
12296
|
serialize: (serializer, expr2) => {
|
|
12297
|
+
if (nops(expr2) === 2 && operator(operand(expr2, 2)) === "Condition") {
|
|
12298
|
+
const condition = operand(expr2, 2);
|
|
12299
|
+
return joinLatex([
|
|
12300
|
+
"\\lbrace",
|
|
12301
|
+
serializer.serialize(operand(expr2, 1)),
|
|
12302
|
+
"\\mid",
|
|
12303
|
+
// Serialize the inner expression of the Condition wrapper
|
|
12304
|
+
serializer.serialize(operand(condition, 1)),
|
|
12305
|
+
"\\rbrace"
|
|
12306
|
+
]);
|
|
12307
|
+
}
|
|
12275
12308
|
return joinLatex([
|
|
12276
12309
|
"\\lbrace",
|
|
12277
12310
|
operands(expr2).map((x) => serializer.serialize(x)).join(", "),
|
|
@@ -12438,23 +12471,6 @@ var ComputeEngine = (() => {
|
|
|
12438
12471
|
if (expr2 === null) return "";
|
|
12439
12472
|
const h = operator(expr2);
|
|
12440
12473
|
if (!h) return "";
|
|
12441
|
-
if (h === "Set") {
|
|
12442
|
-
if (nops(expr2) === 0) return "\\emptyset";
|
|
12443
|
-
if (nops(expr2) === 2 && operator(operand(expr2, 2)) === "Condition") {
|
|
12444
|
-
return joinLatex([
|
|
12445
|
-
"\\left\\lbrace",
|
|
12446
|
-
serializer.serialize(operand(expr2, 1)),
|
|
12447
|
-
"\\middle\\mid",
|
|
12448
|
-
serializer.serialize(operand(expr2, 2)),
|
|
12449
|
-
"\\right\\rbrace"
|
|
12450
|
-
]);
|
|
12451
|
-
}
|
|
12452
|
-
return joinLatex([
|
|
12453
|
-
"\\left\\lbrace",
|
|
12454
|
-
...operands(expr2).map((x) => serializer.serialize(x) + " ,"),
|
|
12455
|
-
"\\right\\rbrace"
|
|
12456
|
-
]);
|
|
12457
|
-
}
|
|
12458
12474
|
if (h === "Multiple") {
|
|
12459
12475
|
}
|
|
12460
12476
|
if (h === "Range") {
|
|
@@ -13602,11 +13618,13 @@ var ComputeEngine = (() => {
|
|
|
13602
13618
|
if (!parser.match("_")) return null;
|
|
13603
13619
|
const base = parser.parseGroup();
|
|
13604
13620
|
if (operator(base) !== "To") return null;
|
|
13605
|
-
const expr2 = parser.
|
|
13621
|
+
const expr2 = parser.parseExpression({
|
|
13622
|
+
minPrec: MULTIPLICATION_PRECEDENCE
|
|
13623
|
+
});
|
|
13606
13624
|
if (!expr2) return null;
|
|
13607
13625
|
return [
|
|
13608
13626
|
"Limit",
|
|
13609
|
-
["Function", expr2
|
|
13627
|
+
["Function", expr2, operand(base, 1)],
|
|
13610
13628
|
operand(base, 2)
|
|
13611
13629
|
];
|
|
13612
13630
|
},
|
|
@@ -13687,6 +13705,8 @@ var ComputeEngine = (() => {
|
|
|
13687
13705
|
precedence: DIVISION_PRECEDENCE,
|
|
13688
13706
|
parse: "Mod"
|
|
13689
13707
|
},
|
|
13708
|
+
// Function-style alias: `\operatorname{mod}(a, b)`
|
|
13709
|
+
{ latexTrigger: "\\operatorname{mod}", parse: "Mod" },
|
|
13690
13710
|
{
|
|
13691
13711
|
latexTrigger: "\\pmod",
|
|
13692
13712
|
kind: "prefix",
|
|
@@ -13927,6 +13947,13 @@ var ComputeEngine = (() => {
|
|
|
13927
13947
|
const rhs = serializer.wrap(operand(expr2, 2), ADDITION_PRECEDENCE + 3);
|
|
13928
13948
|
return joinLatex([lhs, "-", rhs]);
|
|
13929
13949
|
}
|
|
13950
|
+
},
|
|
13951
|
+
// Euclidean distance between two points (tuples of numbers).
|
|
13952
|
+
{
|
|
13953
|
+
name: "Distance",
|
|
13954
|
+
latexTrigger: ["\\operatorname{distance}"],
|
|
13955
|
+
kind: "function",
|
|
13956
|
+
serialize: (serializer, expr2) => "\\operatorname{distance}" + serializer.wrapArguments(expr2)
|
|
13930
13957
|
}
|
|
13931
13958
|
];
|
|
13932
13959
|
function getIndexAssignment(expr2, upper) {
|
|
@@ -15351,7 +15378,9 @@ var ComputeEngine = (() => {
|
|
|
15351
15378
|
if (!expr2 || !symbol(expr2)) return null;
|
|
15352
15379
|
return ["Mean", expr2];
|
|
15353
15380
|
}
|
|
15354
|
-
}
|
|
15381
|
+
},
|
|
15382
|
+
// Function-style alias: `\operatorname{var}(...)`
|
|
15383
|
+
{ latexTrigger: "\\operatorname{var}", parse: "Variance" }
|
|
15355
15384
|
];
|
|
15356
15385
|
|
|
15357
15386
|
// src/compute-engine/numerics/unit-data.ts
|
|
@@ -15903,12 +15932,52 @@ var ComputeEngine = (() => {
|
|
|
15903
15932
|
];
|
|
15904
15933
|
|
|
15905
15934
|
// src/compute-engine/latex-syntax/dictionary/definitions-other.ts
|
|
15935
|
+
var TEX_UNITS = [
|
|
15936
|
+
"pt",
|
|
15937
|
+
"em",
|
|
15938
|
+
"mu",
|
|
15939
|
+
"ex",
|
|
15940
|
+
"mm",
|
|
15941
|
+
"cm",
|
|
15942
|
+
"in",
|
|
15943
|
+
"bp",
|
|
15944
|
+
"sp",
|
|
15945
|
+
"dd",
|
|
15946
|
+
"cc",
|
|
15947
|
+
"pc",
|
|
15948
|
+
"nc",
|
|
15949
|
+
"nd"
|
|
15950
|
+
];
|
|
15951
|
+
function skipTexDimension(parser) {
|
|
15952
|
+
parser.skipSpace();
|
|
15953
|
+
if (parser.peek === "-" || parser.peek === "+") parser.nextToken();
|
|
15954
|
+
while (/^[\d.]$/.test(parser.peek)) parser.nextToken();
|
|
15955
|
+
for (const unit of TEX_UNITS) {
|
|
15956
|
+
if (parser.matchAll([...unit])) return;
|
|
15957
|
+
}
|
|
15958
|
+
}
|
|
15906
15959
|
function parseSingleArg(cmd) {
|
|
15907
15960
|
return (parser) => {
|
|
15908
15961
|
const arg = parser.parseGroup();
|
|
15909
15962
|
return arg === null ? [cmd] : [cmd, arg];
|
|
15910
15963
|
};
|
|
15911
15964
|
}
|
|
15965
|
+
function parseMathStyleSwitch(mathStyle) {
|
|
15966
|
+
return (parser) => {
|
|
15967
|
+
const body = parser.parseExpression();
|
|
15968
|
+
if (body !== null && !isEmptySequence(body))
|
|
15969
|
+
return ["Annotated", body, { dict: { mathStyle } }];
|
|
15970
|
+
return "Nothing";
|
|
15971
|
+
};
|
|
15972
|
+
}
|
|
15973
|
+
function parseSizeSwitch(size) {
|
|
15974
|
+
return (parser) => {
|
|
15975
|
+
const body = parser.parseExpression();
|
|
15976
|
+
if (body !== null && !isEmptySequence(body))
|
|
15977
|
+
return ["Annotated", body, { dict: { size } }];
|
|
15978
|
+
return "Nothing";
|
|
15979
|
+
};
|
|
15980
|
+
}
|
|
15912
15981
|
var DEFINITIONS_OTHERS = [
|
|
15913
15982
|
{
|
|
15914
15983
|
name: "Overscript",
|
|
@@ -16148,80 +16217,71 @@ var ComputeEngine = (() => {
|
|
|
16148
16217
|
},
|
|
16149
16218
|
{
|
|
16150
16219
|
latexTrigger: ["\\displaystyle"],
|
|
16151
|
-
parse: (
|
|
16152
|
-
// @todo: parse as ['Annotated'...]
|
|
16220
|
+
parse: parseMathStyleSwitch("normal")
|
|
16153
16221
|
},
|
|
16154
16222
|
{
|
|
16155
16223
|
latexTrigger: ["\\textstyle"],
|
|
16156
|
-
parse: (
|
|
16157
|
-
// @todo: parse as ['Annotated'...]
|
|
16224
|
+
parse: parseMathStyleSwitch("compact")
|
|
16158
16225
|
},
|
|
16159
16226
|
{
|
|
16160
16227
|
latexTrigger: ["\\scriptstyle"],
|
|
16161
|
-
parse: (
|
|
16162
|
-
// @todo: parse as ['Annotated'...]
|
|
16228
|
+
parse: parseMathStyleSwitch("script")
|
|
16163
16229
|
},
|
|
16164
16230
|
{
|
|
16165
16231
|
latexTrigger: ["\\scriptscriptstyle"],
|
|
16166
|
-
parse: (
|
|
16167
|
-
// @todo: parse as ['Annotated'...]
|
|
16232
|
+
parse: parseMathStyleSwitch("scriptscript")
|
|
16168
16233
|
},
|
|
16169
16234
|
{
|
|
16170
16235
|
latexTrigger: ["\\color"],
|
|
16171
16236
|
parse: (parser) => {
|
|
16172
|
-
parser.
|
|
16237
|
+
const color = parser.parseStringGroup();
|
|
16238
|
+
if (color !== null) {
|
|
16239
|
+
const body = parser.parseExpression();
|
|
16240
|
+
if (body !== null && !isEmptySequence(body))
|
|
16241
|
+
return ["Annotated", body, { dict: { color } }];
|
|
16242
|
+
}
|
|
16173
16243
|
return "Nothing";
|
|
16174
16244
|
}
|
|
16175
16245
|
},
|
|
16176
16246
|
{
|
|
16177
16247
|
latexTrigger: ["\\tiny"],
|
|
16178
|
-
parse: ()
|
|
16179
|
-
// @todo: parse as ['Annotated'...]
|
|
16248
|
+
parse: parseSizeSwitch(1)
|
|
16180
16249
|
},
|
|
16181
16250
|
{
|
|
16182
16251
|
latexTrigger: ["\\scriptsize"],
|
|
16183
|
-
parse: ()
|
|
16184
|
-
// @todo: parse as ['Annotated'...]
|
|
16252
|
+
parse: parseSizeSwitch(2)
|
|
16185
16253
|
},
|
|
16186
16254
|
{
|
|
16187
16255
|
latexTrigger: ["\\footnotesize"],
|
|
16188
|
-
parse: ()
|
|
16189
|
-
// @todo: parse as ['Annotated'...]
|
|
16256
|
+
parse: parseSizeSwitch(3)
|
|
16190
16257
|
},
|
|
16191
16258
|
{
|
|
16192
16259
|
latexTrigger: ["\\small"],
|
|
16193
|
-
parse: ()
|
|
16194
|
-
// @todo: parse as ['Annotated'...]
|
|
16260
|
+
parse: parseSizeSwitch(4)
|
|
16195
16261
|
},
|
|
16196
16262
|
{
|
|
16197
16263
|
latexTrigger: ["\\normalsize"],
|
|
16198
|
-
parse: ()
|
|
16199
|
-
// @todo: parse as ['Annotated'...]
|
|
16264
|
+
parse: parseSizeSwitch(5)
|
|
16200
16265
|
},
|
|
16201
16266
|
{
|
|
16202
16267
|
latexTrigger: ["\\large"],
|
|
16203
|
-
parse: ()
|
|
16204
|
-
// @todo: parse as ['Annotated'...]
|
|
16268
|
+
parse: parseSizeSwitch(6)
|
|
16205
16269
|
},
|
|
16206
16270
|
{
|
|
16207
16271
|
latexTrigger: ["\\Large"],
|
|
16208
|
-
parse: ()
|
|
16209
|
-
// @todo: parse as ['Annotated'...]
|
|
16272
|
+
parse: parseSizeSwitch(7)
|
|
16210
16273
|
},
|
|
16211
16274
|
{
|
|
16212
16275
|
latexTrigger: ["\\LARGE"],
|
|
16213
|
-
parse: ()
|
|
16214
|
-
// @todo: parse as ['Annotated'...]
|
|
16276
|
+
parse: parseSizeSwitch(8)
|
|
16215
16277
|
},
|
|
16216
16278
|
{
|
|
16217
16279
|
latexTrigger: ["\\huge"],
|
|
16218
|
-
parse: ()
|
|
16219
|
-
// @todo: parse as ['Annotated'...]
|
|
16280
|
+
parse: parseSizeSwitch(9)
|
|
16220
16281
|
},
|
|
16221
16282
|
{
|
|
16222
16283
|
latexTrigger: ["\\Huge"],
|
|
16223
|
-
parse: ()
|
|
16224
|
-
// @todo: parse as ['Annotated'...]
|
|
16284
|
+
parse: parseSizeSwitch(10)
|
|
16225
16285
|
},
|
|
16226
16286
|
{
|
|
16227
16287
|
name: "Annotated",
|
|
@@ -16233,6 +16293,10 @@ var ComputeEngine = (() => {
|
|
|
16233
16293
|
result = joinLatex(["{\\displaystyle", result, "}"]);
|
|
16234
16294
|
else if (dict.dict.mathStyle === "compact")
|
|
16235
16295
|
result = joinLatex(["{\\textstyle", result, "}"]);
|
|
16296
|
+
else if (dict.dict.mathStyle === "script")
|
|
16297
|
+
result = joinLatex(["{\\scriptstyle", result, "}"]);
|
|
16298
|
+
else if (dict.dict.mathStyle === "scriptscript")
|
|
16299
|
+
result = joinLatex(["{\\scriptscriptstyle", result, "}"]);
|
|
16236
16300
|
const v = dict.dict.size;
|
|
16237
16301
|
if (v !== null && v >= 1 && v <= 10) {
|
|
16238
16302
|
result = joinLatex([
|
|
@@ -16320,6 +16384,28 @@ var ComputeEngine = (() => {
|
|
|
16320
16384
|
latexTrigger: ["\\enspace"],
|
|
16321
16385
|
parse: () => ["HorizontalSpacing", 9]
|
|
16322
16386
|
},
|
|
16387
|
+
{
|
|
16388
|
+
latexTrigger: ["\\hspace"],
|
|
16389
|
+
parse: (parser) => {
|
|
16390
|
+
if (parser.peek === "*") parser.nextToken();
|
|
16391
|
+
parser.parseStringGroup();
|
|
16392
|
+
return ["HorizontalSpacing", 0];
|
|
16393
|
+
}
|
|
16394
|
+
},
|
|
16395
|
+
{
|
|
16396
|
+
latexTrigger: ["\\hskip"],
|
|
16397
|
+
parse: (parser) => {
|
|
16398
|
+
skipTexDimension(parser);
|
|
16399
|
+
return ["HorizontalSpacing", 0];
|
|
16400
|
+
}
|
|
16401
|
+
},
|
|
16402
|
+
{
|
|
16403
|
+
latexTrigger: ["\\kern"],
|
|
16404
|
+
parse: (parser) => {
|
|
16405
|
+
skipTexDimension(parser);
|
|
16406
|
+
return ["HorizontalSpacing", 0];
|
|
16407
|
+
}
|
|
16408
|
+
},
|
|
16323
16409
|
{
|
|
16324
16410
|
latexTrigger: ["\\phantom"],
|
|
16325
16411
|
parse: (parser) => {
|
|
@@ -16370,7 +16456,17 @@ var ComputeEngine = (() => {
|
|
|
16370
16456
|
// `["HorizontalSpacing", expr, 'op'|'bin'|rel]` -> indicate a spacing around and expression, i.e. `\mathbin{x}`, etc...
|
|
16371
16457
|
serialize: (serializer, expr2) => {
|
|
16372
16458
|
if (operand(expr2, 2) !== null) {
|
|
16373
|
-
|
|
16459
|
+
const cls = stringValue(operand(expr2, 2));
|
|
16460
|
+
const inner = serializer.serialize(operand(expr2, 1));
|
|
16461
|
+
if (cls === "bin") return `\\mathbin{${inner}}`;
|
|
16462
|
+
if (cls === "op") return `\\mathop{${inner}}`;
|
|
16463
|
+
if (cls === "rel") return `\\mathrel{${inner}}`;
|
|
16464
|
+
if (cls === "ord") return `\\mathord{${inner}}`;
|
|
16465
|
+
if (cls === "open") return `\\mathopen{${inner}}`;
|
|
16466
|
+
if (cls === "close") return `\\mathclose{${inner}}`;
|
|
16467
|
+
if (cls === "punct") return `\\mathpunct{${inner}}`;
|
|
16468
|
+
if (cls === "inner") return `\\mathinner{${inner}}`;
|
|
16469
|
+
return inner;
|
|
16374
16470
|
}
|
|
16375
16471
|
const v = machineValue(operand(expr2, 1));
|
|
16376
16472
|
if (v === null) return "";
|
|
@@ -16385,7 +16481,7 @@ var ComputeEngine = (() => {
|
|
|
16385
16481
|
36: "\\qquad"
|
|
16386
16482
|
}[v] ?? "";
|
|
16387
16483
|
}
|
|
16388
|
-
}
|
|
16484
|
+
},
|
|
16389
16485
|
// if (
|
|
16390
16486
|
// [
|
|
16391
16487
|
// '\\!',
|
|
@@ -16409,6 +16505,121 @@ var ComputeEngine = (() => {
|
|
|
16409
16505
|
// name: '',
|
|
16410
16506
|
// trigger: '\\check',
|
|
16411
16507
|
// },
|
|
16508
|
+
// ---------------------------------------------------------------------------
|
|
16509
|
+
// Function-style aliases for collection / random operators that some
|
|
16510
|
+
// notations write in lowercase (e.g. `\operatorname{shuffle}(L)`).
|
|
16511
|
+
// The capitalized library entries already exist; these are pure parse
|
|
16512
|
+
// aliases so the lowercase names don't land in `unsupported-operator`.
|
|
16513
|
+
// ---------------------------------------------------------------------------
|
|
16514
|
+
{ latexTrigger: "\\operatorname{random}", parse: "Random" },
|
|
16515
|
+
{ latexTrigger: "\\operatorname{shuffle}", parse: "Shuffle" },
|
|
16516
|
+
{ latexTrigger: "\\operatorname{repeat}", parse: "Repeat" },
|
|
16517
|
+
{ latexTrigger: "\\operatorname{join}", parse: "Join" },
|
|
16518
|
+
// ---------------------------------------------------------------------------
|
|
16519
|
+
// Geometric primitive heads. Registered as known typed heads so consumers
|
|
16520
|
+
// can branch on the operator name; CE itself doesn't render them. The
|
|
16521
|
+
// library entries (with no evaluator) live in `library/core.ts`.
|
|
16522
|
+
// ---------------------------------------------------------------------------
|
|
16523
|
+
{
|
|
16524
|
+
name: "Triangle",
|
|
16525
|
+
latexTrigger: ["\\operatorname{triangle}"],
|
|
16526
|
+
kind: "function",
|
|
16527
|
+
serialize: (serializer, expr2) => "\\operatorname{triangle}" + serializer.wrapArguments(expr2)
|
|
16528
|
+
},
|
|
16529
|
+
// Desmos's geometric `vector(p1, p2)` — a directed segment between two
|
|
16530
|
+
// points. Routed to a dedicated head (not the existing column-vector
|
|
16531
|
+
// `Vector`, which has a narrower `(number+) -> vector` signature).
|
|
16532
|
+
{
|
|
16533
|
+
name: "GeometricVector",
|
|
16534
|
+
latexTrigger: ["\\operatorname{vector}"],
|
|
16535
|
+
kind: "function",
|
|
16536
|
+
serialize: (serializer, expr2) => "\\operatorname{vector}" + serializer.wrapArguments(expr2)
|
|
16537
|
+
},
|
|
16538
|
+
{
|
|
16539
|
+
name: "Sphere",
|
|
16540
|
+
latexTrigger: ["\\operatorname{sphere}"],
|
|
16541
|
+
kind: "function",
|
|
16542
|
+
serialize: (serializer, expr2) => "\\operatorname{sphere}" + serializer.wrapArguments(expr2)
|
|
16543
|
+
},
|
|
16544
|
+
{
|
|
16545
|
+
name: "Segment",
|
|
16546
|
+
latexTrigger: ["\\operatorname{segment}"],
|
|
16547
|
+
kind: "function",
|
|
16548
|
+
serialize: (serializer, expr2) => "\\operatorname{segment}" + serializer.wrapArguments(expr2)
|
|
16549
|
+
}
|
|
16550
|
+
];
|
|
16551
|
+
|
|
16552
|
+
// src/compute-engine/latex-syntax/dictionary/definitions-colors.ts
|
|
16553
|
+
var DEFINITIONS_COLORS = [
|
|
16554
|
+
// Color constructors (one per colorspace, preserves space on evaluation)
|
|
16555
|
+
{
|
|
16556
|
+
name: "Rgb",
|
|
16557
|
+
latexTrigger: ["\\operatorname{rgb}"],
|
|
16558
|
+
kind: "function",
|
|
16559
|
+
serialize: (serializer, expr2) => "\\operatorname{rgb}" + serializer.wrapArguments(expr2)
|
|
16560
|
+
},
|
|
16561
|
+
{
|
|
16562
|
+
name: "Hsv",
|
|
16563
|
+
latexTrigger: ["\\operatorname{hsv}"],
|
|
16564
|
+
kind: "function",
|
|
16565
|
+
serialize: (serializer, expr2) => "\\operatorname{hsv}" + serializer.wrapArguments(expr2)
|
|
16566
|
+
},
|
|
16567
|
+
{
|
|
16568
|
+
name: "Hsl",
|
|
16569
|
+
latexTrigger: ["\\operatorname{hsl}"],
|
|
16570
|
+
kind: "function",
|
|
16571
|
+
serialize: (serializer, expr2) => "\\operatorname{hsl}" + serializer.wrapArguments(expr2)
|
|
16572
|
+
},
|
|
16573
|
+
{
|
|
16574
|
+
name: "Oklab",
|
|
16575
|
+
latexTrigger: ["\\operatorname{oklab}"],
|
|
16576
|
+
kind: "function",
|
|
16577
|
+
serialize: (serializer, expr2) => "\\operatorname{oklab}" + serializer.wrapArguments(expr2)
|
|
16578
|
+
},
|
|
16579
|
+
{
|
|
16580
|
+
name: "Oklch",
|
|
16581
|
+
latexTrigger: ["\\operatorname{oklch}"],
|
|
16582
|
+
kind: "function",
|
|
16583
|
+
serialize: (serializer, expr2) => "\\operatorname{oklch}" + serializer.wrapArguments(expr2)
|
|
16584
|
+
},
|
|
16585
|
+
// Conversion functions (color → color in the named space)
|
|
16586
|
+
{
|
|
16587
|
+
name: "AsRgb",
|
|
16588
|
+
latexTrigger: ["\\operatorname{asRgb}"],
|
|
16589
|
+
kind: "function",
|
|
16590
|
+
serialize: (serializer, expr2) => "\\operatorname{asRgb}" + serializer.wrapArguments(expr2)
|
|
16591
|
+
},
|
|
16592
|
+
{
|
|
16593
|
+
name: "AsHsv",
|
|
16594
|
+
latexTrigger: ["\\operatorname{asHsv}"],
|
|
16595
|
+
kind: "function",
|
|
16596
|
+
serialize: (serializer, expr2) => "\\operatorname{asHsv}" + serializer.wrapArguments(expr2)
|
|
16597
|
+
},
|
|
16598
|
+
{
|
|
16599
|
+
name: "AsHsl",
|
|
16600
|
+
latexTrigger: ["\\operatorname{asHsl}"],
|
|
16601
|
+
kind: "function",
|
|
16602
|
+
serialize: (serializer, expr2) => "\\operatorname{asHsl}" + serializer.wrapArguments(expr2)
|
|
16603
|
+
},
|
|
16604
|
+
{
|
|
16605
|
+
name: "AsOklab",
|
|
16606
|
+
latexTrigger: ["\\operatorname{asOklab}"],
|
|
16607
|
+
kind: "function",
|
|
16608
|
+
serialize: (serializer, expr2) => "\\operatorname{asOklab}" + serializer.wrapArguments(expr2)
|
|
16609
|
+
},
|
|
16610
|
+
{
|
|
16611
|
+
name: "AsOklch",
|
|
16612
|
+
latexTrigger: ["\\operatorname{asOklch}"],
|
|
16613
|
+
kind: "function",
|
|
16614
|
+
serialize: (serializer, expr2) => "\\operatorname{asOklch}" + serializer.wrapArguments(expr2)
|
|
16615
|
+
},
|
|
16616
|
+
// Perceptual difference (returns a scalar in [0, ~1])
|
|
16617
|
+
{
|
|
16618
|
+
name: "ColorDelta",
|
|
16619
|
+
latexTrigger: ["\\operatorname{colorDelta}"],
|
|
16620
|
+
kind: "function",
|
|
16621
|
+
serialize: (serializer, expr2) => "\\operatorname{colorDelta}" + serializer.wrapArguments(expr2)
|
|
16622
|
+
}
|
|
16412
16623
|
];
|
|
16413
16624
|
|
|
16414
16625
|
// src/compute-engine/latex-syntax/dictionary/default-dictionary.ts
|
|
@@ -16439,7 +16650,8 @@ var ComputeEngine = (() => {
|
|
|
16439
16650
|
...DEFINITIONS_STATISTICS,
|
|
16440
16651
|
...DEFINITIONS_UNITS,
|
|
16441
16652
|
...DEFINITIONS_OTHERS,
|
|
16442
|
-
...DEFINITIONS_PHYSICS
|
|
16653
|
+
...DEFINITIONS_PHYSICS,
|
|
16654
|
+
...DEFINITIONS_COLORS
|
|
16443
16655
|
];
|
|
16444
16656
|
|
|
16445
16657
|
// src/math-json/symbols.ts
|
|
@@ -16604,6 +16816,17 @@ var ComputeEngine = (() => {
|
|
|
16604
16816
|
} else if (Array.isArray(openTrigger) && openTrigger.length > 0) {
|
|
16605
16817
|
openTokens.push(openTrigger[0]);
|
|
16606
16818
|
}
|
|
16819
|
+
const closeTrigger = indexedEntry.closeTrigger;
|
|
16820
|
+
const closeTokens = /* @__PURE__ */ new Set();
|
|
16821
|
+
if (typeof closeTrigger === "string") {
|
|
16822
|
+
const variants = DELIMITER_SHORTHAND[closeTrigger];
|
|
16823
|
+
if (variants) for (const v of variants) closeTokens.add(v);
|
|
16824
|
+
else closeTokens.add(closeTrigger);
|
|
16825
|
+
if (closeTrigger === "||") closeTokens.add("|");
|
|
16826
|
+
} else if (Array.isArray(closeTrigger) && closeTrigger.length > 0) {
|
|
16827
|
+
closeTokens.add(closeTrigger[0]);
|
|
16828
|
+
}
|
|
16829
|
+
indexedEntry.closeTokens = closeTokens;
|
|
16607
16830
|
for (const token of openTokens) {
|
|
16608
16831
|
const existing = result.matchfixByOpen.get(token);
|
|
16609
16832
|
if (existing) {
|
|
@@ -16761,25 +16984,43 @@ var ComputeEngine = (() => {
|
|
|
16761
16984
|
result.arguments = entry.arguments;
|
|
16762
16985
|
return result;
|
|
16763
16986
|
}
|
|
16987
|
+
function serializeTabularBody(serializer, body) {
|
|
16988
|
+
if (!body) return "";
|
|
16989
|
+
if (operator(body) !== "List") return serializer.serialize(body);
|
|
16990
|
+
const rows = operands(body);
|
|
16991
|
+
if (rows.length === 0) return "";
|
|
16992
|
+
if (!rows.every((row) => operator(row) === "List"))
|
|
16993
|
+
return serializer.serialize(body);
|
|
16994
|
+
return rows.map(
|
|
16995
|
+
(row) => operands(row).map((cell) => serializer.serialize(cell)).join(" & ")
|
|
16996
|
+
).join(" \\\\\n");
|
|
16997
|
+
}
|
|
16764
16998
|
function makeSerializeHandler(entry, latexTrigger, idTrigger) {
|
|
16765
16999
|
if (typeof entry.serialize === "function") return entry.serialize;
|
|
16766
17000
|
const kind = entry["kind"] ?? "expression";
|
|
16767
17001
|
if (kind === "environment") {
|
|
16768
17002
|
const envName = entry["symbolTrigger"] ?? entry.name ?? "unknown";
|
|
16769
|
-
return (serializer, expr2) =>
|
|
16770
|
-
|
|
16771
|
-
|
|
16772
|
-
|
|
16773
|
-
|
|
17003
|
+
return (serializer, expr2) => {
|
|
17004
|
+
const body = operand(expr2, 1);
|
|
17005
|
+
return joinLatex([
|
|
17006
|
+
`\\begin{${envName}}`,
|
|
17007
|
+
serializeTabularBody(serializer, body),
|
|
17008
|
+
`\\end{${envName}}`
|
|
17009
|
+
]);
|
|
17010
|
+
};
|
|
16774
17011
|
}
|
|
16775
17012
|
if (isMatchfixEntry(entry)) {
|
|
16776
17013
|
const openDelim = typeof entry.openTrigger === "string" ? DEFAULT_DELIMITER[entry.openTrigger] : tokensToString(entry.openTrigger);
|
|
16777
17014
|
const closeDelim = typeof entry.closeTrigger === "string" ? DEFAULT_DELIMITER[entry.closeTrigger] : tokensToString(entry.closeTrigger);
|
|
16778
|
-
return (serializer, expr2) =>
|
|
16779
|
-
|
|
16780
|
-
serializer.serialize(operand(expr2, 1))
|
|
16781
|
-
|
|
16782
|
-
|
|
17015
|
+
return (serializer, expr2) => {
|
|
17016
|
+
const style = serializer.groupStyle(expr2, serializer.level + 1);
|
|
17017
|
+
const inner = serializer.serialize(operand(expr2, 1));
|
|
17018
|
+
if (style === "scaled")
|
|
17019
|
+
return joinLatex([`\\left${openDelim}`, inner, `\\right${closeDelim}`]);
|
|
17020
|
+
if (style === "big")
|
|
17021
|
+
return joinLatex([`\\Bigl${openDelim}`, inner, `\\Bigr${closeDelim}`]);
|
|
17022
|
+
return joinLatex([openDelim, inner, closeDelim]);
|
|
17023
|
+
};
|
|
16783
17024
|
}
|
|
16784
17025
|
let latex = entry.serialize;
|
|
16785
17026
|
if (latex === void 0 && latexTrigger) latex = tokensToString(latexTrigger);
|
|
@@ -17664,6 +17905,16 @@ var ComputeEngine = (() => {
|
|
|
17664
17905
|
}
|
|
17665
17906
|
|
|
17666
17907
|
// src/compute-engine/latex-syntax/parse.ts
|
|
17908
|
+
var _symbolToUnicode = null;
|
|
17909
|
+
function getSymbolToUnicode() {
|
|
17910
|
+
if (!_symbolToUnicode) {
|
|
17911
|
+
_symbolToUnicode = /* @__PURE__ */ new Map();
|
|
17912
|
+
for (const [, latex, codepoint] of SYMBOLS2) {
|
|
17913
|
+
_symbolToUnicode.set(latex, String.fromCodePoint(codepoint));
|
|
17914
|
+
}
|
|
17915
|
+
}
|
|
17916
|
+
return _symbolToUnicode;
|
|
17917
|
+
}
|
|
17667
17918
|
var DELIMITER_SHORTHAND2 = {
|
|
17668
17919
|
"(": ["\\lparen", "("],
|
|
17669
17920
|
")": ["\\rparen", ")"],
|
|
@@ -18111,6 +18362,35 @@ var ComputeEngine = (() => {
|
|
|
18111
18362
|
this.nextToken();
|
|
18112
18363
|
this.skipVisualSpace();
|
|
18113
18364
|
}
|
|
18365
|
+
if (this.match("\\hspace")) {
|
|
18366
|
+
this.match("*");
|
|
18367
|
+
this.parseStringGroup();
|
|
18368
|
+
this.skipVisualSpace();
|
|
18369
|
+
}
|
|
18370
|
+
if (this.match("\\hskip") || this.match("\\kern")) {
|
|
18371
|
+
this.skipSpace();
|
|
18372
|
+
if (!this.match("-")) this.match("+");
|
|
18373
|
+
while (/^[\d.]$/.test(this.peek)) this.nextToken();
|
|
18374
|
+
for (const unit of [
|
|
18375
|
+
"pt",
|
|
18376
|
+
"em",
|
|
18377
|
+
"mu",
|
|
18378
|
+
"ex",
|
|
18379
|
+
"mm",
|
|
18380
|
+
"cm",
|
|
18381
|
+
"in",
|
|
18382
|
+
"bp",
|
|
18383
|
+
"sp",
|
|
18384
|
+
"dd",
|
|
18385
|
+
"cc",
|
|
18386
|
+
"pc",
|
|
18387
|
+
"nc",
|
|
18388
|
+
"nd"
|
|
18389
|
+
]) {
|
|
18390
|
+
if (this.matchAll([...unit])) break;
|
|
18391
|
+
}
|
|
18392
|
+
this.skipVisualSpace();
|
|
18393
|
+
}
|
|
18114
18394
|
this.skipSpace();
|
|
18115
18395
|
}
|
|
18116
18396
|
match(token) {
|
|
@@ -18448,7 +18728,8 @@ var ComputeEngine = (() => {
|
|
|
18448
18728
|
} else if (token === "<space>") {
|
|
18449
18729
|
result += " ";
|
|
18450
18730
|
} else if (token[0] === "\\") {
|
|
18451
|
-
|
|
18731
|
+
const unicode = getSymbolToUnicode().get(token);
|
|
18732
|
+
result += unicode ?? token;
|
|
18452
18733
|
} else {
|
|
18453
18734
|
result += token;
|
|
18454
18735
|
}
|
|
@@ -18602,6 +18883,19 @@ var ComputeEngine = (() => {
|
|
|
18602
18883
|
}
|
|
18603
18884
|
for (const def of defs) {
|
|
18604
18885
|
this.index = start;
|
|
18886
|
+
if (def.closeTokens.size > 0) {
|
|
18887
|
+
let found = false;
|
|
18888
|
+
const tokens = this._tokens;
|
|
18889
|
+
for (let i = start; i < tokens.length; i++) {
|
|
18890
|
+
if (def.closeTokens.has(tokens[i])) {
|
|
18891
|
+
found = true;
|
|
18892
|
+
break;
|
|
18893
|
+
}
|
|
18894
|
+
}
|
|
18895
|
+
if (!found) continue;
|
|
18896
|
+
}
|
|
18897
|
+
if (typeof def.openTrigger === "string" && def.openTrigger === "." && !OPEN_DELIMITER_PREFIX[currentToken])
|
|
18898
|
+
continue;
|
|
18605
18899
|
const matched = this.matchDelimiter(def.openTrigger, def.closeTrigger);
|
|
18606
18900
|
if (!matched) continue;
|
|
18607
18901
|
const bodyStart = this.index;
|
|
@@ -19808,7 +20102,7 @@ var ComputeEngine = (() => {
|
|
|
19808
20102
|
sansserif: (s) => `\\mathsf{${s}}`,
|
|
19809
20103
|
monospace: (s) => `\\mathtt{${s}}`
|
|
19810
20104
|
};
|
|
19811
|
-
var
|
|
20105
|
+
var Serializer5 = class {
|
|
19812
20106
|
options;
|
|
19813
20107
|
dictionary;
|
|
19814
20108
|
level = -1;
|
|
@@ -19823,11 +20117,18 @@ var ComputeEngine = (() => {
|
|
|
19823
20117
|
/**
|
|
19824
20118
|
* Serialize the expression, and if the expression is an operator
|
|
19825
20119
|
* of precedence less than or equal to prec, wrap it in some parens.
|
|
19826
|
-
*
|
|
20120
|
+
*
|
|
20121
|
+
* Skip wrapping for matchfix operators (Abs, Floor, Ceil, Norm, etc.)
|
|
20122
|
+
* and Delimiter since they already have visible delimiters.
|
|
19827
20123
|
*/
|
|
19828
20124
|
wrap(expr2, prec) {
|
|
19829
20125
|
if (expr2 === null || expr2 === void 0) return "";
|
|
19830
20126
|
if (prec === void 0) {
|
|
20127
|
+
const name2 = operator(expr2);
|
|
20128
|
+
if (name2) {
|
|
20129
|
+
const def = this.dictionary.ids.get(name2);
|
|
20130
|
+
if (def?.kind === "matchfix") return this.serialize(expr2);
|
|
20131
|
+
}
|
|
19831
20132
|
return this.wrapString(
|
|
19832
20133
|
this.serialize(expr2),
|
|
19833
20134
|
this.options.groupStyle(expr2, this.level + 1)
|
|
@@ -20121,7 +20422,7 @@ var ComputeEngine = (() => {
|
|
|
20121
20422
|
return body;
|
|
20122
20423
|
}
|
|
20123
20424
|
function serializeLatex(expr2, dict, options) {
|
|
20124
|
-
const serializer = new
|
|
20425
|
+
const serializer = new Serializer5(dict, options);
|
|
20125
20426
|
return serializer.serialize(expr2);
|
|
20126
20427
|
}
|
|
20127
20428
|
|
|
@@ -32157,6 +32458,29 @@ ${lines.join("\n")}`;
|
|
|
32157
32458
|
signature: "(value*) -> number | list",
|
|
32158
32459
|
evaluate: (xs, { engine }) => evaluateMinMax(engine, xs, "Infimum")
|
|
32159
32460
|
},
|
|
32461
|
+
Distance: {
|
|
32462
|
+
description: "Euclidean distance between two points (tuples of numbers).",
|
|
32463
|
+
complexity: 6e3,
|
|
32464
|
+
signature: "(tuple, tuple) -> number",
|
|
32465
|
+
evaluate: ([a, b], { engine: ce }) => {
|
|
32466
|
+
if (!isFunction2(a) || !isFunction2(b))
|
|
32467
|
+
return ce.error("incompatible-type");
|
|
32468
|
+
if (a.operator !== "Tuple" || b.operator !== "Tuple")
|
|
32469
|
+
return ce.error("incompatible-type");
|
|
32470
|
+
if (a.ops.length !== b.ops.length || a.ops.length === 0)
|
|
32471
|
+
return ce.error("incompatible-type");
|
|
32472
|
+
let sumSq = 0;
|
|
32473
|
+
for (let i = 0; i < a.ops.length; i++) {
|
|
32474
|
+
const ai = a.ops[i].re;
|
|
32475
|
+
const bi = b.ops[i].re;
|
|
32476
|
+
if (!Number.isFinite(ai) || !Number.isFinite(bi))
|
|
32477
|
+
return ce.error("expected-value");
|
|
32478
|
+
const d = ai - bi;
|
|
32479
|
+
sumSq += d * d;
|
|
32480
|
+
}
|
|
32481
|
+
return ce.number(Math.sqrt(sumSq));
|
|
32482
|
+
}
|
|
32483
|
+
},
|
|
32160
32484
|
Product: {
|
|
32161
32485
|
description: "`Product(f, a, b)` computes the product of `f` from `a` to `b`",
|
|
32162
32486
|
wikidata: "Q901718",
|
|
@@ -32689,16 +33013,11 @@ ${lines.join("\n")}`;
|
|
|
32689
33013
|
);
|
|
32690
33014
|
let condFn;
|
|
32691
33015
|
if (typeof condition === "string") {
|
|
32692
|
-
const
|
|
32693
|
-
|
|
32694
|
-
const
|
|
32695
|
-
|
|
32696
|
-
|
|
32697
|
-
condFn = (x, _ce) => {
|
|
32698
|
-
const evaluated = condPattern.subs(x).evaluate();
|
|
32699
|
-
return isSymbol2(evaluated, "True");
|
|
32700
|
-
};
|
|
32701
|
-
}
|
|
33016
|
+
const condPattern = ce.parse(condition) ?? ce.expr("Nothing");
|
|
33017
|
+
condFn = (x, _ce) => {
|
|
33018
|
+
const evaluated = condPattern.subs(x).evaluate();
|
|
33019
|
+
return isSymbol2(evaluated, "True");
|
|
33020
|
+
};
|
|
32702
33021
|
} else {
|
|
32703
33022
|
if (condition !== void 0 && typeof condition !== "function")
|
|
32704
33023
|
throw new Error(
|
|
@@ -32800,6 +33119,15 @@ ${e.message}
|
|
|
32800
33119
|
function applyRule(rule, expr2, substitution, options) {
|
|
32801
33120
|
if (!rule) return null;
|
|
32802
33121
|
let canonical2 = options?.canonical ?? (expr2.isCanonical || expr2.isStructural);
|
|
33122
|
+
let { match: match2, replace: replace2, condition, id, onMatch, onBeforeMatch } = rule;
|
|
33123
|
+
const because = id ?? "";
|
|
33124
|
+
const ce = expr2.engine;
|
|
33125
|
+
if (canonical2 && match2) {
|
|
33126
|
+
const awc = getWildcards(match2);
|
|
33127
|
+
const canonicalMatch = match2.canonical;
|
|
33128
|
+
const bwc = getWildcards(canonicalMatch);
|
|
33129
|
+
if (!awc.every((x) => bwc.includes(x))) return null;
|
|
33130
|
+
}
|
|
32803
33131
|
let operandsMatched = false;
|
|
32804
33132
|
if (isFunction2(expr2) && options?.recursive) {
|
|
32805
33133
|
const newOps = expr2.ops.map((op) => {
|
|
@@ -32811,20 +33139,11 @@ ${e.message}
|
|
|
32811
33139
|
if (operandsMatched) {
|
|
32812
33140
|
if (!canonical2 && options?.canonical === void 0 && newOps.every((x) => x.isCanonical))
|
|
32813
33141
|
canonical2 = true;
|
|
32814
|
-
expr2 =
|
|
33142
|
+
expr2 = ce.function(expr2.operator, newOps, {
|
|
32815
33143
|
form: canonical2 ? "canonical" : "raw"
|
|
32816
33144
|
});
|
|
32817
33145
|
}
|
|
32818
33146
|
}
|
|
32819
|
-
let { match: match2, replace: replace2, condition, id, onMatch, onBeforeMatch } = rule;
|
|
32820
|
-
const because = id ?? "";
|
|
32821
|
-
if (canonical2 && match2) {
|
|
32822
|
-
const awc = getWildcards(match2);
|
|
32823
|
-
const canonicalMatch = match2.canonical;
|
|
32824
|
-
const bwc = getWildcards(canonicalMatch);
|
|
32825
|
-
if (!awc.every((x) => bwc.includes(x)))
|
|
32826
|
-
return operandsMatched ? { value: expr2, because } : null;
|
|
32827
|
-
}
|
|
32828
33147
|
const useVariations = rule.useVariations ?? options?.useVariations ?? false;
|
|
32829
33148
|
const matchPermutations = options?.matchPermutations ?? true;
|
|
32830
33149
|
onBeforeMatch?.(rule, expr2);
|
|
@@ -32843,7 +33162,7 @@ ${e.message}
|
|
|
32843
33162
|
...sub2
|
|
32844
33163
|
};
|
|
32845
33164
|
try {
|
|
32846
|
-
if (!condition(conditionSub,
|
|
33165
|
+
if (!condition(conditionSub, ce))
|
|
32847
33166
|
return operandsMatched ? { value: expr2, because } : null;
|
|
32848
33167
|
} catch (e) {
|
|
32849
33168
|
console.error(
|
|
@@ -32858,7 +33177,8 @@ ${e.message}
|
|
|
32858
33177
|
if (!canonical2 && options?.canonical === void 0 && replace2 instanceof _BoxedExpression && replace2.isCanonical)
|
|
32859
33178
|
canonical2 = true;
|
|
32860
33179
|
const result = typeof replace2 === "function" ? replace2(expr2, sub2) : replace2.subs(sub2, { canonical: canonical2 });
|
|
32861
|
-
if (!result)
|
|
33180
|
+
if (!result)
|
|
33181
|
+
return operandsMatched ? { value: canonical2 ? expr2.canonical : expr2, because } : null;
|
|
32862
33182
|
onMatch?.(rule, expr2, result);
|
|
32863
33183
|
if (isRuleStep(result))
|
|
32864
33184
|
return canonical2 ? { ...result, value: result.value.canonical } : result;
|
|
@@ -38432,6 +38752,40 @@ ${e.message}
|
|
|
38432
38752
|
else h = ((r - g) / d + 4) / 6;
|
|
38433
38753
|
return { h: h * 360, s, l };
|
|
38434
38754
|
}
|
|
38755
|
+
function hsvToRgb(h, s, v) {
|
|
38756
|
+
h = (h % 360 + 360) % 360;
|
|
38757
|
+
s = Math.max(0, Math.min(1, s));
|
|
38758
|
+
v = Math.max(0, Math.min(1, v));
|
|
38759
|
+
const c = v * s;
|
|
38760
|
+
const x = c * (1 - Math.abs(h / 60 % 2 - 1));
|
|
38761
|
+
const m = v - c;
|
|
38762
|
+
let r = 0, g = 0, b = 0;
|
|
38763
|
+
if (h < 60) [r, g, b] = [c, x, 0];
|
|
38764
|
+
else if (h < 120) [r, g, b] = [x, c, 0];
|
|
38765
|
+
else if (h < 180) [r, g, b] = [0, c, x];
|
|
38766
|
+
else if (h < 240) [r, g, b] = [0, x, c];
|
|
38767
|
+
else if (h < 300) [r, g, b] = [x, 0, c];
|
|
38768
|
+
else [r, g, b] = [c, 0, x];
|
|
38769
|
+
return { r: (r + m) * 255, g: (g + m) * 255, b: (b + m) * 255 };
|
|
38770
|
+
}
|
|
38771
|
+
function rgbToHsv(r, g, b) {
|
|
38772
|
+
r /= 255;
|
|
38773
|
+
g /= 255;
|
|
38774
|
+
b /= 255;
|
|
38775
|
+
const max2 = Math.max(r, g, b);
|
|
38776
|
+
const min2 = Math.min(r, g, b);
|
|
38777
|
+
const d = max2 - min2;
|
|
38778
|
+
let h = 0;
|
|
38779
|
+
if (d > 0) {
|
|
38780
|
+
if (max2 === r) h = (g - b) / d % 6;
|
|
38781
|
+
else if (max2 === g) h = (b - r) / d + 2;
|
|
38782
|
+
else h = (r - g) / d + 4;
|
|
38783
|
+
h *= 60;
|
|
38784
|
+
if (h < 0) h += 360;
|
|
38785
|
+
}
|
|
38786
|
+
const s = max2 === 0 ? 0 : d / max2;
|
|
38787
|
+
return { h, s, v: max2 };
|
|
38788
|
+
}
|
|
38435
38789
|
function parseHexColor(s) {
|
|
38436
38790
|
const hex = s.startsWith("#") ? s.substring(1) : s;
|
|
38437
38791
|
let r, g, b;
|
|
@@ -38456,6 +38810,12 @@ ${e.message}
|
|
|
38456
38810
|
if (alpha !== void 0) result.alpha = alpha;
|
|
38457
38811
|
return result;
|
|
38458
38812
|
}
|
|
38813
|
+
function asOklch(color) {
|
|
38814
|
+
if (typeof color === "string") return rgbToOklch(parseHexColor(color));
|
|
38815
|
+
if ("C" in color) return color;
|
|
38816
|
+
if ("a" in color && "b" in color) return oklabToOklch(color);
|
|
38817
|
+
return rgbToOklch(color);
|
|
38818
|
+
}
|
|
38459
38819
|
function asRgb(color) {
|
|
38460
38820
|
if (typeof color === "number") {
|
|
38461
38821
|
return {
|
|
@@ -38887,6 +39247,13 @@ ${e.message}
|
|
|
38887
39247
|
};
|
|
38888
39248
|
function parseColor(s, darkMode) {
|
|
38889
39249
|
const str = s.trim().toLowerCase();
|
|
39250
|
+
const opacityMatch = str.match(/^(.+?)\s*\/\s*(\d+(?:\.\d+)?)%?\s*$/);
|
|
39251
|
+
if (opacityMatch) {
|
|
39252
|
+
const base = parseColor(opacityMatch[1].trim(), darkMode);
|
|
39253
|
+
const opacity = Math.max(0, Math.min(100, parseFloat(opacityMatch[2])));
|
|
39254
|
+
const alpha = Math.round(opacity / 100 * 255);
|
|
39255
|
+
return base & 4294967040 | alpha;
|
|
39256
|
+
}
|
|
38890
39257
|
if (str.startsWith("#")) {
|
|
38891
39258
|
const hex = str.substring(1);
|
|
38892
39259
|
let r, g, b, a = 255;
|
|
@@ -39019,14 +39386,6 @@ ${e.message}
|
|
|
39019
39386
|
console.warn(`parseColor: unrecognized color "${s}"`);
|
|
39020
39387
|
return 0;
|
|
39021
39388
|
}
|
|
39022
|
-
function parseColorToRgb01(s, darkMode) {
|
|
39023
|
-
const color = parseColor(s, darkMode);
|
|
39024
|
-
return [
|
|
39025
|
-
(color >>> 24 & 255) / 255,
|
|
39026
|
-
(color >>> 16 & 255) / 255,
|
|
39027
|
-
(color >>> 8 & 255) / 255
|
|
39028
|
-
];
|
|
39029
|
-
}
|
|
39030
39389
|
function apca(bgColor, fgColor) {
|
|
39031
39390
|
const bgRgb = asRgb(bgColor);
|
|
39032
39391
|
const fgRgb = asRgb(fgColor);
|
|
@@ -39085,6 +39444,12 @@ ${e.message}
|
|
|
39085
39444
|
const contrast2 = Math.abs(apca(fg2, bg));
|
|
39086
39445
|
return contrast1 >= contrast2 ? asColorNumber(fg1) : asColorNumber(fg2);
|
|
39087
39446
|
}
|
|
39447
|
+
function oklabDeltaE(a, b) {
|
|
39448
|
+
const dL = a.L - b.L;
|
|
39449
|
+
const da = a.a - b.a;
|
|
39450
|
+
const db = a.b - b.b;
|
|
39451
|
+
return Math.sqrt(dL * dL + da * da + db * db);
|
|
39452
|
+
}
|
|
39088
39453
|
function lerpOklch(c1, c2, f) {
|
|
39089
39454
|
const L = c1.L + (c2.L - c1.L) * f;
|
|
39090
39455
|
const C = c1.C + (c2.C - c1.C) * f;
|
|
@@ -41846,14 +42211,30 @@ ${e.message}
|
|
|
41846
42211
|
};
|
|
41847
42212
|
|
|
41848
42213
|
// src/compute-engine/library/colors.ts
|
|
41849
|
-
function
|
|
41850
|
-
|
|
41851
|
-
|
|
41852
|
-
|
|
41853
|
-
|
|
41854
|
-
|
|
41855
|
-
|
|
41856
|
-
|
|
42214
|
+
function normalizeAlpha(a) {
|
|
42215
|
+
if (a === void 0) return void 0;
|
|
42216
|
+
if (!Number.isFinite(a)) return void 0;
|
|
42217
|
+
if (Math.abs(a - 1) < 1e-9) return void 0;
|
|
42218
|
+
return a;
|
|
42219
|
+
}
|
|
42220
|
+
function normalizeColorHead(ce, expr2) {
|
|
42221
|
+
if (!isFunction2(expr2) || !expr2.ops || expr2.ops.length < 4) return expr2;
|
|
42222
|
+
const alphaExpr = expr2.ops[3];
|
|
42223
|
+
if (!isNumber(alphaExpr)) return expr2;
|
|
42224
|
+
if (normalizeAlpha(alphaExpr.re) === void 0) {
|
|
42225
|
+
return ce.function(expr2.operator, [expr2.ops[0], expr2.ops[1], expr2.ops[2]]);
|
|
42226
|
+
}
|
|
42227
|
+
return expr2;
|
|
42228
|
+
}
|
|
42229
|
+
function colorNumberToOklch(ce, color) {
|
|
42230
|
+
const r = color >>> 24 & 255;
|
|
42231
|
+
const g = color >>> 16 & 255;
|
|
42232
|
+
const b = color >>> 8 & 255;
|
|
42233
|
+
const a = normalizeAlpha((color & 255) / 255);
|
|
42234
|
+
const c = rgbToOklch({ r, g, b });
|
|
42235
|
+
const args = [ce.number(c.L), ce.number(c.C), ce.number(c.H)];
|
|
42236
|
+
if (a !== void 0) args.push(ce.number(a));
|
|
42237
|
+
return ce.function("Oklch", args);
|
|
41857
42238
|
}
|
|
41858
42239
|
var ALL_PALETTES = {
|
|
41859
42240
|
...SEQUENTIAL_PALETTES,
|
|
@@ -41864,45 +42245,139 @@ ${e.message}
|
|
|
41864
42245
|
t = Math.max(0, Math.min(1, t));
|
|
41865
42246
|
const n = palette.length;
|
|
41866
42247
|
if (n === 0) return ce.error("expected-value");
|
|
41867
|
-
if (n === 1) return
|
|
42248
|
+
if (n === 1) return colorNumberToOklch(ce, parseColor(palette[0]));
|
|
41868
42249
|
const pos = t * (n - 1);
|
|
41869
42250
|
const i = Math.floor(pos);
|
|
41870
42251
|
const frac = pos - i;
|
|
41871
|
-
if (i >= n - 1) return
|
|
41872
|
-
if (frac < 1e-9) return
|
|
41873
|
-
|
|
41874
|
-
|
|
41875
|
-
|
|
41876
|
-
|
|
41877
|
-
|
|
42252
|
+
if (i >= n - 1) return colorNumberToOklch(ce, parseColor(palette[n - 1]));
|
|
42253
|
+
if (frac < 1e-9) return colorNumberToOklch(ce, parseColor(palette[i]));
|
|
42254
|
+
return oklchToExpr(
|
|
42255
|
+
ce,
|
|
42256
|
+
asOklch(interpolateOklch(palette[i], palette[i + 1], frac))
|
|
42257
|
+
);
|
|
42258
|
+
}
|
|
42259
|
+
var COLOR_OPERATORS = /* @__PURE__ */ new Set(["Rgb", "Hsv", "Hsl", "Oklab", "Oklch"]);
|
|
42260
|
+
function readColorExpr(arg) {
|
|
42261
|
+
if (!isFunction2(arg)) return null;
|
|
42262
|
+
if (!COLOR_OPERATORS.has(arg.operator)) return null;
|
|
42263
|
+
if (!arg.ops || arg.ops.length < 3) return null;
|
|
42264
|
+
const c0 = arg.ops[0].re;
|
|
42265
|
+
const c1 = arg.ops[1].re;
|
|
42266
|
+
const c2 = arg.ops[2].re;
|
|
42267
|
+
if (!Number.isFinite(c0) || !Number.isFinite(c1) || !Number.isFinite(c2))
|
|
42268
|
+
return null;
|
|
42269
|
+
const alpha = arg.ops.length >= 4 ? normalizeAlpha(arg.ops[3].re) : void 0;
|
|
42270
|
+
return { space: arg.operator, c0, c1, c2, alpha };
|
|
42271
|
+
}
|
|
42272
|
+
function colorExprToRgb(arg) {
|
|
42273
|
+
const c = readColorExpr(arg);
|
|
42274
|
+
if (!c) return null;
|
|
42275
|
+
const withAlpha = (rgb) => c.alpha !== void 0 ? { ...rgb, alpha: c.alpha } : rgb;
|
|
42276
|
+
switch (c.space) {
|
|
42277
|
+
case "Rgb":
|
|
42278
|
+
return withAlpha({ r: c.c0 * 255, g: c.c1 * 255, b: c.c2 * 255 });
|
|
42279
|
+
case "Hsv":
|
|
42280
|
+
return withAlpha(hsvToRgb(c.c0, c.c1, c.c2));
|
|
42281
|
+
case "Hsl":
|
|
42282
|
+
return withAlpha(hslToRgb(c.c0, c.c1, c.c2));
|
|
42283
|
+
case "Oklab":
|
|
42284
|
+
return withAlpha(oklabToRgb({ L: c.c0, a: c.c1, b: c.c2 }));
|
|
42285
|
+
case "Oklch":
|
|
42286
|
+
return withAlpha(oklchToRgb({ L: c.c0, C: c.c1, H: c.c2 }));
|
|
42287
|
+
}
|
|
42288
|
+
return null;
|
|
42289
|
+
}
|
|
42290
|
+
function colorExprToOklch(arg) {
|
|
42291
|
+
const c = readColorExpr(arg);
|
|
42292
|
+
if (!c) return null;
|
|
42293
|
+
switch (c.space) {
|
|
42294
|
+
case "Oklch":
|
|
42295
|
+
return asOklch({ L: c.c0, C: c.c1, H: c.c2, alpha: c.alpha });
|
|
42296
|
+
case "Oklab":
|
|
42297
|
+
return asOklch({ L: c.c0, a: c.c1, b: c.c2, alpha: c.alpha });
|
|
42298
|
+
case "Rgb":
|
|
42299
|
+
return asOklch({
|
|
42300
|
+
r: c.c0 * 255,
|
|
42301
|
+
g: c.c1 * 255,
|
|
42302
|
+
b: c.c2 * 255,
|
|
42303
|
+
alpha: c.alpha
|
|
42304
|
+
});
|
|
42305
|
+
case "Hsv": {
|
|
42306
|
+
const rgb = hsvToRgb(c.c0, c.c1, c.c2);
|
|
42307
|
+
return asOklch({ ...rgb, alpha: c.alpha });
|
|
42308
|
+
}
|
|
42309
|
+
case "Hsl": {
|
|
42310
|
+
const rgb = hslToRgb(c.c0, c.c1, c.c2);
|
|
42311
|
+
return asOklch({ r: rgb.r, g: rgb.g, b: rgb.b, alpha: c.alpha });
|
|
42312
|
+
}
|
|
42313
|
+
}
|
|
42314
|
+
return null;
|
|
42315
|
+
}
|
|
42316
|
+
function toOklch(ce, arg) {
|
|
42317
|
+
const direct = colorExprToOklch(arg);
|
|
42318
|
+
if (direct) return direct;
|
|
42319
|
+
const rgb = extractRgb(ce, arg);
|
|
42320
|
+
return rgb ? asOklch(rgb) : null;
|
|
42321
|
+
}
|
|
42322
|
+
function lerpOklchColor(a, b, t) {
|
|
42323
|
+
const L = a.L + (b.L - a.L) * t;
|
|
42324
|
+
const C = a.C + (b.C - a.C) * t;
|
|
42325
|
+
const aAchromatic = a.C < 1e-6;
|
|
42326
|
+
const bAchromatic = b.C < 1e-6;
|
|
42327
|
+
let H;
|
|
42328
|
+
if (aAchromatic && bAchromatic) H = a.H;
|
|
42329
|
+
else if (aAchromatic) H = b.H;
|
|
42330
|
+
else if (bAchromatic) H = a.H;
|
|
42331
|
+
else {
|
|
42332
|
+
let dH = b.H - a.H;
|
|
42333
|
+
if (dH > 180) dH -= 360;
|
|
42334
|
+
if (dH < -180) dH += 360;
|
|
42335
|
+
H = a.H + dH * t;
|
|
42336
|
+
if (H < 0) H += 360;
|
|
42337
|
+
if (H >= 360) H -= 360;
|
|
42338
|
+
}
|
|
42339
|
+
const alphaA = a.alpha ?? 1;
|
|
42340
|
+
const alphaB = b.alpha ?? 1;
|
|
42341
|
+
return { L, C, H, alpha: normalizeAlpha(alphaA + (alphaB - alphaA) * t) };
|
|
42342
|
+
}
|
|
42343
|
+
function oklchToExpr(ce, c) {
|
|
42344
|
+
const args = [ce.number(c.L), ce.number(c.C), ce.number(c.H)];
|
|
42345
|
+
if (c.alpha !== void 0) args.push(ce.number(c.alpha));
|
|
42346
|
+
return ce.function("Oklch", args);
|
|
41878
42347
|
}
|
|
41879
42348
|
function extractRgb(ce, arg) {
|
|
41880
42349
|
if (isString(arg)) {
|
|
41881
42350
|
const s = arg.string;
|
|
41882
42351
|
if (!s) return void 0;
|
|
41883
42352
|
const color = parseColor(s);
|
|
41884
|
-
|
|
42353
|
+
const rgb = {
|
|
41885
42354
|
r: color >>> 24 & 255,
|
|
41886
42355
|
g: color >>> 16 & 255,
|
|
41887
|
-
b: color >>> 8 & 255
|
|
41888
|
-
alpha: (color & 255) / 255
|
|
42356
|
+
b: color >>> 8 & 255
|
|
41889
42357
|
};
|
|
42358
|
+
const alpha = normalizeAlpha((color & 255) / 255);
|
|
42359
|
+
if (alpha !== void 0) rgb.alpha = alpha;
|
|
42360
|
+
return rgb;
|
|
41890
42361
|
}
|
|
42362
|
+
const fromTyped = colorExprToRgb(arg);
|
|
42363
|
+
if (fromTyped) return fromTyped;
|
|
41891
42364
|
if (arg.operator === "Tuple" && arg.ops && arg.ops.length >= 3) {
|
|
41892
42365
|
const rgb = {
|
|
41893
42366
|
r: arg.ops[0].re * 255,
|
|
41894
42367
|
g: arg.ops[1].re * 255,
|
|
41895
42368
|
b: arg.ops[2].re * 255
|
|
41896
42369
|
};
|
|
41897
|
-
if (arg.ops.length >= 4)
|
|
42370
|
+
if (arg.ops.length >= 4) {
|
|
42371
|
+
const alpha = normalizeAlpha(arg.ops[3].re);
|
|
42372
|
+
if (alpha !== void 0) rgb.alpha = alpha;
|
|
42373
|
+
}
|
|
41898
42374
|
return rgb;
|
|
41899
42375
|
}
|
|
41900
42376
|
return void 0;
|
|
41901
42377
|
}
|
|
41902
42378
|
function componentsTuple(ce, components, alpha) {
|
|
41903
42379
|
const args = components.map((v) => ce.number(v));
|
|
41904
|
-
if (alpha !== void 0
|
|
41905
|
-
args.push(ce.number(alpha));
|
|
42380
|
+
if (alpha !== void 0) args.push(ce.number(alpha));
|
|
41906
42381
|
return ce.tuple(...args);
|
|
41907
42382
|
}
|
|
41908
42383
|
function rgbToHex(rgb) {
|
|
@@ -41910,7 +42385,7 @@ ${e.message}
|
|
|
41910
42385
|
const g = Math.round(Math.max(0, Math.min(255, rgb.g)));
|
|
41911
42386
|
const b = Math.round(Math.max(0, Math.min(255, rgb.b)));
|
|
41912
42387
|
const hex = `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
|
|
41913
|
-
if (rgb.alpha !== void 0
|
|
42388
|
+
if (rgb.alpha !== void 0) {
|
|
41914
42389
|
const a = Math.round(Math.max(0, Math.min(255, rgb.alpha * 255)));
|
|
41915
42390
|
return hex + a.toString(16).padStart(2, "0");
|
|
41916
42391
|
}
|
|
@@ -41918,22 +42393,29 @@ ${e.message}
|
|
|
41918
42393
|
}
|
|
41919
42394
|
var COLORS_LIBRARY = {
|
|
41920
42395
|
Color: {
|
|
41921
|
-
description: "
|
|
42396
|
+
description: "Parse a CSS-style color string to an Oklch color",
|
|
41922
42397
|
complexity: 8e3,
|
|
41923
|
-
signature: "(string) ->
|
|
42398
|
+
signature: "(string) -> color",
|
|
41924
42399
|
evaluate: (ops, { engine: ce }) => {
|
|
41925
42400
|
const input = isString(ops[0]) ? ops[0].string : void 0;
|
|
41926
42401
|
if (!input) return ce.error("incompatible-type");
|
|
41927
42402
|
const color = parseColor(input);
|
|
41928
42403
|
if (color === 0 && input.trim().toLowerCase() !== "transparent")
|
|
41929
42404
|
return ce.error("incompatible-type");
|
|
41930
|
-
|
|
42405
|
+
const r = color >>> 24 & 255;
|
|
42406
|
+
const g = color >>> 16 & 255;
|
|
42407
|
+
const b = color >>> 8 & 255;
|
|
42408
|
+
const a = normalizeAlpha((color & 255) / 255);
|
|
42409
|
+
const c = rgbToOklch({ r, g, b });
|
|
42410
|
+
const args = [ce.number(c.L), ce.number(c.C), ce.number(c.H)];
|
|
42411
|
+
if (a !== void 0) args.push(ce.number(a));
|
|
42412
|
+
return ce.function("Oklch", args);
|
|
41931
42413
|
}
|
|
41932
42414
|
},
|
|
41933
42415
|
ColorToString: {
|
|
41934
42416
|
description: "Convert a color to a string in the specified format",
|
|
41935
42417
|
complexity: 8e3,
|
|
41936
|
-
signature: "(
|
|
42418
|
+
signature: "(color | string | tuple, string?) -> string",
|
|
41937
42419
|
evaluate: (ops, { engine: ce }) => {
|
|
41938
42420
|
const rgb = extractRgb(ce, ops[0]);
|
|
41939
42421
|
if (!rgb) return ce.error("incompatible-type");
|
|
@@ -41945,7 +42427,7 @@ ${e.message}
|
|
|
41945
42427
|
const r = Math.round(rgb.r);
|
|
41946
42428
|
const g = Math.round(rgb.g);
|
|
41947
42429
|
const b = Math.round(rgb.b);
|
|
41948
|
-
if (rgb.alpha !== void 0
|
|
42430
|
+
if (rgb.alpha !== void 0)
|
|
41949
42431
|
return ce.string(`rgb(${r} ${g} ${b} / ${rgb.alpha})`);
|
|
41950
42432
|
return ce.string(`rgb(${r} ${g} ${b})`);
|
|
41951
42433
|
}
|
|
@@ -41954,17 +42436,17 @@ ${e.message}
|
|
|
41954
42436
|
const h = Math.round(hsl.h * 10) / 10;
|
|
41955
42437
|
const s = Math.round(hsl.s * 1e3) / 10;
|
|
41956
42438
|
const l = Math.round(hsl.l * 1e3) / 10;
|
|
41957
|
-
if (rgb.alpha !== void 0
|
|
42439
|
+
if (rgb.alpha !== void 0)
|
|
41958
42440
|
return ce.string(`hsl(${h} ${s}% ${l}% / ${rgb.alpha})`);
|
|
41959
42441
|
return ce.string(`hsl(${h} ${s}% ${l}%)`);
|
|
41960
42442
|
}
|
|
41961
42443
|
case "oklch": {
|
|
41962
|
-
const c =
|
|
42444
|
+
const c = colorExprToOklch(ops[0]) ?? asOklch(rgb);
|
|
41963
42445
|
const L = Math.round(c.L * 1e3) / 1e3;
|
|
41964
42446
|
const C = Math.round(c.C * 1e3) / 1e3;
|
|
41965
42447
|
const H = Math.round(c.H * 10) / 10;
|
|
41966
|
-
if (
|
|
41967
|
-
return ce.string(`oklch(${L} ${C} ${H} / ${
|
|
42448
|
+
if (c.alpha !== void 0)
|
|
42449
|
+
return ce.string(`oklch(${L} ${C} ${H} / ${c.alpha})`);
|
|
41968
42450
|
return ce.string(`oklch(${L} ${C} ${H})`);
|
|
41969
42451
|
}
|
|
41970
42452
|
default:
|
|
@@ -41975,60 +42457,44 @@ ${e.message}
|
|
|
41975
42457
|
ColorMix: {
|
|
41976
42458
|
description: "Mix two colors in OKLCh space",
|
|
41977
42459
|
complexity: 8e3,
|
|
41978
|
-
signature: "(
|
|
42460
|
+
signature: "(color | string | tuple, color | string | tuple, number?) -> color",
|
|
41979
42461
|
evaluate: (ops, { engine: ce }) => {
|
|
41980
|
-
const rgb1 = extractRgb(ce, ops[0]);
|
|
41981
|
-
const rgb2 = extractRgb(ce, ops[1]);
|
|
41982
|
-
if (!rgb1 || !rgb2) return ce.error("incompatible-type");
|
|
41983
42462
|
let ratio = 0.5;
|
|
41984
42463
|
if (ops.length >= 3 && ops[2] !== void 0) {
|
|
41985
42464
|
ratio = ops[2].re;
|
|
41986
42465
|
if (!Number.isFinite(ratio)) return ce.error("expected-value");
|
|
41987
42466
|
ratio = Math.max(0, Math.min(1, ratio));
|
|
41988
42467
|
}
|
|
41989
|
-
const
|
|
41990
|
-
const
|
|
41991
|
-
|
|
41992
|
-
|
|
41993
|
-
const g = mixed.g / 255;
|
|
41994
|
-
const b = mixed.b / 255;
|
|
41995
|
-
const a1 = rgb1.alpha ?? 1;
|
|
41996
|
-
const a2 = rgb2.alpha ?? 1;
|
|
41997
|
-
const alpha = a1 + (a2 - a1) * ratio;
|
|
41998
|
-
if (Math.abs(alpha - 1) > 1e-4)
|
|
41999
|
-
return ce.tuple(
|
|
42000
|
-
ce.number(r),
|
|
42001
|
-
ce.number(g),
|
|
42002
|
-
ce.number(b),
|
|
42003
|
-
ce.number(alpha)
|
|
42004
|
-
);
|
|
42005
|
-
return ce.tuple(ce.number(r), ce.number(g), ce.number(b));
|
|
42468
|
+
const oklch1 = toOklch(ce, ops[0]);
|
|
42469
|
+
const oklch2 = toOklch(ce, ops[1]);
|
|
42470
|
+
if (!oklch1 || !oklch2) return ce.error("incompatible-type");
|
|
42471
|
+
return oklchToExpr(ce, lerpOklchColor(oklch1, oklch2, ratio));
|
|
42006
42472
|
}
|
|
42007
42473
|
},
|
|
42008
42474
|
Colormap: {
|
|
42009
42475
|
description: "Sample colors from a named palette",
|
|
42010
42476
|
complexity: 8e3,
|
|
42011
|
-
signature: "(string, number?) ->
|
|
42477
|
+
signature: "(string, number?) -> color | list<color>",
|
|
42012
42478
|
evaluate: (ops, { engine: ce }) => {
|
|
42013
42479
|
const name = isString(ops[0]) ? ops[0].string : void 0;
|
|
42014
42480
|
if (!name) return ce.error("incompatible-type");
|
|
42015
42481
|
const palette = ALL_PALETTES[name];
|
|
42016
42482
|
if (!palette) return ce.error("expected-value", name);
|
|
42017
42483
|
if (ops.length < 2 || ops[1] === void 0) {
|
|
42018
|
-
const
|
|
42019
|
-
(hex) =>
|
|
42484
|
+
const colors = palette.map(
|
|
42485
|
+
(hex) => colorNumberToOklch(ce, parseColor(hex))
|
|
42020
42486
|
);
|
|
42021
|
-
return ce.function("List",
|
|
42487
|
+
return ce.function("List", colors);
|
|
42022
42488
|
}
|
|
42023
42489
|
const val = ops[1].re;
|
|
42024
42490
|
if (!Number.isFinite(val)) return ce.error("expected-value");
|
|
42025
42491
|
if (Number.isInteger(val) && val >= 2) {
|
|
42026
42492
|
const n = val;
|
|
42027
|
-
const
|
|
42493
|
+
const colors = [];
|
|
42028
42494
|
for (let i = 0; i < n; i++) {
|
|
42029
|
-
|
|
42495
|
+
colors.push(samplePalette(ce, palette, i / (n - 1)));
|
|
42030
42496
|
}
|
|
42031
|
-
return ce.function("List",
|
|
42497
|
+
return ce.function("List", colors);
|
|
42032
42498
|
}
|
|
42033
42499
|
return samplePalette(ce, palette, val);
|
|
42034
42500
|
}
|
|
@@ -42036,12 +42502,25 @@ ${e.message}
|
|
|
42036
42502
|
ColorToColorspace: {
|
|
42037
42503
|
description: "Convert a color to components in a target color space",
|
|
42038
42504
|
complexity: 8e3,
|
|
42039
|
-
signature: "(
|
|
42505
|
+
signature: "(color | string | tuple, string) -> tuple",
|
|
42040
42506
|
evaluate: (ops, { engine: ce }) => {
|
|
42041
|
-
const rgb = extractRgb(ce, ops[0]);
|
|
42042
|
-
if (!rgb) return ce.error("incompatible-type");
|
|
42043
42507
|
const space = isString(ops[1]) ? ops[1].string?.toLowerCase() : void 0;
|
|
42044
42508
|
if (!space) return ce.error("incompatible-type");
|
|
42509
|
+
if (space === "oklch" || space === "oklab" || space === "lab") {
|
|
42510
|
+
const oklch2 = colorExprToOklch(ops[0]);
|
|
42511
|
+
if (oklch2) {
|
|
42512
|
+
if (space === "oklch")
|
|
42513
|
+
return componentsTuple(
|
|
42514
|
+
ce,
|
|
42515
|
+
[oklch2.L, oklch2.C, oklch2.H],
|
|
42516
|
+
oklch2.alpha
|
|
42517
|
+
);
|
|
42518
|
+
const lab = oklchToOklab(oklch2);
|
|
42519
|
+
return componentsTuple(ce, [lab.L, lab.a, lab.b], lab.alpha);
|
|
42520
|
+
}
|
|
42521
|
+
}
|
|
42522
|
+
const rgb = extractRgb(ce, ops[0]);
|
|
42523
|
+
if (!rgb) return ce.error("incompatible-type");
|
|
42045
42524
|
const alpha = rgb.alpha;
|
|
42046
42525
|
switch (space) {
|
|
42047
42526
|
case "rgb":
|
|
@@ -42071,17 +42550,27 @@ ${e.message}
|
|
|
42071
42550
|
ColorFromColorspace: {
|
|
42072
42551
|
description: "Convert color space components to a canonical sRGB tuple",
|
|
42073
42552
|
complexity: 8e3,
|
|
42074
|
-
signature: "(tuple, string) -> tuple",
|
|
42553
|
+
signature: "(color | tuple, string) -> tuple",
|
|
42075
42554
|
evaluate: (ops, { engine: ce }) => {
|
|
42076
|
-
const tuple = ops[0];
|
|
42077
|
-
if (!isFunction2(tuple) || tuple.operator !== "Tuple" || tuple.ops.length < 3)
|
|
42078
|
-
return ce.error("incompatible-type");
|
|
42079
|
-
const c0 = tuple.ops[0].re;
|
|
42080
|
-
const c1 = tuple.ops[1].re;
|
|
42081
|
-
const c2 = tuple.ops[2].re;
|
|
42082
|
-
const alpha = tuple.ops.length >= 4 ? tuple.ops[3].re : void 0;
|
|
42083
42555
|
const space = isString(ops[1]) ? ops[1].string?.toLowerCase() : void 0;
|
|
42084
42556
|
if (!space) return ce.error("incompatible-type");
|
|
42557
|
+
let c0, c1, c2;
|
|
42558
|
+
let alpha;
|
|
42559
|
+
const arg = ops[0];
|
|
42560
|
+
const typed = readColorExpr(arg);
|
|
42561
|
+
if (typed) {
|
|
42562
|
+
c0 = typed.c0;
|
|
42563
|
+
c1 = typed.c1;
|
|
42564
|
+
c2 = typed.c2;
|
|
42565
|
+
alpha = typed.alpha;
|
|
42566
|
+
} else if (isFunction2(arg) && arg.operator === "Tuple" && arg.ops.length >= 3) {
|
|
42567
|
+
c0 = arg.ops[0].re;
|
|
42568
|
+
c1 = arg.ops[1].re;
|
|
42569
|
+
c2 = arg.ops[2].re;
|
|
42570
|
+
alpha = arg.ops.length >= 4 ? arg.ops[3].re : void 0;
|
|
42571
|
+
} else {
|
|
42572
|
+
return ce.error("incompatible-type");
|
|
42573
|
+
}
|
|
42085
42574
|
let rgb;
|
|
42086
42575
|
switch (space) {
|
|
42087
42576
|
case "rgb":
|
|
@@ -42117,7 +42606,7 @@ ${e.message}
|
|
|
42117
42606
|
ColorContrast: {
|
|
42118
42607
|
description: "APCA contrast ratio between two colors",
|
|
42119
42608
|
complexity: 8e3,
|
|
42120
|
-
signature: "(
|
|
42609
|
+
signature: "(color | string | tuple, color | string | tuple) -> number",
|
|
42121
42610
|
evaluate: (ops, { engine: ce }) => {
|
|
42122
42611
|
const bgRgb = extractRgb(ce, ops[0]);
|
|
42123
42612
|
const fgRgb = extractRgb(ce, ops[1]);
|
|
@@ -42128,19 +42617,186 @@ ${e.message}
|
|
|
42128
42617
|
ContrastingColor: {
|
|
42129
42618
|
description: "Choose the foreground color with better APCA contrast against a background",
|
|
42130
42619
|
complexity: 8e3,
|
|
42131
|
-
signature: "(
|
|
42620
|
+
signature: "(color | string | tuple, (color | string | tuple)?, (color | string | tuple)?) -> color",
|
|
42132
42621
|
evaluate: (ops, { engine: ce }) => {
|
|
42133
42622
|
const bgRgb = extractRgb(ce, ops[0]);
|
|
42134
42623
|
if (!bgRgb) return ce.error("incompatible-type");
|
|
42624
|
+
let packed;
|
|
42135
42625
|
if (ops.length >= 3 && ops[1] !== void 0 && ops[2] !== void 0) {
|
|
42136
42626
|
const fg1 = extractRgb(ce, ops[1]);
|
|
42137
42627
|
const fg2 = extractRgb(ce, ops[2]);
|
|
42138
42628
|
if (!fg1 || !fg2) return ce.error("incompatible-type");
|
|
42139
|
-
|
|
42140
|
-
|
|
42629
|
+
packed = contrastingColor({ bg: bgRgb, fg1, fg2 });
|
|
42630
|
+
} else {
|
|
42631
|
+
packed = contrastingColor(bgRgb);
|
|
42632
|
+
}
|
|
42633
|
+
const r = (packed >>> 24 & 255) / 255;
|
|
42634
|
+
const g = (packed >>> 16 & 255) / 255;
|
|
42635
|
+
const b = (packed >>> 8 & 255) / 255;
|
|
42636
|
+
const alpha = normalizeAlpha((packed & 255) / 255);
|
|
42637
|
+
const args = [ce.number(r), ce.number(g), ce.number(b)];
|
|
42638
|
+
if (alpha !== void 0) args.push(ce.number(alpha));
|
|
42639
|
+
return ce.function("Rgb", args);
|
|
42640
|
+
}
|
|
42641
|
+
},
|
|
42642
|
+
// ---------------------------------------------------------------------------
|
|
42643
|
+
// Color constructors. Each preserves its colorspace on evaluation; the
|
|
42644
|
+
// operator name is the discriminator. Components are interpreted per
|
|
42645
|
+
// colorspace conventions (Rgb channels 0-1, Hsv/Hsl hue in degrees with
|
|
42646
|
+
// sat/value 0-1, Oklab/Oklch L 0-1 with standard a/b/C/H ranges). The
|
|
42647
|
+
// optional 4th argument is alpha in [0, 1]. No clamping at evaluation time.
|
|
42648
|
+
// ---------------------------------------------------------------------------
|
|
42649
|
+
Rgb: {
|
|
42650
|
+
description: "sRGB color (channels 0-1, optional alpha 0-1)",
|
|
42651
|
+
complexity: 8e3,
|
|
42652
|
+
signature: "(number, number, number, number?) -> color"
|
|
42653
|
+
},
|
|
42654
|
+
Hsv: {
|
|
42655
|
+
description: "HSV color (hue degrees, saturation/value 0-1, optional alpha)",
|
|
42656
|
+
complexity: 8e3,
|
|
42657
|
+
signature: "(number, number, number, number?) -> color"
|
|
42658
|
+
},
|
|
42659
|
+
Hsl: {
|
|
42660
|
+
description: "HSL color (hue degrees, saturation/lightness 0-1, optional alpha)",
|
|
42661
|
+
complexity: 8e3,
|
|
42662
|
+
signature: "(number, number, number, number?) -> color"
|
|
42663
|
+
},
|
|
42664
|
+
Oklab: {
|
|
42665
|
+
description: "OKLab color (L 0-1, a/b ~ -0.4..0.4, optional alpha)",
|
|
42666
|
+
complexity: 8e3,
|
|
42667
|
+
signature: "(number, number, number, number?) -> color"
|
|
42668
|
+
},
|
|
42669
|
+
Oklch: {
|
|
42670
|
+
description: "OKLCh color (L 0-1, C 0-~0.4, hue degrees, optional alpha)",
|
|
42671
|
+
complexity: 8e3,
|
|
42672
|
+
signature: "(number, number, number, number?) -> color"
|
|
42673
|
+
},
|
|
42674
|
+
// ---------------------------------------------------------------------------
|
|
42675
|
+
// Color-space conversions. Each accepts any of the five color heads and
|
|
42676
|
+
// returns the same color in the named space. If the input is already in
|
|
42677
|
+
// the target space, returns the input unchanged.
|
|
42678
|
+
// ---------------------------------------------------------------------------
|
|
42679
|
+
AsRgb: {
|
|
42680
|
+
description: "Convert any color to sRGB (channels 0-1)",
|
|
42681
|
+
complexity: 8e3,
|
|
42682
|
+
signature: "(color) -> color",
|
|
42683
|
+
evaluate: (ops, { engine: ce }) => {
|
|
42684
|
+
const arg = ops[0];
|
|
42685
|
+
if (isFunction2(arg) && arg.operator === "Rgb")
|
|
42686
|
+
return normalizeColorHead(ce, arg);
|
|
42687
|
+
const rgb = colorExprToRgb(arg);
|
|
42688
|
+
if (!rgb) return ce.error("incompatible-type");
|
|
42689
|
+
const args = [
|
|
42690
|
+
ce.number(rgb.r / 255),
|
|
42691
|
+
ce.number(rgb.g / 255),
|
|
42692
|
+
ce.number(rgb.b / 255)
|
|
42693
|
+
];
|
|
42694
|
+
if (rgb.alpha !== void 0) args.push(ce.number(rgb.alpha));
|
|
42695
|
+
return ce.function("Rgb", args);
|
|
42696
|
+
}
|
|
42697
|
+
},
|
|
42698
|
+
AsHsv: {
|
|
42699
|
+
description: "Convert any color to HSV (hue degrees, s/v 0-1)",
|
|
42700
|
+
complexity: 8e3,
|
|
42701
|
+
signature: "(color) -> color",
|
|
42702
|
+
evaluate: (ops, { engine: ce }) => {
|
|
42703
|
+
const arg = ops[0];
|
|
42704
|
+
if (isFunction2(arg) && arg.operator === "Hsv")
|
|
42705
|
+
return normalizeColorHead(ce, arg);
|
|
42706
|
+
const rgb = colorExprToRgb(arg);
|
|
42707
|
+
if (!rgb) return ce.error("incompatible-type");
|
|
42708
|
+
const hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
|
|
42709
|
+
const args = [ce.number(hsv.h), ce.number(hsv.s), ce.number(hsv.v)];
|
|
42710
|
+
if (rgb.alpha !== void 0) args.push(ce.number(rgb.alpha));
|
|
42711
|
+
return ce.function("Hsv", args);
|
|
42712
|
+
}
|
|
42713
|
+
},
|
|
42714
|
+
AsHsl: {
|
|
42715
|
+
description: "Convert any color to HSL (hue degrees, s/l 0-1)",
|
|
42716
|
+
complexity: 8e3,
|
|
42717
|
+
signature: "(color) -> color",
|
|
42718
|
+
evaluate: (ops, { engine: ce }) => {
|
|
42719
|
+
const arg = ops[0];
|
|
42720
|
+
if (isFunction2(arg) && arg.operator === "Hsl")
|
|
42721
|
+
return normalizeColorHead(ce, arg);
|
|
42722
|
+
const rgb = colorExprToRgb(arg);
|
|
42723
|
+
if (!rgb) return ce.error("incompatible-type");
|
|
42724
|
+
const hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);
|
|
42725
|
+
const args = [ce.number(hsl.h), ce.number(hsl.s), ce.number(hsl.l)];
|
|
42726
|
+
if (rgb.alpha !== void 0) args.push(ce.number(rgb.alpha));
|
|
42727
|
+
return ce.function("Hsl", args);
|
|
42728
|
+
}
|
|
42729
|
+
},
|
|
42730
|
+
AsOklab: {
|
|
42731
|
+
description: "Convert any color to OKLab",
|
|
42732
|
+
complexity: 8e3,
|
|
42733
|
+
signature: "(color) -> color",
|
|
42734
|
+
evaluate: (ops, { engine: ce }) => {
|
|
42735
|
+
const arg = ops[0];
|
|
42736
|
+
if (isFunction2(arg) && arg.operator === "Oklab")
|
|
42737
|
+
return normalizeColorHead(ce, arg);
|
|
42738
|
+
if (isFunction2(arg) && arg.operator === "Oklch") {
|
|
42739
|
+
const c = readColorExpr(arg);
|
|
42740
|
+
if (!c) return ce.error("incompatible-type");
|
|
42741
|
+
const lab2 = oklchToOklab({ L: c.c0, C: c.c1, H: c.c2, alpha: c.alpha });
|
|
42742
|
+
const args2 = [ce.number(lab2.L), ce.number(lab2.a), ce.number(lab2.b)];
|
|
42743
|
+
if (lab2.alpha !== void 0) args2.push(ce.number(lab2.alpha));
|
|
42744
|
+
return ce.function("Oklab", args2);
|
|
42745
|
+
}
|
|
42746
|
+
const rgb = colorExprToRgb(arg);
|
|
42747
|
+
if (!rgb) return ce.error("incompatible-type");
|
|
42748
|
+
const lab = rgbToOklab(rgb);
|
|
42749
|
+
const args = [ce.number(lab.L), ce.number(lab.a), ce.number(lab.b)];
|
|
42750
|
+
if (rgb.alpha !== void 0) args.push(ce.number(rgb.alpha));
|
|
42751
|
+
return ce.function("Oklab", args);
|
|
42752
|
+
}
|
|
42753
|
+
},
|
|
42754
|
+
AsOklch: {
|
|
42755
|
+
description: "Convert any color to OKLCh",
|
|
42756
|
+
complexity: 8e3,
|
|
42757
|
+
signature: "(color) -> color",
|
|
42758
|
+
evaluate: (ops, { engine: ce }) => {
|
|
42759
|
+
const arg = ops[0];
|
|
42760
|
+
if (isFunction2(arg) && arg.operator === "Oklch")
|
|
42761
|
+
return normalizeColorHead(ce, arg);
|
|
42762
|
+
if (isFunction2(arg) && arg.operator === "Oklab") {
|
|
42763
|
+
const c2 = readColorExpr(arg);
|
|
42764
|
+
if (!c2) return ce.error("incompatible-type");
|
|
42765
|
+
const oklch2 = oklabToOklch({
|
|
42766
|
+
L: c2.c0,
|
|
42767
|
+
a: c2.c1,
|
|
42768
|
+
b: c2.c2,
|
|
42769
|
+
alpha: c2.alpha
|
|
42770
|
+
});
|
|
42771
|
+
const args2 = [
|
|
42772
|
+
ce.number(oklch2.L),
|
|
42773
|
+
ce.number(oklch2.C),
|
|
42774
|
+
ce.number(oklch2.H)
|
|
42775
|
+
];
|
|
42776
|
+
if (oklch2.alpha !== void 0) args2.push(ce.number(oklch2.alpha));
|
|
42777
|
+
return ce.function("Oklch", args2);
|
|
42141
42778
|
}
|
|
42142
|
-
const
|
|
42143
|
-
return
|
|
42779
|
+
const rgb = colorExprToRgb(arg);
|
|
42780
|
+
if (!rgb) return ce.error("incompatible-type");
|
|
42781
|
+
const c = rgbToOklch(rgb);
|
|
42782
|
+
const args = [ce.number(c.L), ce.number(c.C), ce.number(c.H)];
|
|
42783
|
+
if (rgb.alpha !== void 0) args.push(ce.number(rgb.alpha));
|
|
42784
|
+
return ce.function("Oklch", args);
|
|
42785
|
+
}
|
|
42786
|
+
},
|
|
42787
|
+
// ---------------------------------------------------------------------------
|
|
42788
|
+
// Perceptual difference. Returns ΔE_OK (Euclidean distance in OKLab),
|
|
42789
|
+
// an approximately perceptually uniform scalar.
|
|
42790
|
+
// ---------------------------------------------------------------------------
|
|
42791
|
+
ColorDelta: {
|
|
42792
|
+
description: "Perceptual color difference (\u0394E_OK) between two colors",
|
|
42793
|
+
complexity: 8e3,
|
|
42794
|
+
signature: "(color | string | tuple, color | string | tuple) -> number",
|
|
42795
|
+
evaluate: (ops, { engine: ce }) => {
|
|
42796
|
+
const a = toOklch(ce, ops[0]);
|
|
42797
|
+
const b = toOklch(ce, ops[1]);
|
|
42798
|
+
if (!a || !b) return ce.error("incompatible-type");
|
|
42799
|
+
return ce.number(oklabDeltaE(oklchToOklab(a), oklchToOklab(b)));
|
|
42144
42800
|
}
|
|
42145
42801
|
}
|
|
42146
42802
|
};
|
|
@@ -42160,12 +42816,14 @@ ${e.message}
|
|
|
42160
42816
|
canonical: canonicalBlock,
|
|
42161
42817
|
evaluate: evaluateBlock
|
|
42162
42818
|
},
|
|
42163
|
-
// A condition expression tests for one or more conditions of an expression
|
|
42164
|
-
//
|
|
42819
|
+
// A condition expression tests for one or more conditions of an expression.
|
|
42820
|
+
// Two forms:
|
|
42821
|
+
// ['Condition', value, "positive"] — tests value against named condition(s)
|
|
42822
|
+
// ['Condition', predicate] — set-builder predicate (e.g. x > 0)
|
|
42165
42823
|
Condition: {
|
|
42166
42824
|
description: "Test whether a value satisfies one or more conditions.",
|
|
42167
42825
|
lazy: true,
|
|
42168
|
-
signature: "(
|
|
42826
|
+
signature: "(expression, symbol?) -> boolean",
|
|
42169
42827
|
evaluate: ([value, conds], { engine }) => {
|
|
42170
42828
|
let conditions = [];
|
|
42171
42829
|
if (isSymbol2(conds)) {
|
|
@@ -44618,6 +45276,34 @@ ${e.message}
|
|
|
44618
45276
|
signature: "() -> expression",
|
|
44619
45277
|
evaluate: (_ops, { engine }) => engine.expr(randomExpression())
|
|
44620
45278
|
}
|
|
45279
|
+
},
|
|
45280
|
+
// ---------------------------------------------------------------------------
|
|
45281
|
+
// Opaque typed heads — registered so the names are in the standard set
|
|
45282
|
+
// (consumers can branch on the operator name); CE itself does not evaluate
|
|
45283
|
+
// them. Geometric primitives `Triangle`/`Sphere`/`Segment` and the action
|
|
45284
|
+
// arrow `To` (`a \to b`).
|
|
45285
|
+
// ---------------------------------------------------------------------------
|
|
45286
|
+
{
|
|
45287
|
+
Triangle: {
|
|
45288
|
+
description: "Triangle primitive \u2014 opaque typed head.",
|
|
45289
|
+
signature: "(any+) -> expression"
|
|
45290
|
+
},
|
|
45291
|
+
GeometricVector: {
|
|
45292
|
+
description: "Geometric vector (directed segment between two points) \u2014 opaque typed head. Distinct from the column-vector `Vector` operator.",
|
|
45293
|
+
signature: "(any, any) -> expression"
|
|
45294
|
+
},
|
|
45295
|
+
Sphere: {
|
|
45296
|
+
description: "Sphere primitive \u2014 opaque typed head.",
|
|
45297
|
+
signature: "(any+) -> expression"
|
|
45298
|
+
},
|
|
45299
|
+
Segment: {
|
|
45300
|
+
description: "Segment primitive \u2014 opaque typed head.",
|
|
45301
|
+
signature: "(any+) -> expression"
|
|
45302
|
+
},
|
|
45303
|
+
To: {
|
|
45304
|
+
description: "Action arrow / mapping (`a \\to b`) \u2014 opaque typed head.",
|
|
45305
|
+
signature: "(any, any) -> nothing"
|
|
45306
|
+
}
|
|
44621
45307
|
}
|
|
44622
45308
|
];
|
|
44623
45309
|
|
|
@@ -51754,6 +52440,7 @@ Error in definition of "${name}"`,
|
|
|
51754
52440
|
|
|
51755
52441
|
// src/compute-engine/boxed-expression/cache.ts
|
|
51756
52442
|
function cachedValue(v, generation, fn) {
|
|
52443
|
+
if (v.generation === generation && v.value !== null) return v.value;
|
|
51757
52444
|
v.generation = generation;
|
|
51758
52445
|
v.value = fn();
|
|
51759
52446
|
return v.value;
|
|
@@ -53531,6 +54218,12 @@ Error in definition of "${name}"`,
|
|
|
53531
54218
|
function _escapeJsonString(s) {
|
|
53532
54219
|
return s;
|
|
53533
54220
|
}
|
|
54221
|
+
function _serializeLatexMetadata(ce, expr2) {
|
|
54222
|
+
const syntax = ce.latexSyntax;
|
|
54223
|
+
const opts = ce.latexOptions;
|
|
54224
|
+
if (Object.keys(opts).length === 0) return syntax.serialize(expr2);
|
|
54225
|
+
return syntax.serialize(expr2, { ...opts });
|
|
54226
|
+
}
|
|
53534
54227
|
function serializeSubtract(ce, a, b, options, metadata) {
|
|
53535
54228
|
if (isNumber(a) && a.isNegative) {
|
|
53536
54229
|
const v = a.numericValue;
|
|
@@ -53835,7 +54528,7 @@ Error in definition of "${name}"`,
|
|
|
53835
54528
|
];
|
|
53836
54529
|
const md = { ...metadata ?? {} };
|
|
53837
54530
|
if (options.metadata.includes("latex") && ce.latexSyntax) {
|
|
53838
|
-
md.latex = _escapeJsonString(md.latex ?? ce
|
|
54531
|
+
md.latex = _escapeJsonString(md.latex ?? _serializeLatexMetadata(ce, fn));
|
|
53839
54532
|
} else md.latex = "";
|
|
53840
54533
|
if (!options.metadata.includes("wikidata")) md.wikidata = "";
|
|
53841
54534
|
if (!md.latex && !md.wikidata && options.shorthands.includes("function"))
|
|
@@ -53860,7 +54553,7 @@ Error in definition of "${name}"`,
|
|
|
53860
54553
|
}
|
|
53861
54554
|
metadata = { ...metadata };
|
|
53862
54555
|
if (options.metadata.includes("latex") && ce.latexSyntax) {
|
|
53863
|
-
metadata.latex = metadata.latex ?? ce
|
|
54556
|
+
metadata.latex = metadata.latex ?? _serializeLatexMetadata(ce, sym2);
|
|
53864
54557
|
if (metadata.latex !== void 0)
|
|
53865
54558
|
metadata.latex = _escapeJsonString(metadata.latex);
|
|
53866
54559
|
} else metadata.latex = void 0;
|
|
@@ -54022,7 +54715,7 @@ Error in definition of "${name}"`,
|
|
|
54022
54715
|
}
|
|
54023
54716
|
}
|
|
54024
54717
|
if (options.metadata.includes("latex") && ce.latexSyntax)
|
|
54025
|
-
metadata.latex = metadata.latex ?? ce
|
|
54718
|
+
metadata.latex = metadata.latex ?? _serializeLatexMetadata(ce, result2 ?? { num });
|
|
54026
54719
|
if (result2) {
|
|
54027
54720
|
if (metadata.latex !== void 0)
|
|
54028
54721
|
return { sym: result2, latex: metadata.latex };
|
|
@@ -54038,7 +54731,7 @@ Error in definition of "${name}"`,
|
|
|
54038
54731
|
if (value.isNaN()) {
|
|
54039
54732
|
num = "NaN";
|
|
54040
54733
|
if (options.metadata.includes("latex") && ce.latexSyntax)
|
|
54041
|
-
metadata.latex = metadata.latex ?? ce
|
|
54734
|
+
metadata.latex = metadata.latex ?? _serializeLatexMetadata(ce, { num });
|
|
54042
54735
|
return metadata.latex !== void 0 ? { num, latex: metadata.latex } : { num };
|
|
54043
54736
|
}
|
|
54044
54737
|
return serializeJsonFunction(
|
|
@@ -54072,7 +54765,7 @@ Error in definition of "${name}"`,
|
|
|
54072
54765
|
value = Number(value);
|
|
54073
54766
|
} else {
|
|
54074
54767
|
if (options.metadata.includes("latex") && ce.latexSyntax)
|
|
54075
|
-
metadata.latex = metadata.latex ?? ce
|
|
54768
|
+
metadata.latex = metadata.latex ?? _serializeLatexMetadata(ce, {
|
|
54076
54769
|
num: value.toString()
|
|
54077
54770
|
});
|
|
54078
54771
|
if (metadata.latex !== void 0)
|
|
@@ -54086,7 +54779,7 @@ Error in definition of "${name}"`,
|
|
|
54086
54779
|
result = value > 0 ? "PositiveInfinity" : "NegativeInfinity";
|
|
54087
54780
|
else num = serializeRepeatingDecimals(value.toString(), options);
|
|
54088
54781
|
if (options.metadata.includes("latex") && ce.latexSyntax)
|
|
54089
|
-
metadata.latex = metadata.latex ?? ce
|
|
54782
|
+
metadata.latex = metadata.latex ?? _serializeLatexMetadata(ce, { num });
|
|
54090
54783
|
if (result) {
|
|
54091
54784
|
if (metadata.latex !== void 0)
|
|
54092
54785
|
return { sym: result, latex: metadata.latex };
|
|
@@ -54839,8 +55532,7 @@ Error in definition of "${name}"`,
|
|
|
54839
55532
|
vars: options?.vars,
|
|
54840
55533
|
imports: options?.imports,
|
|
54841
55534
|
preamble: options?.preamble,
|
|
54842
|
-
realOnly: options?.realOnly
|
|
54843
|
-
hints: options?.hints
|
|
55535
|
+
realOnly: options?.realOnly
|
|
54844
55536
|
});
|
|
54845
55537
|
} catch (e) {
|
|
54846
55538
|
if (options?.fallback ?? true) {
|
|
@@ -54852,8 +55544,7 @@ Error in definition of "${name}"`,
|
|
|
54852
55544
|
ce.pushScope();
|
|
54853
55545
|
try {
|
|
54854
55546
|
if (vars && typeof vars === "object") {
|
|
54855
|
-
for (const [k, v] of Object.entries(vars))
|
|
54856
|
-
ce.assign(k, v);
|
|
55547
|
+
for (const [k, v] of Object.entries(vars)) ce.assign(k, v);
|
|
54857
55548
|
}
|
|
54858
55549
|
return expr2.evaluate().re;
|
|
54859
55550
|
} finally {
|
|
@@ -60083,8 +60774,7 @@ Error in definition of "${name}"`,
|
|
|
60083
60774
|
return { re: null, im: formatFloat(iScale) };
|
|
60084
60775
|
}
|
|
60085
60776
|
const compiledFactors = remaining.map((r) => compile3(r));
|
|
60086
|
-
if (iScale !== 1)
|
|
60087
|
-
compiledFactors.unshift(formatFloat(iScale));
|
|
60777
|
+
if (iScale !== 1) compiledFactors.unshift(formatFloat(iScale));
|
|
60088
60778
|
const imCode = foldTerms(compiledFactors, "1.0", "*");
|
|
60089
60779
|
return { re: null, im: imCode };
|
|
60090
60780
|
}
|
|
@@ -60688,39 +61378,130 @@ Error in definition of "${name}"`,
|
|
|
60688
61378
|
if (args.length >= 2)
|
|
60689
61379
|
return `_SYS.colormap(${compile3(args[0])}, ${compile3(args[1])})`;
|
|
60690
61380
|
return `_SYS.colormap(${compile3(args[0])})`;
|
|
61381
|
+
},
|
|
61382
|
+
// -----------------------------------------------------------------------
|
|
61383
|
+
// Color constructor heads. All compile to OKLCh arrays at runtime — the
|
|
61384
|
+
// canonical color representation in this target. The constructors take
|
|
61385
|
+
// their own colorspace's components and convert internally.
|
|
61386
|
+
// (Mirrors the GPU target's design: color values are vec3 OKLCh.)
|
|
61387
|
+
// -----------------------------------------------------------------------
|
|
61388
|
+
Rgb: (args, compile3) => {
|
|
61389
|
+
if (args.length < 3) throw new Error("Rgb: need 3 components");
|
|
61390
|
+
return `_SYS.rgb(${args.map(compile3).join(", ")})`;
|
|
61391
|
+
},
|
|
61392
|
+
Hsv: (args, compile3) => {
|
|
61393
|
+
if (args.length < 3) throw new Error("Hsv: need 3 components");
|
|
61394
|
+
return `_SYS.hsv(${args.map(compile3).join(", ")})`;
|
|
61395
|
+
},
|
|
61396
|
+
Hsl: (args, compile3) => {
|
|
61397
|
+
if (args.length < 3) throw new Error("Hsl: need 3 components");
|
|
61398
|
+
return `_SYS.hsl(${args.map(compile3).join(", ")})`;
|
|
61399
|
+
},
|
|
61400
|
+
Oklab: (args, compile3) => {
|
|
61401
|
+
if (args.length < 3) throw new Error("Oklab: need 3 components");
|
|
61402
|
+
return `_SYS.oklab(${args.map(compile3).join(", ")})`;
|
|
61403
|
+
},
|
|
61404
|
+
Oklch: (args, compile3) => {
|
|
61405
|
+
if (args.length < 3) throw new Error("Oklch: need 3 components");
|
|
61406
|
+
return `_SYS.oklch(${args.map(compile3).join(", ")})`;
|
|
61407
|
+
},
|
|
61408
|
+
// -----------------------------------------------------------------------
|
|
61409
|
+
// As* converters. Compile-time output convention matches the engine and
|
|
61410
|
+
// the GPU target: each returns components in the named space as a 3- or
|
|
61411
|
+
// 4-element array. `AsRgb` uses 0-1 sRGB channels (consistent across all
|
|
61412
|
+
// layers). `AsOklch` is the identity (canonical form).
|
|
61413
|
+
// -----------------------------------------------------------------------
|
|
61414
|
+
AsRgb: ([c], compile3) => {
|
|
61415
|
+
if (c === null) throw new Error("AsRgb: no argument");
|
|
61416
|
+
return `_SYS.asRgb(${compile3(c)})`;
|
|
61417
|
+
},
|
|
61418
|
+
AsHsv: ([c], compile3) => {
|
|
61419
|
+
if (c === null) throw new Error("AsHsv: no argument");
|
|
61420
|
+
return `_SYS.asHsv(${compile3(c)})`;
|
|
61421
|
+
},
|
|
61422
|
+
AsHsl: ([c], compile3) => {
|
|
61423
|
+
if (c === null) throw new Error("AsHsl: no argument");
|
|
61424
|
+
return `_SYS.asHsl(${compile3(c)})`;
|
|
61425
|
+
},
|
|
61426
|
+
AsOklab: ([c], compile3) => {
|
|
61427
|
+
if (c === null) throw new Error("AsOklab: no argument");
|
|
61428
|
+
return `_SYS.asOklab(${compile3(c)})`;
|
|
61429
|
+
},
|
|
61430
|
+
AsOklch: ([c], compile3) => {
|
|
61431
|
+
if (c === null) throw new Error("AsOklch: no argument");
|
|
61432
|
+
return compile3(c);
|
|
61433
|
+
},
|
|
61434
|
+
// Perceptual color difference (ΔE_OK).
|
|
61435
|
+
ColorDelta: ([a, b], compile3) => {
|
|
61436
|
+
if (a === null || b === null)
|
|
61437
|
+
throw new Error("ColorDelta: need two colors");
|
|
61438
|
+
return `_SYS.colorDelta(${compile3(a)}, ${compile3(b)})`;
|
|
61439
|
+
},
|
|
61440
|
+
// Euclidean distance between two tuples (any positive dimension).
|
|
61441
|
+
// The GPU target maps `Distance` to the GLSL/WGSL `distance()` builtin
|
|
61442
|
+
// (vec-only); this JS handler works on plain arrays of any length.
|
|
61443
|
+
Distance: ([a, b], compile3) => {
|
|
61444
|
+
if (a === null || b === null) throw new Error("Distance: need two points");
|
|
61445
|
+
return `_SYS.distance(${compile3(a)}, ${compile3(b)})`;
|
|
60691
61446
|
}
|
|
60692
61447
|
};
|
|
60693
61448
|
function toRI(c) {
|
|
60694
61449
|
return { re: c.re, im: c.im };
|
|
60695
61450
|
}
|
|
61451
|
+
function normalizeAlpha2(a) {
|
|
61452
|
+
if (a === void 0) return void 0;
|
|
61453
|
+
if (!Number.isFinite(a)) return void 0;
|
|
61454
|
+
if (Math.abs(a - 1) < 1e-9) return void 0;
|
|
61455
|
+
return a;
|
|
61456
|
+
}
|
|
60696
61457
|
function toRgb255(input) {
|
|
60697
61458
|
if (typeof input === "string") {
|
|
60698
61459
|
const c = parseColor(input);
|
|
60699
|
-
|
|
61460
|
+
const rgb2 = {
|
|
60700
61461
|
r: c >>> 24 & 255,
|
|
60701
61462
|
g: c >>> 16 & 255,
|
|
60702
|
-
b: c >>> 8 & 255
|
|
60703
|
-
alpha: (c & 255) / 255
|
|
61463
|
+
b: c >>> 8 & 255
|
|
60704
61464
|
};
|
|
61465
|
+
const alpha = normalizeAlpha2((c & 255) / 255);
|
|
61466
|
+
if (alpha !== void 0) rgb2.alpha = alpha;
|
|
61467
|
+
return rgb2;
|
|
61468
|
+
}
|
|
61469
|
+
const rgb = oklchToRgb({ L: input[0], C: input[1], H: input[2] });
|
|
61470
|
+
if (input.length >= 4) {
|
|
61471
|
+
const alpha = normalizeAlpha2(input[3]);
|
|
61472
|
+
if (alpha !== void 0) rgb.alpha = alpha;
|
|
60705
61473
|
}
|
|
60706
|
-
const rgb = {
|
|
60707
|
-
r: input[0] * 255,
|
|
60708
|
-
g: input[1] * 255,
|
|
60709
|
-
b: input[2] * 255
|
|
60710
|
-
};
|
|
60711
|
-
if (input.length >= 4) rgb.alpha = input[3];
|
|
60712
61474
|
return rgb;
|
|
60713
61475
|
}
|
|
60714
|
-
function
|
|
60715
|
-
|
|
60716
|
-
|
|
60717
|
-
|
|
60718
|
-
|
|
60719
|
-
|
|
61476
|
+
function toOklch2(input) {
|
|
61477
|
+
if (typeof input === "string") {
|
|
61478
|
+
const c = parseColor(input);
|
|
61479
|
+
const r = c >>> 24 & 255;
|
|
61480
|
+
const g = c >>> 16 & 255;
|
|
61481
|
+
const b = c >>> 8 & 255;
|
|
61482
|
+
const oklch2 = rgbToOklch({ r, g, b });
|
|
61483
|
+
const alpha = normalizeAlpha2((c & 255) / 255);
|
|
61484
|
+
if (alpha !== void 0) oklch2.alpha = alpha;
|
|
61485
|
+
return oklch2;
|
|
61486
|
+
}
|
|
61487
|
+
return {
|
|
61488
|
+
L: input[0],
|
|
61489
|
+
C: input[1],
|
|
61490
|
+
H: input[2],
|
|
61491
|
+
alpha: input.length >= 4 ? normalizeAlpha2(input[3]) : void 0
|
|
61492
|
+
};
|
|
61493
|
+
}
|
|
61494
|
+
function packedToOklch(c) {
|
|
61495
|
+
const r = c >>> 24 & 255;
|
|
61496
|
+
const g = c >>> 16 & 255;
|
|
61497
|
+
const b = c >>> 8 & 255;
|
|
61498
|
+
const oklch2 = rgbToOklch({ r, g, b });
|
|
61499
|
+
const alpha = normalizeAlpha2((c & 255) / 255);
|
|
61500
|
+
return alpha !== void 0 ? [oklch2.L, oklch2.C, oklch2.H, alpha] : [oklch2.L, oklch2.C, oklch2.H];
|
|
60720
61501
|
}
|
|
60721
61502
|
var colorHelpers = {
|
|
60722
61503
|
color(input) {
|
|
60723
|
-
return
|
|
61504
|
+
return packedToOklch(parseColor(input));
|
|
60724
61505
|
},
|
|
60725
61506
|
colorToString(input, format) {
|
|
60726
61507
|
const rgb = toRgb255(input);
|
|
@@ -60731,7 +61512,7 @@ Error in definition of "${name}"`,
|
|
|
60731
61512
|
const g = Math.round(Math.max(0, Math.min(255, rgb.g)));
|
|
60732
61513
|
const b = Math.round(Math.max(0, Math.min(255, rgb.b)));
|
|
60733
61514
|
let hex = `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
|
|
60734
|
-
if (rgb.alpha !== void 0
|
|
61515
|
+
if (rgb.alpha !== void 0) {
|
|
60735
61516
|
const a = Math.round(Math.max(0, Math.min(255, rgb.alpha * 255)));
|
|
60736
61517
|
hex += a.toString(16).padStart(2, "0");
|
|
60737
61518
|
}
|
|
@@ -60741,7 +61522,7 @@ Error in definition of "${name}"`,
|
|
|
60741
61522
|
const r = Math.round(rgb.r);
|
|
60742
61523
|
const g = Math.round(rgb.g);
|
|
60743
61524
|
const b = Math.round(rgb.b);
|
|
60744
|
-
if (rgb.alpha !== void 0
|
|
61525
|
+
if (rgb.alpha !== void 0)
|
|
60745
61526
|
return `rgb(${r} ${g} ${b} / ${rgb.alpha})`;
|
|
60746
61527
|
return `rgb(${r} ${g} ${b})`;
|
|
60747
61528
|
}
|
|
@@ -60750,7 +61531,7 @@ Error in definition of "${name}"`,
|
|
|
60750
61531
|
const h = Math.round(hsl.h * 10) / 10;
|
|
60751
61532
|
const s = Math.round(hsl.s * 1e3) / 10;
|
|
60752
61533
|
const l = Math.round(hsl.l * 1e3) / 10;
|
|
60753
|
-
if (rgb.alpha !== void 0
|
|
61534
|
+
if (rgb.alpha !== void 0)
|
|
60754
61535
|
return `hsl(${h} ${s}% ${l}% / ${rgb.alpha})`;
|
|
60755
61536
|
return `hsl(${h} ${s}% ${l}%)`;
|
|
60756
61537
|
}
|
|
@@ -60759,7 +61540,7 @@ Error in definition of "${name}"`,
|
|
|
60759
61540
|
const L = Math.round(c.L * 1e3) / 1e3;
|
|
60760
61541
|
const C = Math.round(c.C * 1e3) / 1e3;
|
|
60761
61542
|
const H = Math.round(c.H * 10) / 10;
|
|
60762
|
-
if (rgb.alpha !== void 0
|
|
61543
|
+
if (rgb.alpha !== void 0)
|
|
60763
61544
|
return `oklch(${L} ${C} ${H} / ${rgb.alpha})`;
|
|
60764
61545
|
return `oklch(${L} ${C} ${H})`;
|
|
60765
61546
|
}
|
|
@@ -60768,29 +61549,29 @@ Error in definition of "${name}"`,
|
|
|
60768
61549
|
}
|
|
60769
61550
|
},
|
|
60770
61551
|
colorMix(input1, input2, ratio = 0.5) {
|
|
60771
|
-
const
|
|
60772
|
-
const
|
|
61552
|
+
const c1 = toOklch2(input1);
|
|
61553
|
+
const c2 = toOklch2(input2);
|
|
60773
61554
|
ratio = Math.max(0, Math.min(1, ratio));
|
|
60774
|
-
const
|
|
60775
|
-
const
|
|
60776
|
-
let
|
|
60777
|
-
if (
|
|
60778
|
-
if (
|
|
60779
|
-
|
|
60780
|
-
|
|
60781
|
-
|
|
60782
|
-
|
|
60783
|
-
|
|
60784
|
-
|
|
60785
|
-
H
|
|
60786
|
-
|
|
60787
|
-
|
|
60788
|
-
const
|
|
60789
|
-
const
|
|
60790
|
-
const a1 =
|
|
60791
|
-
const a2 =
|
|
60792
|
-
const alpha = a1 + (a2 - a1) * ratio;
|
|
60793
|
-
return
|
|
61555
|
+
const c1Achromatic = c1.C < 1e-6;
|
|
61556
|
+
const c2Achromatic = c2.C < 1e-6;
|
|
61557
|
+
let H;
|
|
61558
|
+
if (c1Achromatic && c2Achromatic) H = c1.H;
|
|
61559
|
+
else if (c1Achromatic) H = c2.H;
|
|
61560
|
+
else if (c2Achromatic) H = c1.H;
|
|
61561
|
+
else {
|
|
61562
|
+
let dh = c2.H - c1.H;
|
|
61563
|
+
if (dh > 180) dh -= 360;
|
|
61564
|
+
if (dh < -180) dh += 360;
|
|
61565
|
+
H = c1.H + dh * ratio;
|
|
61566
|
+
if (H < 0) H += 360;
|
|
61567
|
+
if (H >= 360) H -= 360;
|
|
61568
|
+
}
|
|
61569
|
+
const L = c1.L + (c2.L - c1.L) * ratio;
|
|
61570
|
+
const C = c1.C + (c2.C - c1.C) * ratio;
|
|
61571
|
+
const a1 = c1.alpha ?? 1;
|
|
61572
|
+
const a2 = c2.alpha ?? 1;
|
|
61573
|
+
const alpha = normalizeAlpha2(a1 + (a2 - a1) * ratio);
|
|
61574
|
+
return alpha !== void 0 ? [L, C, H, alpha] : [L, C, H];
|
|
60794
61575
|
},
|
|
60795
61576
|
colorContrast(bg, fg) {
|
|
60796
61577
|
return apca(toRgb255(bg), toRgb255(fg));
|
|
@@ -60798,11 +61579,11 @@ Error in definition of "${name}"`,
|
|
|
60798
61579
|
contrastingColor(bg, fg1, fg2) {
|
|
60799
61580
|
const bgRgb = toRgb255(bg);
|
|
60800
61581
|
if (fg1 !== void 0 && fg2 !== void 0) {
|
|
60801
|
-
return
|
|
61582
|
+
return packedToOklch(
|
|
60802
61583
|
contrastingColor({ bg: bgRgb, fg1: toRgb255(fg1), fg2: toRgb255(fg2) })
|
|
60803
61584
|
);
|
|
60804
61585
|
}
|
|
60805
|
-
return
|
|
61586
|
+
return packedToOklch(contrastingColor(bgRgb));
|
|
60806
61587
|
},
|
|
60807
61588
|
colorToColorspace(input, space) {
|
|
60808
61589
|
const rgb = toRgb255(input);
|
|
@@ -60831,7 +61612,7 @@ Error in definition of "${name}"`,
|
|
|
60831
61612
|
default:
|
|
60832
61613
|
throw new Error(`Unknown color space: ${space}`);
|
|
60833
61614
|
}
|
|
60834
|
-
if (alpha !== void 0
|
|
61615
|
+
if (alpha !== void 0) result.push(alpha);
|
|
60835
61616
|
return result;
|
|
60836
61617
|
},
|
|
60837
61618
|
colormap(name, arg) {
|
|
@@ -60843,7 +61624,7 @@ Error in definition of "${name}"`,
|
|
|
60843
61624
|
const palette = allPalettes[name];
|
|
60844
61625
|
if (!palette) throw new Error(`Unknown palette: ${name}`);
|
|
60845
61626
|
const colors = palette.map(
|
|
60846
|
-
(hex) =>
|
|
61627
|
+
(hex) => packedToOklch(parseColor(hex))
|
|
60847
61628
|
);
|
|
60848
61629
|
if (arg === void 0) return colors;
|
|
60849
61630
|
if (Number.isInteger(arg) && arg >= 2) {
|
|
@@ -60867,62 +61648,128 @@ Error in definition of "${name}"`,
|
|
|
60867
61648
|
const frac = pos - i;
|
|
60868
61649
|
if (frac === 0 || i >= colors.length - 1)
|
|
60869
61650
|
return [...colors[Math.min(i, colors.length - 1)]];
|
|
60870
|
-
const
|
|
60871
|
-
|
|
60872
|
-
|
|
60873
|
-
|
|
60874
|
-
|
|
60875
|
-
|
|
60876
|
-
|
|
60877
|
-
|
|
60878
|
-
|
|
60879
|
-
|
|
60880
|
-
|
|
60881
|
-
|
|
60882
|
-
|
|
60883
|
-
|
|
60884
|
-
|
|
60885
|
-
|
|
60886
|
-
|
|
60887
|
-
if (H >= 360) H -= 360;
|
|
60888
|
-
const mixed = oklchToRgb({
|
|
60889
|
-
L: c1.L + (c2.L - c1.L) * frac,
|
|
60890
|
-
C: c1.C + (c2.C - c1.C) * frac,
|
|
60891
|
-
H
|
|
60892
|
-
});
|
|
60893
|
-
return [mixed.r / 255, mixed.g / 255, mixed.b / 255];
|
|
61651
|
+
const [L1, C1, H1] = colors[i];
|
|
61652
|
+
const [L2, C2, H2] = colors[i + 1];
|
|
61653
|
+
const c1Achromatic = C1 < 1e-6;
|
|
61654
|
+
const c2Achromatic = C2 < 1e-6;
|
|
61655
|
+
let H;
|
|
61656
|
+
if (c1Achromatic && c2Achromatic) H = H1;
|
|
61657
|
+
else if (c1Achromatic) H = H2;
|
|
61658
|
+
else if (c2Achromatic) H = H1;
|
|
61659
|
+
else {
|
|
61660
|
+
let dh = H2 - H1;
|
|
61661
|
+
if (dh > 180) dh -= 360;
|
|
61662
|
+
if (dh < -180) dh += 360;
|
|
61663
|
+
H = H1 + dh * frac;
|
|
61664
|
+
if (H < 0) H += 360;
|
|
61665
|
+
if (H >= 360) H -= 360;
|
|
61666
|
+
}
|
|
61667
|
+
return [L1 + (L2 - L1) * frac, C1 + (C2 - C1) * frac, H];
|
|
60894
61668
|
},
|
|
60895
61669
|
colorFromColorspace(components, space) {
|
|
60896
61670
|
const c0 = components[0];
|
|
60897
61671
|
const c1 = components[1];
|
|
60898
61672
|
const c2 = components[2];
|
|
60899
61673
|
const alpha = components.length >= 4 ? components[3] : void 0;
|
|
60900
|
-
let
|
|
61674
|
+
let oklch2;
|
|
60901
61675
|
switch (space.toLowerCase()) {
|
|
60902
61676
|
case "rgb":
|
|
60903
|
-
|
|
61677
|
+
oklch2 = rgbToOklch({ r: c0 * 255, g: c1 * 255, b: c2 * 255 });
|
|
60904
61678
|
break;
|
|
60905
61679
|
case "hsl": {
|
|
60906
|
-
const
|
|
60907
|
-
|
|
61680
|
+
const rgb = hslToRgb(c0, c1, c2);
|
|
61681
|
+
oklch2 = rgbToOklch(rgb);
|
|
60908
61682
|
break;
|
|
60909
61683
|
}
|
|
60910
|
-
case "oklch":
|
|
60911
|
-
|
|
60912
|
-
result = [r.r / 255, r.g / 255, r.b / 255];
|
|
61684
|
+
case "oklch":
|
|
61685
|
+
oklch2 = { L: c0, C: c1, H: c2 };
|
|
60913
61686
|
break;
|
|
60914
|
-
}
|
|
60915
61687
|
case "oklab":
|
|
60916
|
-
case "lab":
|
|
60917
|
-
|
|
60918
|
-
result = [r.r / 255, r.g / 255, r.b / 255];
|
|
61688
|
+
case "lab":
|
|
61689
|
+
oklch2 = oklabToOklch({ L: c0, a: c1, b: c2 });
|
|
60919
61690
|
break;
|
|
60920
|
-
}
|
|
60921
61691
|
default:
|
|
60922
61692
|
throw new Error(`Unknown color space: ${space}`);
|
|
60923
61693
|
}
|
|
60924
|
-
|
|
60925
|
-
|
|
61694
|
+
return alpha !== void 0 ? [oklch2.L, oklch2.C, oklch2.H, alpha] : [oklch2.L, oklch2.C, oklch2.H];
|
|
61695
|
+
},
|
|
61696
|
+
// -----------------------------------------------------------------------
|
|
61697
|
+
// Color constructors. Each accepts components in its colorspace's natural
|
|
61698
|
+
// units and returns the canonical OKLCh array `[L, C, H]` (or with alpha).
|
|
61699
|
+
// -----------------------------------------------------------------------
|
|
61700
|
+
rgb(r, g, b, alpha) {
|
|
61701
|
+
const c = rgbToOklch({ r: r * 255, g: g * 255, b: b * 255 });
|
|
61702
|
+
const a = normalizeAlpha2(alpha);
|
|
61703
|
+
return a !== void 0 ? [c.L, c.C, c.H, a] : [c.L, c.C, c.H];
|
|
61704
|
+
},
|
|
61705
|
+
hsv(h, s, v, alpha) {
|
|
61706
|
+
const rgb = hsvToRgb(h, s, v);
|
|
61707
|
+
const c = rgbToOklch(rgb);
|
|
61708
|
+
const a = normalizeAlpha2(alpha);
|
|
61709
|
+
return a !== void 0 ? [c.L, c.C, c.H, a] : [c.L, c.C, c.H];
|
|
61710
|
+
},
|
|
61711
|
+
hsl(h, s, l, alpha) {
|
|
61712
|
+
const rgb = hslToRgb(h, s, l);
|
|
61713
|
+
const c = rgbToOklch({ r: rgb.r, g: rgb.g, b: rgb.b });
|
|
61714
|
+
const a = normalizeAlpha2(alpha);
|
|
61715
|
+
return a !== void 0 ? [c.L, c.C, c.H, a] : [c.L, c.C, c.H];
|
|
61716
|
+
},
|
|
61717
|
+
oklab(L, a, b, alpha) {
|
|
61718
|
+
const c = oklabToOklch({ L, a, b });
|
|
61719
|
+
const al = normalizeAlpha2(alpha);
|
|
61720
|
+
return al !== void 0 ? [c.L, c.C, c.H, al] : [c.L, c.C, c.H];
|
|
61721
|
+
},
|
|
61722
|
+
oklch(L, C, H, alpha) {
|
|
61723
|
+
const a = normalizeAlpha2(alpha);
|
|
61724
|
+
return a !== void 0 ? [L, C, H, a] : [L, C, H];
|
|
61725
|
+
},
|
|
61726
|
+
// -----------------------------------------------------------------------
|
|
61727
|
+
// As* converters. Inputs are anything `toOklch` accepts (string, packed
|
|
61728
|
+
// int, or OKLCh array). Outputs are 3- or 4-element arrays in the named
|
|
61729
|
+
// space. sRGB-based outputs (asRgb/asHsv/asHsl) use 0-1 channels for
|
|
61730
|
+
// consistency with the GPU target's shader convention.
|
|
61731
|
+
// -----------------------------------------------------------------------
|
|
61732
|
+
asRgb(input) {
|
|
61733
|
+
const rgb = toRgb255(input);
|
|
61734
|
+
const r = rgb.r / 255;
|
|
61735
|
+
const g = rgb.g / 255;
|
|
61736
|
+
const b = rgb.b / 255;
|
|
61737
|
+
return rgb.alpha !== void 0 ? [r, g, b, rgb.alpha] : [r, g, b];
|
|
61738
|
+
},
|
|
61739
|
+
asHsv(input) {
|
|
61740
|
+
const rgb = toRgb255(input);
|
|
61741
|
+
const hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
|
|
61742
|
+
return rgb.alpha !== void 0 ? [hsv.h, hsv.s, hsv.v, rgb.alpha] : [hsv.h, hsv.s, hsv.v];
|
|
61743
|
+
},
|
|
61744
|
+
asHsl(input) {
|
|
61745
|
+
const rgb = toRgb255(input);
|
|
61746
|
+
const hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);
|
|
61747
|
+
return rgb.alpha !== void 0 ? [hsl.h, hsl.s, hsl.l, rgb.alpha] : [hsl.h, hsl.s, hsl.l];
|
|
61748
|
+
},
|
|
61749
|
+
asOklab(input) {
|
|
61750
|
+
const c = toOklch2(input);
|
|
61751
|
+
const lab = oklchToOklab({ L: c.L, C: c.C, H: c.H });
|
|
61752
|
+
return c.alpha !== void 0 ? [lab.L, lab.a, lab.b, c.alpha] : [lab.L, lab.a, lab.b];
|
|
61753
|
+
},
|
|
61754
|
+
// asOklch is identity — handled at compile time as a pass-through
|
|
61755
|
+
// Perceptual color difference (ΔE_OK).
|
|
61756
|
+
colorDelta(a, b) {
|
|
61757
|
+
const labA = oklchToOklab(toOklch2(a));
|
|
61758
|
+
const labB = oklchToOklab(toOklch2(b));
|
|
61759
|
+
return oklabDeltaE(labA, labB);
|
|
61760
|
+
},
|
|
61761
|
+
// Euclidean distance between two tuples. Plain numeric — not a color
|
|
61762
|
+
// operation despite living in the same helpers block.
|
|
61763
|
+
distance(a, b) {
|
|
61764
|
+
if (!Array.isArray(a) || !Array.isArray(b))
|
|
61765
|
+
throw new Error("Distance: expected two arrays");
|
|
61766
|
+
if (a.length !== b.length) throw new Error("Distance: dimension mismatch");
|
|
61767
|
+
let sumSq = 0;
|
|
61768
|
+
for (let i = 0; i < a.length; i++) {
|
|
61769
|
+
const d = a[i] - b[i];
|
|
61770
|
+
sumSq += d * d;
|
|
61771
|
+
}
|
|
61772
|
+
return Math.sqrt(sumSq);
|
|
60926
61773
|
}
|
|
60927
61774
|
};
|
|
60928
61775
|
var SYS_HELPERS = {
|
|
@@ -61340,43 +62187,6 @@ Error in definition of "${name}"`,
|
|
|
61340
62187
|
return b;
|
|
61341
62188
|
}
|
|
61342
62189
|
|
|
61343
|
-
// src/compute-engine/compilation/fractal-orbit.ts
|
|
61344
|
-
function toBigDecimal(v) {
|
|
61345
|
-
if (typeof v === "object" && "hi" in v)
|
|
61346
|
-
return new BigDecimal(v.hi).add(new BigDecimal(v.lo));
|
|
61347
|
-
return new BigDecimal(v);
|
|
61348
|
-
}
|
|
61349
|
-
function hpToNumber(v) {
|
|
61350
|
-
if (typeof v === "number") return v;
|
|
61351
|
-
if (typeof v === "string") return Number(v);
|
|
61352
|
-
return v.hi + v.lo;
|
|
61353
|
-
}
|
|
61354
|
-
function computeReferenceOrbit(center, maxIter, precision) {
|
|
61355
|
-
const prevPrecision = BigDecimal.precision;
|
|
61356
|
-
BigDecimal.precision = precision;
|
|
61357
|
-
try {
|
|
61358
|
-
const cr = toBigDecimal(center[0]);
|
|
61359
|
-
const ci = toBigDecimal(center[1]);
|
|
61360
|
-
let zr = BigDecimal.ZERO;
|
|
61361
|
-
let zi = BigDecimal.ZERO;
|
|
61362
|
-
const ESCAPE = new BigDecimal(256);
|
|
61363
|
-
const points = [];
|
|
61364
|
-
for (let i = 0; i < maxIter; i++) {
|
|
61365
|
-
points.push(zr.toNumber(), zi.toNumber());
|
|
61366
|
-
const zr2 = zr.mul(zr).toPrecision(precision);
|
|
61367
|
-
const zi2 = zi.mul(zi).toPrecision(precision);
|
|
61368
|
-
const mag2 = zr2.add(zi2);
|
|
61369
|
-
if (mag2.cmp(ESCAPE) > 0) break;
|
|
61370
|
-
const new_zi = zr.mul(zi).toPrecision(precision).mul(2).add(ci);
|
|
61371
|
-
zr = zr2.sub(zi2).add(cr);
|
|
61372
|
-
zi = new_zi;
|
|
61373
|
-
}
|
|
61374
|
-
return new Float32Array(points);
|
|
61375
|
-
} finally {
|
|
61376
|
-
BigDecimal.precision = prevPrecision;
|
|
61377
|
-
}
|
|
61378
|
-
}
|
|
61379
|
-
|
|
61380
62190
|
// src/compute-engine/compilation/gpu-target.ts
|
|
61381
62191
|
var GPU_OPERATORS = {
|
|
61382
62192
|
Add: ["+", 11],
|
|
@@ -61398,6 +62208,13 @@ Error in definition of "${name}"`,
|
|
|
61398
62208
|
function gpuVec2(target) {
|
|
61399
62209
|
return target?.language === "wgsl" ? "vec2f" : "vec2";
|
|
61400
62210
|
}
|
|
62211
|
+
function gpuVec3(target) {
|
|
62212
|
+
return target?.language === "wgsl" ? "vec3f" : "vec3";
|
|
62213
|
+
}
|
|
62214
|
+
function readStringLiteral(expr2) {
|
|
62215
|
+
if (!isString(expr2)) return null;
|
|
62216
|
+
return expr2.string?.toLowerCase() ?? null;
|
|
62217
|
+
}
|
|
61401
62218
|
function compileIntArg(expr2, compile3, target) {
|
|
61402
62219
|
const c = tryGetConstant(expr2);
|
|
61403
62220
|
if (c !== void 0 && Number.isInteger(c)) return c.toString();
|
|
@@ -61456,17 +62273,10 @@ Error in definition of "${name}"`,
|
|
|
61456
62273
|
`for (${indexDecl} = ${lowerStr}; ${index} <= ${upperStr}; ${index}++) {`,
|
|
61457
62274
|
` ${acc} ${op}= ${body};`,
|
|
61458
62275
|
`}`,
|
|
61459
|
-
`return ${acc}
|
|
62276
|
+
`return ${acc};`
|
|
61460
62277
|
];
|
|
61461
62278
|
return lines.join("\n");
|
|
61462
62279
|
}
|
|
61463
|
-
function selectFractalStrategy(target) {
|
|
61464
|
-
const radius = target.hints?.viewport?.radius;
|
|
61465
|
-
if (radius === void 0) return "single";
|
|
61466
|
-
if (radius > 1e-6) return "single";
|
|
61467
|
-
if (radius > 1e-14) return "double";
|
|
61468
|
-
return "perturbation";
|
|
61469
|
-
}
|
|
61470
62280
|
var GPU_FUNCTIONS = {
|
|
61471
62281
|
// Variadic arithmetic (for function-call form, e.g., with vectors)
|
|
61472
62282
|
Add: (args, compile3, target) => {
|
|
@@ -61517,8 +62327,7 @@ Error in definition of "${name}"`,
|
|
|
61517
62327
|
const iScale = isSymbol2(iFactor, "ImaginaryUnit") ? 1 : iFactor.im;
|
|
61518
62328
|
const realFactors = args.filter((_, i) => i !== iIndex);
|
|
61519
62329
|
const v2 = gpuVec2(target);
|
|
61520
|
-
if (realFactors.length === 0)
|
|
61521
|
-
return `${v2}(0.0, ${formatFloat(iScale)})`;
|
|
62330
|
+
if (realFactors.length === 0) return `${v2}(0.0, ${formatFloat(iScale)})`;
|
|
61522
62331
|
const factors = realFactors.map((f) => compile3(f));
|
|
61523
62332
|
if (iScale !== 1) factors.unshift(formatFloat(iScale));
|
|
61524
62333
|
const imCode = foldTerms(factors, "1.0", "*");
|
|
@@ -61571,8 +62380,7 @@ Error in definition of "${name}"`,
|
|
|
61571
62380
|
if (isNumber(x) && x.im !== 0) {
|
|
61572
62381
|
return `${gpuVec2(target)}(${formatFloat(-x.re)}, ${formatFloat(-x.im)})`;
|
|
61573
62382
|
}
|
|
61574
|
-
if (isSymbol2(x, "ImaginaryUnit"))
|
|
61575
|
-
return `${gpuVec2(target)}(0.0, -1.0)`;
|
|
62383
|
+
if (isSymbol2(x, "ImaginaryUnit")) return `${gpuVec2(target)}(0.0, -1.0)`;
|
|
61576
62384
|
return `(-${compile3(x)})`;
|
|
61577
62385
|
},
|
|
61578
62386
|
// Standard math functions with complex dispatch
|
|
@@ -61945,49 +62753,139 @@ Error in definition of "${name}"`,
|
|
|
61945
62753
|
}
|
|
61946
62754
|
const isWGSL = target?.language === "wgsl";
|
|
61947
62755
|
const v3 = isWGSL ? "vec3f" : "vec3";
|
|
61948
|
-
|
|
62756
|
+
const black = `${v3}(0.0)`;
|
|
62757
|
+
const white = `${v3}(1.0, 0.0, 0.0)`;
|
|
62758
|
+
return `((_gpu_apca(${bg}, ${black}) > 50.0) ? ${black} : ${white})`;
|
|
61949
62759
|
},
|
|
61950
62760
|
ColorToColorspace: ([color, space], compile3) => {
|
|
61951
62761
|
if (color === null || space === null)
|
|
61952
62762
|
throw new Error("ColorToColorspace: need color and space");
|
|
61953
|
-
|
|
62763
|
+
const spaceName = readStringLiteral(space);
|
|
62764
|
+
if (spaceName === null)
|
|
62765
|
+
throw new Error("ColorToColorspace: space must be a string literal");
|
|
62766
|
+
const c = compile3(color);
|
|
62767
|
+
switch (spaceName) {
|
|
62768
|
+
case "oklch":
|
|
62769
|
+
return c;
|
|
62770
|
+
case "oklab":
|
|
62771
|
+
case "lab":
|
|
62772
|
+
return `_gpu_oklch_to_oklab(${c})`;
|
|
62773
|
+
case "rgb":
|
|
62774
|
+
return `_gpu_oklch_to_srgb(${c})`;
|
|
62775
|
+
case "hsl":
|
|
62776
|
+
return `_gpu_rgb_to_hsl(_gpu_oklch_to_srgb(${c}))`;
|
|
62777
|
+
case "hsv":
|
|
62778
|
+
return `_gpu_rgb_to_hsv(_gpu_oklch_to_srgb(${c}))`;
|
|
62779
|
+
default:
|
|
62780
|
+
throw new Error(
|
|
62781
|
+
`ColorToColorspace: unsupported space "${spaceName}" on GPU target`
|
|
62782
|
+
);
|
|
62783
|
+
}
|
|
61954
62784
|
},
|
|
61955
62785
|
ColorFromColorspace: ([components, space], compile3) => {
|
|
61956
62786
|
if (components === null || space === null)
|
|
61957
62787
|
throw new Error("ColorFromColorspace: need components and space");
|
|
61958
|
-
|
|
62788
|
+
const spaceName = readStringLiteral(space);
|
|
62789
|
+
if (spaceName === null)
|
|
62790
|
+
throw new Error("ColorFromColorspace: space must be a string literal");
|
|
62791
|
+
const c = compile3(components);
|
|
62792
|
+
switch (spaceName) {
|
|
62793
|
+
case "oklch":
|
|
62794
|
+
return c;
|
|
62795
|
+
case "oklab":
|
|
62796
|
+
case "lab":
|
|
62797
|
+
return `_gpu_oklab_to_oklch(${c})`;
|
|
62798
|
+
case "rgb":
|
|
62799
|
+
return `_gpu_srgb_to_oklch(${c})`;
|
|
62800
|
+
case "hsl":
|
|
62801
|
+
return `_gpu_srgb_to_oklch(_gpu_hsl_to_rgb(${c}))`;
|
|
62802
|
+
case "hsv":
|
|
62803
|
+
return `_gpu_srgb_to_oklch(_gpu_hsv_to_rgb(${c}))`;
|
|
62804
|
+
default:
|
|
62805
|
+
throw new Error(
|
|
62806
|
+
`ColorFromColorspace: unsupported space "${spaceName}" on GPU target`
|
|
62807
|
+
);
|
|
62808
|
+
}
|
|
62809
|
+
},
|
|
62810
|
+
// ---------------------------------------------------------------------------
|
|
62811
|
+
// Color literals. Each typed head compiles to a canonical OKLCh vec3.
|
|
62812
|
+
// Alpha (4th argument) is dropped — GPU color values are vec3 only. Pass
|
|
62813
|
+
// alpha as a separate uniform if it's needed at the framebuffer boundary.
|
|
62814
|
+
// ---------------------------------------------------------------------------
|
|
62815
|
+
Color: ([s], _compile2, target) => {
|
|
62816
|
+
if (s === null) throw new Error("Color: no argument");
|
|
62817
|
+
const str = readStringLiteral(s);
|
|
62818
|
+
if (str === null)
|
|
62819
|
+
throw new Error("Color: argument must be a string literal on GPU target");
|
|
62820
|
+
const packed = parseColor(str);
|
|
62821
|
+
if (packed === 0 && str.trim().toLowerCase() !== "transparent")
|
|
62822
|
+
throw new Error(`Color: invalid color string "${str}"`);
|
|
62823
|
+
const r = packed >>> 24 & 255;
|
|
62824
|
+
const g = packed >>> 16 & 255;
|
|
62825
|
+
const b = packed >>> 8 & 255;
|
|
62826
|
+
const oklch2 = rgbToOklch({ r, g, b });
|
|
62827
|
+
return `${gpuVec3(target)}(${formatFloat(oklch2.L)}, ${formatFloat(oklch2.C)}, ${formatFloat(oklch2.H)})`;
|
|
62828
|
+
},
|
|
62829
|
+
Rgb: (args, compile3, target) => {
|
|
62830
|
+
if (args.length < 3) throw new Error("Rgb: need 3 components");
|
|
62831
|
+
const v3 = gpuVec3(target);
|
|
62832
|
+
return `_gpu_srgb_to_oklch(${v3}(${compile3(args[0])}, ${compile3(args[1])}, ${compile3(args[2])}))`;
|
|
62833
|
+
},
|
|
62834
|
+
Hsv: (args, compile3, target) => {
|
|
62835
|
+
if (args.length < 3) throw new Error("Hsv: need 3 components");
|
|
62836
|
+
const v3 = gpuVec3(target);
|
|
62837
|
+
return `_gpu_srgb_to_oklch(_gpu_hsv_to_rgb(${v3}(${compile3(args[0])}, ${compile3(args[1])}, ${compile3(args[2])})))`;
|
|
62838
|
+
},
|
|
62839
|
+
Hsl: (args, compile3, target) => {
|
|
62840
|
+
if (args.length < 3) throw new Error("Hsl: need 3 components");
|
|
62841
|
+
const v3 = gpuVec3(target);
|
|
62842
|
+
return `_gpu_srgb_to_oklch(_gpu_hsl_to_rgb(${v3}(${compile3(args[0])}, ${compile3(args[1])}, ${compile3(args[2])})))`;
|
|
62843
|
+
},
|
|
62844
|
+
Oklab: (args, compile3, target) => {
|
|
62845
|
+
if (args.length < 3) throw new Error("Oklab: need 3 components");
|
|
62846
|
+
const v3 = gpuVec3(target);
|
|
62847
|
+
return `_gpu_oklab_to_oklch(${v3}(${compile3(args[0])}, ${compile3(args[1])}, ${compile3(args[2])}))`;
|
|
62848
|
+
},
|
|
62849
|
+
Oklch: (args, compile3, target) => {
|
|
62850
|
+
if (args.length < 3) throw new Error("Oklch: need 3 components");
|
|
62851
|
+
const v3 = gpuVec3(target);
|
|
62852
|
+
return `${v3}(${compile3(args[0])}, ${compile3(args[1])}, ${compile3(args[2])})`;
|
|
62853
|
+
},
|
|
62854
|
+
// ---------------------------------------------------------------------------
|
|
62855
|
+
// As* operators. AsOklch is identity (canonical). The other As* return
|
|
62856
|
+
// components in the named space, equivalent to ColorToColorspace(c, 'x').
|
|
62857
|
+
// ---------------------------------------------------------------------------
|
|
62858
|
+
AsOklch: ([c], compile3) => {
|
|
62859
|
+
if (c === null) throw new Error("AsOklch: no argument");
|
|
62860
|
+
return compile3(c);
|
|
62861
|
+
},
|
|
62862
|
+
AsOklab: ([c], compile3) => {
|
|
62863
|
+
if (c === null) throw new Error("AsOklab: no argument");
|
|
62864
|
+
return `_gpu_oklch_to_oklab(${compile3(c)})`;
|
|
62865
|
+
},
|
|
62866
|
+
AsRgb: ([c], compile3) => {
|
|
62867
|
+
if (c === null) throw new Error("AsRgb: no argument");
|
|
62868
|
+
return `_gpu_oklch_to_srgb(${compile3(c)})`;
|
|
62869
|
+
},
|
|
62870
|
+
AsHsv: ([c], compile3) => {
|
|
62871
|
+
if (c === null) throw new Error("AsHsv: no argument");
|
|
62872
|
+
return `_gpu_rgb_to_hsv(_gpu_oklch_to_srgb(${compile3(c)}))`;
|
|
62873
|
+
},
|
|
62874
|
+
AsHsl: ([c], compile3) => {
|
|
62875
|
+
if (c === null) throw new Error("AsHsl: no argument");
|
|
62876
|
+
return `_gpu_rgb_to_hsl(_gpu_oklch_to_srgb(${compile3(c)}))`;
|
|
61959
62877
|
},
|
|
61960
62878
|
// Fractal functions
|
|
61961
62879
|
Mandelbrot: ([c, maxIter], compile3, target) => {
|
|
61962
62880
|
if (c === null || maxIter === null)
|
|
61963
62881
|
throw new Error("Mandelbrot: missing arguments");
|
|
61964
62882
|
const iterCode = compileIntArg(maxIter, compile3, target);
|
|
61965
|
-
const strategy = selectFractalStrategy(target);
|
|
61966
|
-
if (strategy === "double") {
|
|
61967
|
-
const dpCoord = target?.language === "wgsl" ? "_dp_coord(v_uv)" : "_dp_coord()";
|
|
61968
|
-
return `_fractal_mandelbrot_dp(${dpCoord}, ${iterCode})`;
|
|
61969
|
-
}
|
|
61970
|
-
if (strategy === "perturbation") {
|
|
61971
|
-
const ptDelta = target?.language === "wgsl" ? "_pt_delta(v_uv)" : "_pt_delta()";
|
|
61972
|
-
return `_fractal_mandelbrot_pt(${ptDelta}, ${iterCode})`;
|
|
61973
|
-
}
|
|
61974
62883
|
return `_fractal_mandelbrot(${compile3(c)}, ${iterCode})`;
|
|
61975
62884
|
},
|
|
61976
62885
|
Julia: ([z, c, maxIter], compile3, target) => {
|
|
61977
62886
|
if (z === null || c === null || maxIter === null)
|
|
61978
62887
|
throw new Error("Julia: missing arguments");
|
|
61979
62888
|
const iterCode = compileIntArg(maxIter, compile3, target);
|
|
61980
|
-
const strategy = selectFractalStrategy(target);
|
|
61981
|
-
if (strategy === "double") {
|
|
61982
|
-
const dpCoord = target?.language === "wgsl" ? "_dp_coord(v_uv)" : "_dp_coord()";
|
|
61983
|
-
const cCode = compile3(c);
|
|
61984
|
-
return `_fractal_julia_dp(${dpCoord}, vec4(${cCode}, vec2(0.0)), ${iterCode})`;
|
|
61985
|
-
}
|
|
61986
|
-
if (strategy === "perturbation") {
|
|
61987
|
-
const ptDelta = target?.language === "wgsl" ? "_pt_delta(v_uv)" : "_pt_delta()";
|
|
61988
|
-
const cCode = compile3(c);
|
|
61989
|
-
return `_fractal_julia_pt(${ptDelta}, ${cCode}, ${iterCode})`;
|
|
61990
|
-
}
|
|
61991
62889
|
return `_fractal_julia(${compile3(z)}, ${compile3(c)}, ${iterCode})`;
|
|
61992
62890
|
},
|
|
61993
62891
|
// Vector/Matrix operations
|
|
@@ -62584,232 +63482,6 @@ fn _gpu_besselJ(n_in: i32, x_in: f32) -> f32 {
|
|
|
62584
63482
|
for (var k2: i32 = 2; k2 <= M; k2 += 2) { norm += 2.0 * vals[k2]; }
|
|
62585
63483
|
return sgn * vals[n] / norm;
|
|
62586
63484
|
}
|
|
62587
|
-
`;
|
|
62588
|
-
var GPU_DS_ARITHMETIC_PREAMBLE_GLSL = `
|
|
62589
|
-
// Split a float into high and low parts for exact multiplication
|
|
62590
|
-
vec2 ds_split(float a) {
|
|
62591
|
-
const float SPLIT = 4097.0; // 2^12 + 1
|
|
62592
|
-
float t = SPLIT * a;
|
|
62593
|
-
float hi = t - (t - a);
|
|
62594
|
-
float lo = a - hi;
|
|
62595
|
-
return vec2(hi, lo);
|
|
62596
|
-
}
|
|
62597
|
-
|
|
62598
|
-
// Create a double-single from a single float
|
|
62599
|
-
vec2 ds_from(float a) {
|
|
62600
|
-
return vec2(a, 0.0);
|
|
62601
|
-
}
|
|
62602
|
-
|
|
62603
|
-
// Error-free addition (Knuth TwoSum)
|
|
62604
|
-
vec2 ds_add(vec2 a, vec2 b) {
|
|
62605
|
-
float s = a.x + b.x;
|
|
62606
|
-
float v = s - a.x;
|
|
62607
|
-
float e = (a.x - (s - v)) + (b.x - v);
|
|
62608
|
-
float lo = (a.y + b.y) + e;
|
|
62609
|
-
float hi = s + lo;
|
|
62610
|
-
lo = lo - (hi - s);
|
|
62611
|
-
return vec2(hi, lo);
|
|
62612
|
-
}
|
|
62613
|
-
|
|
62614
|
-
// Double-single subtraction
|
|
62615
|
-
vec2 ds_sub(vec2 a, vec2 b) {
|
|
62616
|
-
return ds_add(a, vec2(-b.x, -b.y));
|
|
62617
|
-
}
|
|
62618
|
-
|
|
62619
|
-
// Error-free multiplication (Dekker TwoProduct)
|
|
62620
|
-
vec2 ds_mul(vec2 a, vec2 b) {
|
|
62621
|
-
float p = a.x * b.x;
|
|
62622
|
-
vec2 sa = ds_split(a.x);
|
|
62623
|
-
vec2 sb = ds_split(b.x);
|
|
62624
|
-
float err = ((sa.x * sb.x - p) + sa.x * sb.y + sa.y * sb.x) + sa.y * sb.y;
|
|
62625
|
-
err += a.x * b.y + a.y * b.x;
|
|
62626
|
-
float hi = p + err;
|
|
62627
|
-
float lo = err - (hi - p);
|
|
62628
|
-
return vec2(hi, lo);
|
|
62629
|
-
}
|
|
62630
|
-
|
|
62631
|
-
// Optimized self-multiply
|
|
62632
|
-
vec2 ds_sqr(vec2 a) {
|
|
62633
|
-
float p = a.x * a.x;
|
|
62634
|
-
vec2 sa = ds_split(a.x);
|
|
62635
|
-
float err = ((sa.x * sa.x - p) + 2.0 * sa.x * sa.y) + sa.y * sa.y;
|
|
62636
|
-
err += 2.0 * a.x * a.y;
|
|
62637
|
-
float hi = p + err;
|
|
62638
|
-
float lo = err - (hi - p);
|
|
62639
|
-
return vec2(hi, lo);
|
|
62640
|
-
}
|
|
62641
|
-
|
|
62642
|
-
// Compare magnitude: returns -1, 0, or 1
|
|
62643
|
-
float ds_cmp(vec2 a, vec2 b) {
|
|
62644
|
-
float d = a.x - b.x;
|
|
62645
|
-
if (d != 0.0) return sign(d);
|
|
62646
|
-
return sign(a.y - b.y);
|
|
62647
|
-
}
|
|
62648
|
-
`;
|
|
62649
|
-
var GPU_DS_ARITHMETIC_PREAMBLE_WGSL = `
|
|
62650
|
-
fn ds_split(a: f32) -> vec2f {
|
|
62651
|
-
const SPLIT: f32 = 4097.0;
|
|
62652
|
-
let t = SPLIT * a;
|
|
62653
|
-
let hi = t - (t - a);
|
|
62654
|
-
let lo = a - hi;
|
|
62655
|
-
return vec2f(hi, lo);
|
|
62656
|
-
}
|
|
62657
|
-
|
|
62658
|
-
fn ds_from(a: f32) -> vec2f {
|
|
62659
|
-
return vec2f(a, 0.0);
|
|
62660
|
-
}
|
|
62661
|
-
|
|
62662
|
-
fn ds_add(a: vec2f, b: vec2f) -> vec2f {
|
|
62663
|
-
let s = a.x + b.x;
|
|
62664
|
-
let v = s - a.x;
|
|
62665
|
-
let e = (a.x - (s - v)) + (b.x - v);
|
|
62666
|
-
let lo_t = (a.y + b.y) + e;
|
|
62667
|
-
let hi = s + lo_t;
|
|
62668
|
-
let lo = lo_t - (hi - s);
|
|
62669
|
-
return vec2f(hi, lo);
|
|
62670
|
-
}
|
|
62671
|
-
|
|
62672
|
-
fn ds_sub(a: vec2f, b: vec2f) -> vec2f {
|
|
62673
|
-
return ds_add(a, vec2f(-b.x, -b.y));
|
|
62674
|
-
}
|
|
62675
|
-
|
|
62676
|
-
fn ds_mul(a: vec2f, b: vec2f) -> vec2f {
|
|
62677
|
-
let p = a.x * b.x;
|
|
62678
|
-
let sa = ds_split(a.x);
|
|
62679
|
-
let sb = ds_split(b.x);
|
|
62680
|
-
var err = ((sa.x * sb.x - p) + sa.x * sb.y + sa.y * sb.x) + sa.y * sb.y;
|
|
62681
|
-
err += a.x * b.y + a.y * b.x;
|
|
62682
|
-
let hi = p + err;
|
|
62683
|
-
let lo = err - (hi - p);
|
|
62684
|
-
return vec2f(hi, lo);
|
|
62685
|
-
}
|
|
62686
|
-
|
|
62687
|
-
fn ds_sqr(a: vec2f) -> vec2f {
|
|
62688
|
-
let p = a.x * a.x;
|
|
62689
|
-
let sa = ds_split(a.x);
|
|
62690
|
-
var err = ((sa.x * sa.x - p) + 2.0 * sa.x * sa.y) + sa.y * sa.y;
|
|
62691
|
-
err += 2.0 * a.x * a.y;
|
|
62692
|
-
let hi = p + err;
|
|
62693
|
-
let lo = err - (hi - p);
|
|
62694
|
-
return vec2f(hi, lo);
|
|
62695
|
-
}
|
|
62696
|
-
|
|
62697
|
-
fn ds_cmp(a: vec2f, b: vec2f) -> f32 {
|
|
62698
|
-
let d = a.x - b.x;
|
|
62699
|
-
if (d != 0.0) { return sign(d); }
|
|
62700
|
-
return sign(a.y - b.y);
|
|
62701
|
-
}
|
|
62702
|
-
`;
|
|
62703
|
-
var GPU_FRACTAL_DP_PREAMBLE_GLSL = `
|
|
62704
|
-
uniform float _dp_cx_hi;
|
|
62705
|
-
uniform float _dp_cx_lo;
|
|
62706
|
-
uniform float _dp_cy_hi;
|
|
62707
|
-
uniform float _dp_cy_lo;
|
|
62708
|
-
uniform float _dp_w;
|
|
62709
|
-
uniform float _dp_h;
|
|
62710
|
-
|
|
62711
|
-
vec4 _dp_coord() {
|
|
62712
|
-
// Per-pixel offset from center \u2014 small, so float-precise
|
|
62713
|
-
float dx = (v_uv.x - 0.5) * _dp_w;
|
|
62714
|
-
float dy = (v_uv.y - 0.5) * _dp_h;
|
|
62715
|
-
// Combine center (hi+lo) + delta with emulated double precision
|
|
62716
|
-
vec2 cre = ds_add(vec2(_dp_cx_hi, _dp_cx_lo), ds_from(dx));
|
|
62717
|
-
vec2 cim = ds_add(vec2(_dp_cy_hi, _dp_cy_lo), ds_from(dy));
|
|
62718
|
-
return vec4(cre.x, cim.x, cre.y, cim.y);
|
|
62719
|
-
}
|
|
62720
|
-
|
|
62721
|
-
float _fractal_mandelbrot_dp(vec4 c, int maxIter) {
|
|
62722
|
-
// c = (re_hi, im_hi, re_lo, im_lo)
|
|
62723
|
-
vec2 cr = vec2(c.x, c.z); // real part as ds
|
|
62724
|
-
vec2 ci = vec2(c.y, c.w); // imag part as ds
|
|
62725
|
-
vec2 zr = vec2(0.0, 0.0);
|
|
62726
|
-
vec2 zi = vec2(0.0, 0.0);
|
|
62727
|
-
for (int i = 0; i < maxIter; i++) {
|
|
62728
|
-
vec2 zr2 = ds_sqr(zr);
|
|
62729
|
-
vec2 zi2 = ds_sqr(zi);
|
|
62730
|
-
// |z|^2 > 4.0 ?
|
|
62731
|
-
vec2 mag2 = ds_add(zr2, zi2);
|
|
62732
|
-
if (mag2.x > 4.0)
|
|
62733
|
-
return clamp((float(i) - log2(log2(mag2.x)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
62734
|
-
// z = z^2 + c
|
|
62735
|
-
vec2 new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci); // 2*zr*zi + ci
|
|
62736
|
-
zr = ds_add(ds_sub(zr2, zi2), cr); // zr^2 - zi^2 + cr
|
|
62737
|
-
zi = new_zi;
|
|
62738
|
-
}
|
|
62739
|
-
return 1.0;
|
|
62740
|
-
}
|
|
62741
|
-
|
|
62742
|
-
float _fractal_julia_dp(vec4 z_in, vec4 c, int maxIter) {
|
|
62743
|
-
vec2 zr = vec2(z_in.x, z_in.z);
|
|
62744
|
-
vec2 zi = vec2(z_in.y, z_in.w);
|
|
62745
|
-
vec2 cr = vec2(c.x, c.z);
|
|
62746
|
-
vec2 ci = vec2(c.y, c.w);
|
|
62747
|
-
for (int i = 0; i < maxIter; i++) {
|
|
62748
|
-
vec2 zr2 = ds_sqr(zr);
|
|
62749
|
-
vec2 zi2 = ds_sqr(zi);
|
|
62750
|
-
vec2 mag2 = ds_add(zr2, zi2);
|
|
62751
|
-
if (mag2.x > 4.0)
|
|
62752
|
-
return clamp((float(i) - log2(log2(mag2.x)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
62753
|
-
vec2 new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
|
|
62754
|
-
zr = ds_add(ds_sub(zr2, zi2), cr);
|
|
62755
|
-
zi = new_zi;
|
|
62756
|
-
}
|
|
62757
|
-
return 1.0;
|
|
62758
|
-
}
|
|
62759
|
-
`;
|
|
62760
|
-
var GPU_FRACTAL_DP_PREAMBLE_WGSL = `
|
|
62761
|
-
@group(0) @binding(10) var<uniform> _dp_cx_hi: f32;
|
|
62762
|
-
@group(0) @binding(11) var<uniform> _dp_cx_lo: f32;
|
|
62763
|
-
@group(0) @binding(12) var<uniform> _dp_cy_hi: f32;
|
|
62764
|
-
@group(0) @binding(13) var<uniform> _dp_cy_lo: f32;
|
|
62765
|
-
@group(0) @binding(14) var<uniform> _dp_w: f32;
|
|
62766
|
-
@group(0) @binding(15) var<uniform> _dp_h: f32;
|
|
62767
|
-
|
|
62768
|
-
fn _dp_coord(uv: vec2f) -> vec4f {
|
|
62769
|
-
let dx = (uv.x - 0.5) * _dp_w;
|
|
62770
|
-
let dy = (uv.y - 0.5) * _dp_h;
|
|
62771
|
-
let cre = ds_add(vec2f(_dp_cx_hi, _dp_cx_lo), ds_from(dx));
|
|
62772
|
-
let cim = ds_add(vec2f(_dp_cy_hi, _dp_cy_lo), ds_from(dy));
|
|
62773
|
-
return vec4f(cre.x, cim.x, cre.y, cim.y);
|
|
62774
|
-
}
|
|
62775
|
-
|
|
62776
|
-
fn _fractal_mandelbrot_dp(c: vec4f, maxIter: i32) -> f32 {
|
|
62777
|
-
let cr = vec2f(c.x, c.z);
|
|
62778
|
-
let ci = vec2f(c.y, c.w);
|
|
62779
|
-
var zr = vec2f(0.0, 0.0);
|
|
62780
|
-
var zi = vec2f(0.0, 0.0);
|
|
62781
|
-
for (var i: i32 = 0; i < maxIter; i++) {
|
|
62782
|
-
let zr2 = ds_sqr(zr);
|
|
62783
|
-
let zi2 = ds_sqr(zi);
|
|
62784
|
-
let mag2 = ds_add(zr2, zi2);
|
|
62785
|
-
if (mag2.x > 4.0) {
|
|
62786
|
-
return clamp((f32(i) - log2(log2(mag2.x)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
62787
|
-
}
|
|
62788
|
-
let new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
|
|
62789
|
-
zr = ds_add(ds_sub(zr2, zi2), cr);
|
|
62790
|
-
zi = new_zi;
|
|
62791
|
-
}
|
|
62792
|
-
return 1.0;
|
|
62793
|
-
}
|
|
62794
|
-
|
|
62795
|
-
fn _fractal_julia_dp(z_in: vec4f, c: vec4f, maxIter: i32) -> f32 {
|
|
62796
|
-
var zr = vec2f(z_in.x, z_in.z);
|
|
62797
|
-
var zi = vec2f(z_in.y, z_in.w);
|
|
62798
|
-
let cr = vec2f(c.x, c.z);
|
|
62799
|
-
let ci = vec2f(c.y, c.w);
|
|
62800
|
-
for (var i: i32 = 0; i < maxIter; i++) {
|
|
62801
|
-
let zr2 = ds_sqr(zr);
|
|
62802
|
-
let zi2 = ds_sqr(zi);
|
|
62803
|
-
let mag2 = ds_add(zr2, zi2);
|
|
62804
|
-
if (mag2.x > 4.0) {
|
|
62805
|
-
return clamp((f32(i) - log2(log2(mag2.x)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
62806
|
-
}
|
|
62807
|
-
let new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
|
|
62808
|
-
zr = ds_add(ds_sub(zr2, zi2), cr);
|
|
62809
|
-
zi = new_zi;
|
|
62810
|
-
}
|
|
62811
|
-
return 1.0;
|
|
62812
|
-
}
|
|
62813
63485
|
`;
|
|
62814
63486
|
var GPU_FRACTAL_PREAMBLE_GLSL = `
|
|
62815
63487
|
float _fractal_mandelbrot(vec2 c, int maxIter) {
|
|
@@ -62853,208 +63525,6 @@ fn _fractal_julia(z_in: vec2f, c: vec2f, maxIter: i32) -> f32 {
|
|
|
62853
63525
|
}
|
|
62854
63526
|
return 1.0;
|
|
62855
63527
|
}
|
|
62856
|
-
`;
|
|
62857
|
-
var GPU_FRACTAL_PT_PREAMBLE_GLSL = `
|
|
62858
|
-
uniform sampler2D _refOrbit;
|
|
62859
|
-
uniform int _refOrbitLen;
|
|
62860
|
-
uniform int _refOrbitTexWidth;
|
|
62861
|
-
uniform float _pt_offset_x;
|
|
62862
|
-
uniform float _pt_offset_y;
|
|
62863
|
-
uniform float _pt_w;
|
|
62864
|
-
uniform float _pt_h;
|
|
62865
|
-
|
|
62866
|
-
vec2 _pt_delta() {
|
|
62867
|
-
float dx = _pt_offset_x + (v_uv.x - 0.5) * _pt_w;
|
|
62868
|
-
float dy = _pt_offset_y + (v_uv.y - 0.5) * _pt_h;
|
|
62869
|
-
return vec2(dx, dy);
|
|
62870
|
-
}
|
|
62871
|
-
|
|
62872
|
-
vec2 _pt_fetch_orbit(int i) {
|
|
62873
|
-
int y = i / _refOrbitTexWidth;
|
|
62874
|
-
int x = i - y * _refOrbitTexWidth;
|
|
62875
|
-
return texelFetch(_refOrbit, ivec2(x, y), 0).rg;
|
|
62876
|
-
}
|
|
62877
|
-
|
|
62878
|
-
float _fractal_mandelbrot_pt(vec2 delta_c, int maxIter) {
|
|
62879
|
-
float dr = 0.0;
|
|
62880
|
-
float di = 0.0;
|
|
62881
|
-
int orbitLen = min(maxIter, _refOrbitLen);
|
|
62882
|
-
for (int i = 0; i < orbitLen; i++) {
|
|
62883
|
-
vec2 Zn = _pt_fetch_orbit(i);
|
|
62884
|
-
// delta_{n+1} = 2*Z_n*delta_n + delta_n^2 + delta_c
|
|
62885
|
-
float new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
62886
|
-
float new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
62887
|
-
dr = new_dr;
|
|
62888
|
-
di = new_di;
|
|
62889
|
-
// Full z = Z_{n+1} + delta for escape check
|
|
62890
|
-
vec2 Zn1 = (i + 1 < orbitLen) ? _pt_fetch_orbit(i + 1) : vec2(0.0);
|
|
62891
|
-
float zr = Zn1.x + dr;
|
|
62892
|
-
float zi = Zn1.y + di;
|
|
62893
|
-
float mag2 = zr * zr + zi * zi;
|
|
62894
|
-
if (mag2 > 4.0)
|
|
62895
|
-
return clamp((float(i) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
62896
|
-
// Glitch detection: |delta|^2 > |Z|^2
|
|
62897
|
-
float dmag2 = dr * dr + di * di;
|
|
62898
|
-
float Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
62899
|
-
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
62900
|
-
// Rebase to absolute coordinates and continue with single-float
|
|
62901
|
-
float abs_zr = Zn1.x + dr;
|
|
62902
|
-
float abs_zi = Zn1.y + di;
|
|
62903
|
-
// Reconstruct absolute c from reference + delta
|
|
62904
|
-
// (Use ds_from for the concept, but single-float suffices for fallback)
|
|
62905
|
-
float cx = abs_zr - dr + delta_c.x;
|
|
62906
|
-
float cy = abs_zi - di + delta_c.y;
|
|
62907
|
-
for (int j = i + 1; j < maxIter; j++) {
|
|
62908
|
-
float new_zr = abs_zr * abs_zr - abs_zi * abs_zi + cx;
|
|
62909
|
-
abs_zi = 2.0 * abs_zr * abs_zi + cy;
|
|
62910
|
-
abs_zr = new_zr;
|
|
62911
|
-
mag2 = abs_zr * abs_zr + abs_zi * abs_zi;
|
|
62912
|
-
if (mag2 > 4.0)
|
|
62913
|
-
return clamp((float(j) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
62914
|
-
}
|
|
62915
|
-
return 1.0;
|
|
62916
|
-
}
|
|
62917
|
-
}
|
|
62918
|
-
return 1.0;
|
|
62919
|
-
}
|
|
62920
|
-
|
|
62921
|
-
float _fractal_julia_pt(vec2 z_delta, vec2 delta_c, int maxIter) {
|
|
62922
|
-
float dr = z_delta.x;
|
|
62923
|
-
float di = z_delta.y;
|
|
62924
|
-
int orbitLen = min(maxIter, _refOrbitLen);
|
|
62925
|
-
for (int i = 0; i < orbitLen; i++) {
|
|
62926
|
-
vec2 Zn = _pt_fetch_orbit(i);
|
|
62927
|
-
float new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
62928
|
-
float new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
62929
|
-
dr = new_dr;
|
|
62930
|
-
di = new_di;
|
|
62931
|
-
vec2 Zn1 = (i + 1 < orbitLen) ? _pt_fetch_orbit(i + 1) : vec2(0.0);
|
|
62932
|
-
float zr = Zn1.x + dr;
|
|
62933
|
-
float zi = Zn1.y + di;
|
|
62934
|
-
float mag2 = zr * zr + zi * zi;
|
|
62935
|
-
if (mag2 > 4.0)
|
|
62936
|
-
return clamp((float(i) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
62937
|
-
float dmag2 = dr * dr + di * di;
|
|
62938
|
-
float Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
62939
|
-
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
62940
|
-
float abs_zr = Zn1.x + dr;
|
|
62941
|
-
float abs_zi = Zn1.y + di;
|
|
62942
|
-
float cx = delta_c.x;
|
|
62943
|
-
float cy = delta_c.y;
|
|
62944
|
-
for (int j = i + 1; j < maxIter; j++) {
|
|
62945
|
-
float new_zr = abs_zr * abs_zr - abs_zi * abs_zi + cx;
|
|
62946
|
-
abs_zi = 2.0 * abs_zr * abs_zi + cy;
|
|
62947
|
-
abs_zr = new_zr;
|
|
62948
|
-
mag2 = abs_zr * abs_zr + abs_zi * abs_zi;
|
|
62949
|
-
if (mag2 > 4.0)
|
|
62950
|
-
return clamp((float(j) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
62951
|
-
}
|
|
62952
|
-
return 1.0;
|
|
62953
|
-
}
|
|
62954
|
-
}
|
|
62955
|
-
return 1.0;
|
|
62956
|
-
}
|
|
62957
|
-
`;
|
|
62958
|
-
var GPU_FRACTAL_PT_PREAMBLE_WGSL = `
|
|
62959
|
-
@group(0) @binding(1) var _refOrbit: texture_2d<f32>;
|
|
62960
|
-
var<uniform> _refOrbitLen: i32;
|
|
62961
|
-
var<uniform> _refOrbitTexWidth: i32;
|
|
62962
|
-
var<uniform> _pt_offset_x: f32;
|
|
62963
|
-
var<uniform> _pt_offset_y: f32;
|
|
62964
|
-
var<uniform> _pt_w: f32;
|
|
62965
|
-
var<uniform> _pt_h: f32;
|
|
62966
|
-
|
|
62967
|
-
fn _pt_delta(uv: vec2f) -> vec2f {
|
|
62968
|
-
let dx = _pt_offset_x + (uv.x - 0.5) * _pt_w;
|
|
62969
|
-
let dy = _pt_offset_y + (uv.y - 0.5) * _pt_h;
|
|
62970
|
-
return vec2f(dx, dy);
|
|
62971
|
-
}
|
|
62972
|
-
|
|
62973
|
-
fn _pt_fetch_orbit(i: i32) -> vec2f {
|
|
62974
|
-
let y = i / _refOrbitTexWidth;
|
|
62975
|
-
let x = i - y * _refOrbitTexWidth;
|
|
62976
|
-
return textureLoad(_refOrbit, vec2i(x, y), 0).rg;
|
|
62977
|
-
}
|
|
62978
|
-
|
|
62979
|
-
fn _fractal_mandelbrot_pt(delta_c: vec2f, maxIter: i32) -> f32 {
|
|
62980
|
-
var dr: f32 = 0.0;
|
|
62981
|
-
var di: f32 = 0.0;
|
|
62982
|
-
let orbitLen = min(maxIter, _refOrbitLen);
|
|
62983
|
-
for (var i: i32 = 0; i < orbitLen; i++) {
|
|
62984
|
-
let Zn = _pt_fetch_orbit(i);
|
|
62985
|
-
let new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
62986
|
-
let new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
62987
|
-
dr = new_dr;
|
|
62988
|
-
di = new_di;
|
|
62989
|
-
var Zn1 = vec2f(0.0);
|
|
62990
|
-
if (i + 1 < orbitLen) { Zn1 = _pt_fetch_orbit(i + 1); }
|
|
62991
|
-
let zr = Zn1.x + dr;
|
|
62992
|
-
let zi = Zn1.y + di;
|
|
62993
|
-
var mag2 = zr * zr + zi * zi;
|
|
62994
|
-
if (mag2 > 4.0) {
|
|
62995
|
-
return clamp((f32(i) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
62996
|
-
}
|
|
62997
|
-
let dmag2 = dr * dr + di * di;
|
|
62998
|
-
let Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
62999
|
-
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
63000
|
-
var f_zr = Zn1.x + dr;
|
|
63001
|
-
var f_zi = Zn1.y + di;
|
|
63002
|
-
let cx = delta_c.x;
|
|
63003
|
-
let cy = delta_c.y;
|
|
63004
|
-
for (var j: i32 = i + 1; j < maxIter; j++) {
|
|
63005
|
-
let t_zr = f_zr * f_zr - f_zi * f_zi + cx;
|
|
63006
|
-
f_zi = 2.0 * f_zr * f_zi + cy;
|
|
63007
|
-
f_zr = t_zr;
|
|
63008
|
-
mag2 = f_zr * f_zr + f_zi * f_zi;
|
|
63009
|
-
if (mag2 > 4.0) {
|
|
63010
|
-
return clamp((f32(j) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
63011
|
-
}
|
|
63012
|
-
}
|
|
63013
|
-
return 1.0;
|
|
63014
|
-
}
|
|
63015
|
-
}
|
|
63016
|
-
return 1.0;
|
|
63017
|
-
}
|
|
63018
|
-
|
|
63019
|
-
fn _fractal_julia_pt(z_delta: vec2f, delta_c: vec2f, maxIter: i32) -> f32 {
|
|
63020
|
-
var dr = z_delta.x;
|
|
63021
|
-
var di = z_delta.y;
|
|
63022
|
-
let orbitLen = min(maxIter, _refOrbitLen);
|
|
63023
|
-
for (var i: i32 = 0; i < orbitLen; i++) {
|
|
63024
|
-
let Zn = _pt_fetch_orbit(i);
|
|
63025
|
-
let new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
63026
|
-
let new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
63027
|
-
dr = new_dr;
|
|
63028
|
-
di = new_di;
|
|
63029
|
-
var Zn1 = vec2f(0.0);
|
|
63030
|
-
if (i + 1 < orbitLen) { Zn1 = _pt_fetch_orbit(i + 1); }
|
|
63031
|
-
let zr = Zn1.x + dr;
|
|
63032
|
-
let zi = Zn1.y + di;
|
|
63033
|
-
var mag2 = zr * zr + zi * zi;
|
|
63034
|
-
if (mag2 > 4.0) {
|
|
63035
|
-
return clamp((f32(i) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
63036
|
-
}
|
|
63037
|
-
let dmag2 = dr * dr + di * di;
|
|
63038
|
-
let Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
63039
|
-
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
63040
|
-
var f_zr = Zn1.x + dr;
|
|
63041
|
-
var f_zi = Zn1.y + di;
|
|
63042
|
-
let cx = delta_c.x;
|
|
63043
|
-
let cy = delta_c.y;
|
|
63044
|
-
for (var j: i32 = i + 1; j < maxIter; j++) {
|
|
63045
|
-
let t_zr = f_zr * f_zr - f_zi * f_zi + cx;
|
|
63046
|
-
f_zi = 2.0 * f_zr * f_zi + cy;
|
|
63047
|
-
f_zr = t_zr;
|
|
63048
|
-
mag2 = f_zr * f_zr + f_zi * f_zi;
|
|
63049
|
-
if (mag2 > 4.0) {
|
|
63050
|
-
return clamp((f32(j) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
63051
|
-
}
|
|
63052
|
-
}
|
|
63053
|
-
return 1.0;
|
|
63054
|
-
}
|
|
63055
|
-
}
|
|
63056
|
-
return 1.0;
|
|
63057
|
-
}
|
|
63058
63528
|
`;
|
|
63059
63529
|
var GPU_COLOR_PREAMBLE_GLSL = `
|
|
63060
63530
|
float _gpu_srgb_to_linear(float c) {
|
|
@@ -63096,28 +63566,124 @@ vec3 _gpu_oklab_to_srgb(vec3 lab) {
|
|
|
63096
63566
|
|
|
63097
63567
|
vec3 _gpu_oklab_to_oklch(vec3 lab) {
|
|
63098
63568
|
float C = length(lab.yz);
|
|
63099
|
-
float H = atan(lab.z, lab.y);
|
|
63569
|
+
float H = atan(lab.z, lab.y) * (180.0 / 3.14159265359);
|
|
63570
|
+
if (H < 0.0) H += 360.0;
|
|
63100
63571
|
return vec3(lab.x, C, H);
|
|
63101
63572
|
}
|
|
63102
63573
|
|
|
63103
63574
|
vec3 _gpu_oklch_to_oklab(vec3 lch) {
|
|
63104
|
-
|
|
63575
|
+
float h_rad = lch.z * (3.14159265359 / 180.0);
|
|
63576
|
+
return vec3(lch.x, lch.y * cos(h_rad), lch.y * sin(h_rad));
|
|
63577
|
+
}
|
|
63578
|
+
|
|
63579
|
+
vec3 _gpu_srgb_to_oklch(vec3 rgb) {
|
|
63580
|
+
return _gpu_oklab_to_oklch(_gpu_srgb_to_oklab(rgb));
|
|
63581
|
+
}
|
|
63582
|
+
|
|
63583
|
+
vec3 _gpu_oklch_to_srgb(vec3 lch) {
|
|
63584
|
+
return _gpu_oklab_to_srgb(_gpu_oklch_to_oklab(lch));
|
|
63105
63585
|
}
|
|
63106
63586
|
|
|
63107
|
-
|
|
63108
|
-
|
|
63109
|
-
|
|
63587
|
+
// HSL conversion. Hue in degrees, saturation/lightness in 0-1.
|
|
63588
|
+
vec3 _gpu_hsl_to_rgb(vec3 hsl) {
|
|
63589
|
+
float h = hsl.x;
|
|
63590
|
+
float s = hsl.y;
|
|
63591
|
+
float l = hsl.z;
|
|
63592
|
+
float c = (1.0 - abs(2.0 * l - 1.0)) * s;
|
|
63593
|
+
float h6 = h / 60.0;
|
|
63594
|
+
float x = c * (1.0 - abs(mod(h6, 2.0) - 1.0));
|
|
63595
|
+
float r = 0.0;
|
|
63596
|
+
float g = 0.0;
|
|
63597
|
+
float b = 0.0;
|
|
63598
|
+
if (h6 < 1.0) { r = c; g = x; b = 0.0; }
|
|
63599
|
+
else if (h6 < 2.0) { r = x; g = c; b = 0.0; }
|
|
63600
|
+
else if (h6 < 3.0) { r = 0.0; g = c; b = x; }
|
|
63601
|
+
else if (h6 < 4.0) { r = 0.0; g = x; b = c; }
|
|
63602
|
+
else if (h6 < 5.0) { r = x; g = 0.0; b = c; }
|
|
63603
|
+
else { r = c; g = 0.0; b = x; }
|
|
63604
|
+
float m = l - c / 2.0;
|
|
63605
|
+
return vec3(r + m, g + m, b + m);
|
|
63606
|
+
}
|
|
63607
|
+
|
|
63608
|
+
vec3 _gpu_rgb_to_hsl(vec3 rgb) {
|
|
63609
|
+
float maxc = max(max(rgb.x, rgb.y), rgb.z);
|
|
63610
|
+
float minc = min(min(rgb.x, rgb.y), rgb.z);
|
|
63611
|
+
float l = (maxc + minc) / 2.0;
|
|
63612
|
+
float d = maxc - minc;
|
|
63613
|
+
if (d < 1e-6) return vec3(0.0, 0.0, l);
|
|
63614
|
+
float s = d / (1.0 - abs(2.0 * l - 1.0));
|
|
63615
|
+
float h;
|
|
63616
|
+
if (maxc == rgb.x) h = mod((rgb.y - rgb.z) / d, 6.0);
|
|
63617
|
+
else if (maxc == rgb.y) h = (rgb.z - rgb.x) / d + 2.0;
|
|
63618
|
+
else h = (rgb.x - rgb.y) / d + 4.0;
|
|
63619
|
+
h *= 60.0;
|
|
63620
|
+
if (h < 0.0) h += 360.0;
|
|
63621
|
+
return vec3(h, s, l);
|
|
63622
|
+
}
|
|
63623
|
+
|
|
63624
|
+
// HSV conversion. Hue in degrees, saturation/value in 0-1.
|
|
63625
|
+
vec3 _gpu_hsv_to_rgb(vec3 hsv) {
|
|
63626
|
+
float h = hsv.x;
|
|
63627
|
+
float s = hsv.y;
|
|
63628
|
+
float v = hsv.z;
|
|
63629
|
+
float c = v * s;
|
|
63630
|
+
float h6 = h / 60.0;
|
|
63631
|
+
float x = c * (1.0 - abs(mod(h6, 2.0) - 1.0));
|
|
63632
|
+
float r = 0.0;
|
|
63633
|
+
float g = 0.0;
|
|
63634
|
+
float b = 0.0;
|
|
63635
|
+
if (h6 < 1.0) { r = c; g = x; b = 0.0; }
|
|
63636
|
+
else if (h6 < 2.0) { r = x; g = c; b = 0.0; }
|
|
63637
|
+
else if (h6 < 3.0) { r = 0.0; g = c; b = x; }
|
|
63638
|
+
else if (h6 < 4.0) { r = 0.0; g = x; b = c; }
|
|
63639
|
+
else if (h6 < 5.0) { r = x; g = 0.0; b = c; }
|
|
63640
|
+
else { r = c; g = 0.0; b = x; }
|
|
63641
|
+
float m = v - c;
|
|
63642
|
+
return vec3(r + m, g + m, b + m);
|
|
63643
|
+
}
|
|
63644
|
+
|
|
63645
|
+
vec3 _gpu_rgb_to_hsv(vec3 rgb) {
|
|
63646
|
+
float maxc = max(max(rgb.x, rgb.y), rgb.z);
|
|
63647
|
+
float minc = min(min(rgb.x, rgb.y), rgb.z);
|
|
63648
|
+
float v = maxc;
|
|
63649
|
+
float d = maxc - minc;
|
|
63650
|
+
if (d < 1e-6) return vec3(0.0, 0.0, v);
|
|
63651
|
+
float s = (maxc < 1e-6) ? 0.0 : d / maxc;
|
|
63652
|
+
float h;
|
|
63653
|
+
if (maxc == rgb.x) h = mod((rgb.y - rgb.z) / d, 6.0);
|
|
63654
|
+
else if (maxc == rgb.y) h = (rgb.z - rgb.x) / d + 2.0;
|
|
63655
|
+
else h = (rgb.x - rgb.y) / d + 4.0;
|
|
63656
|
+
h *= 60.0;
|
|
63657
|
+
if (h < 0.0) h += 360.0;
|
|
63658
|
+
return vec3(h, s, v);
|
|
63659
|
+
}
|
|
63660
|
+
|
|
63661
|
+
vec3 _gpu_color_mix(vec3 lch1, vec3 lch2, float t) {
|
|
63110
63662
|
float L = mix(lch1.x, lch2.x, t);
|
|
63111
63663
|
float C = mix(lch1.y, lch2.y, t);
|
|
63112
|
-
|
|
63113
|
-
|
|
63114
|
-
|
|
63115
|
-
if (
|
|
63116
|
-
|
|
63117
|
-
|
|
63664
|
+
bool a1 = lch1.y < 1e-6;
|
|
63665
|
+
bool a2 = lch2.y < 1e-6;
|
|
63666
|
+
float H;
|
|
63667
|
+
if (a1 && a2) {
|
|
63668
|
+
H = lch1.z;
|
|
63669
|
+
} else if (a1) {
|
|
63670
|
+
H = lch2.z;
|
|
63671
|
+
} else if (a2) {
|
|
63672
|
+
H = lch1.z;
|
|
63673
|
+
} else {
|
|
63674
|
+
float dh = lch2.z - lch1.z;
|
|
63675
|
+
if (dh > 180.0) dh -= 360.0;
|
|
63676
|
+
if (dh < -180.0) dh += 360.0;
|
|
63677
|
+
H = lch1.z + dh * t;
|
|
63678
|
+
if (H < 0.0) H += 360.0;
|
|
63679
|
+
if (H >= 360.0) H -= 360.0;
|
|
63680
|
+
}
|
|
63681
|
+
return vec3(L, C, H);
|
|
63118
63682
|
}
|
|
63119
63683
|
|
|
63120
|
-
float _gpu_apca(vec3
|
|
63684
|
+
float _gpu_apca(vec3 lch_bg, vec3 lch_fg) {
|
|
63685
|
+
vec3 bg = _gpu_oklch_to_srgb(lch_bg);
|
|
63686
|
+
vec3 fg = _gpu_oklch_to_srgb(lch_fg);
|
|
63121
63687
|
float bgR = _gpu_srgb_to_linear(bg.x);
|
|
63122
63688
|
float bgG = _gpu_srgb_to_linear(bg.y);
|
|
63123
63689
|
float bgB = _gpu_srgb_to_linear(bg.z);
|
|
@@ -63128,9 +63694,7 @@ float _gpu_apca(vec3 bg, vec3 fg) {
|
|
|
63128
63694
|
float fgY = 0.2126729 * fgR + 0.7151522 * fgG + 0.0721750 * fgB;
|
|
63129
63695
|
float bgC = pow(bgY, 0.56);
|
|
63130
63696
|
float fgC = pow(fgY, 0.57);
|
|
63131
|
-
float contrast = (bgC
|
|
63132
|
-
? (bgC - fgC) * 1.14
|
|
63133
|
-
: (bgC - fgC) * 1.14;
|
|
63697
|
+
float contrast = (bgC - fgC) * 1.14;
|
|
63134
63698
|
return contrast * 100.0;
|
|
63135
63699
|
}
|
|
63136
63700
|
`;
|
|
@@ -63174,28 +63738,133 @@ fn _gpu_oklab_to_srgb(lab: vec3f) -> vec3f {
|
|
|
63174
63738
|
|
|
63175
63739
|
fn _gpu_oklab_to_oklch(lab: vec3f) -> vec3f {
|
|
63176
63740
|
let C = length(lab.yz);
|
|
63177
|
-
|
|
63741
|
+
var H = atan2(lab.z, lab.y) * (180.0 / 3.14159265359);
|
|
63742
|
+
if (H < 0.0) { H = H + 360.0; }
|
|
63178
63743
|
return vec3f(lab.x, C, H);
|
|
63179
63744
|
}
|
|
63180
63745
|
|
|
63181
63746
|
fn _gpu_oklch_to_oklab(lch: vec3f) -> vec3f {
|
|
63182
|
-
|
|
63747
|
+
let h_rad = lch.z * (3.14159265359 / 180.0);
|
|
63748
|
+
return vec3f(lch.x, lch.y * cos(h_rad), lch.y * sin(h_rad));
|
|
63749
|
+
}
|
|
63750
|
+
|
|
63751
|
+
fn _gpu_srgb_to_oklch(rgb: vec3f) -> vec3f {
|
|
63752
|
+
return _gpu_oklab_to_oklch(_gpu_srgb_to_oklab(rgb));
|
|
63753
|
+
}
|
|
63754
|
+
|
|
63755
|
+
fn _gpu_oklch_to_srgb(lch: vec3f) -> vec3f {
|
|
63756
|
+
return _gpu_oklab_to_srgb(_gpu_oklch_to_oklab(lch));
|
|
63757
|
+
}
|
|
63758
|
+
|
|
63759
|
+
fn _gpu_hsl_to_rgb(hsl: vec3f) -> vec3f {
|
|
63760
|
+
let h = hsl.x;
|
|
63761
|
+
let s = hsl.y;
|
|
63762
|
+
let l = hsl.z;
|
|
63763
|
+
let c = (1.0 - abs(2.0 * l - 1.0)) * s;
|
|
63764
|
+
let h6 = h / 60.0;
|
|
63765
|
+
let x = c * (1.0 - abs((h6 - 2.0 * floor(h6 / 2.0)) - 1.0));
|
|
63766
|
+
var r: f32 = 0.0;
|
|
63767
|
+
var g: f32 = 0.0;
|
|
63768
|
+
var b: f32 = 0.0;
|
|
63769
|
+
if (h6 < 1.0) { r = c; g = x; b = 0.0; }
|
|
63770
|
+
else if (h6 < 2.0) { r = x; g = c; b = 0.0; }
|
|
63771
|
+
else if (h6 < 3.0) { r = 0.0; g = c; b = x; }
|
|
63772
|
+
else if (h6 < 4.0) { r = 0.0; g = x; b = c; }
|
|
63773
|
+
else if (h6 < 5.0) { r = x; g = 0.0; b = c; }
|
|
63774
|
+
else { r = c; g = 0.0; b = x; }
|
|
63775
|
+
let m = l - c / 2.0;
|
|
63776
|
+
return vec3f(r + m, g + m, b + m);
|
|
63183
63777
|
}
|
|
63184
63778
|
|
|
63185
|
-
fn
|
|
63186
|
-
let
|
|
63187
|
-
let
|
|
63779
|
+
fn _gpu_rgb_to_hsl(rgb: vec3f) -> vec3f {
|
|
63780
|
+
let maxc = max(max(rgb.x, rgb.y), rgb.z);
|
|
63781
|
+
let minc = min(min(rgb.x, rgb.y), rgb.z);
|
|
63782
|
+
let l = (maxc + minc) / 2.0;
|
|
63783
|
+
let d = maxc - minc;
|
|
63784
|
+
if (d < 1e-6) { return vec3f(0.0, 0.0, l); }
|
|
63785
|
+
let s = d / (1.0 - abs(2.0 * l - 1.0));
|
|
63786
|
+
var h: f32;
|
|
63787
|
+
if (maxc == rgb.x) {
|
|
63788
|
+
let v = (rgb.y - rgb.z) / d;
|
|
63789
|
+
h = v - 6.0 * floor(v / 6.0);
|
|
63790
|
+
} else if (maxc == rgb.y) {
|
|
63791
|
+
h = (rgb.z - rgb.x) / d + 2.0;
|
|
63792
|
+
} else {
|
|
63793
|
+
h = (rgb.x - rgb.y) / d + 4.0;
|
|
63794
|
+
}
|
|
63795
|
+
h = h * 60.0;
|
|
63796
|
+
if (h < 0.0) { h = h + 360.0; }
|
|
63797
|
+
return vec3f(h, s, l);
|
|
63798
|
+
}
|
|
63799
|
+
|
|
63800
|
+
fn _gpu_hsv_to_rgb(hsv: vec3f) -> vec3f {
|
|
63801
|
+
let h = hsv.x;
|
|
63802
|
+
let s = hsv.y;
|
|
63803
|
+
let v = hsv.z;
|
|
63804
|
+
let c = v * s;
|
|
63805
|
+
let h6 = h / 60.0;
|
|
63806
|
+
let x = c * (1.0 - abs((h6 - 2.0 * floor(h6 / 2.0)) - 1.0));
|
|
63807
|
+
var r: f32 = 0.0;
|
|
63808
|
+
var g: f32 = 0.0;
|
|
63809
|
+
var b: f32 = 0.0;
|
|
63810
|
+
if (h6 < 1.0) { r = c; g = x; b = 0.0; }
|
|
63811
|
+
else if (h6 < 2.0) { r = x; g = c; b = 0.0; }
|
|
63812
|
+
else if (h6 < 3.0) { r = 0.0; g = c; b = x; }
|
|
63813
|
+
else if (h6 < 4.0) { r = 0.0; g = x; b = c; }
|
|
63814
|
+
else if (h6 < 5.0) { r = x; g = 0.0; b = c; }
|
|
63815
|
+
else { r = c; g = 0.0; b = x; }
|
|
63816
|
+
let m = v - c;
|
|
63817
|
+
return vec3f(r + m, g + m, b + m);
|
|
63818
|
+
}
|
|
63819
|
+
|
|
63820
|
+
fn _gpu_rgb_to_hsv(rgb: vec3f) -> vec3f {
|
|
63821
|
+
let maxc = max(max(rgb.x, rgb.y), rgb.z);
|
|
63822
|
+
let minc = min(min(rgb.x, rgb.y), rgb.z);
|
|
63823
|
+
let v = maxc;
|
|
63824
|
+
let d = maxc - minc;
|
|
63825
|
+
if (d < 1e-6) { return vec3f(0.0, 0.0, v); }
|
|
63826
|
+
var s: f32 = 0.0;
|
|
63827
|
+
if (maxc >= 1e-6) { s = d / maxc; }
|
|
63828
|
+
var h: f32;
|
|
63829
|
+
if (maxc == rgb.x) {
|
|
63830
|
+
let q = (rgb.y - rgb.z) / d;
|
|
63831
|
+
h = q - 6.0 * floor(q / 6.0);
|
|
63832
|
+
} else if (maxc == rgb.y) {
|
|
63833
|
+
h = (rgb.z - rgb.x) / d + 2.0;
|
|
63834
|
+
} else {
|
|
63835
|
+
h = (rgb.x - rgb.y) / d + 4.0;
|
|
63836
|
+
}
|
|
63837
|
+
h = h * 60.0;
|
|
63838
|
+
if (h < 0.0) { h = h + 360.0; }
|
|
63839
|
+
return vec3f(h, s, v);
|
|
63840
|
+
}
|
|
63841
|
+
|
|
63842
|
+
fn _gpu_color_mix(lch1: vec3f, lch2: vec3f, t: f32) -> vec3f {
|
|
63188
63843
|
let L = mix(lch1.x, lch2.x, t);
|
|
63189
63844
|
let C = mix(lch1.y, lch2.y, t);
|
|
63190
|
-
let
|
|
63191
|
-
|
|
63192
|
-
|
|
63193
|
-
if (
|
|
63194
|
-
|
|
63195
|
-
|
|
63845
|
+
let a1 = lch1.y < 1e-6;
|
|
63846
|
+
let a2 = lch2.y < 1e-6;
|
|
63847
|
+
var H: f32;
|
|
63848
|
+
if (a1 && a2) {
|
|
63849
|
+
H = lch1.z;
|
|
63850
|
+
} else if (a1) {
|
|
63851
|
+
H = lch2.z;
|
|
63852
|
+
} else if (a2) {
|
|
63853
|
+
H = lch1.z;
|
|
63854
|
+
} else {
|
|
63855
|
+
var dh = lch2.z - lch1.z;
|
|
63856
|
+
if (dh > 180.0) { dh = dh - 360.0; }
|
|
63857
|
+
if (dh < -180.0) { dh = dh + 360.0; }
|
|
63858
|
+
H = lch1.z + dh * t;
|
|
63859
|
+
if (H < 0.0) { H = H + 360.0; }
|
|
63860
|
+
if (H >= 360.0) { H = H - 360.0; }
|
|
63861
|
+
}
|
|
63862
|
+
return vec3f(L, C, H);
|
|
63196
63863
|
}
|
|
63197
63864
|
|
|
63198
|
-
fn _gpu_apca(
|
|
63865
|
+
fn _gpu_apca(lch_bg: vec3f, lch_fg: vec3f) -> f32 {
|
|
63866
|
+
let bg = _gpu_oklch_to_srgb(lch_bg);
|
|
63867
|
+
let fg = _gpu_oklch_to_srgb(lch_fg);
|
|
63199
63868
|
let bgR = _gpu_srgb_to_linear(bg.x);
|
|
63200
63869
|
let bgG = _gpu_srgb_to_linear(bg.y);
|
|
63201
63870
|
let bgB = _gpu_srgb_to_linear(bg.z);
|
|
@@ -63483,7 +64152,7 @@ fn _gpu_apca(bg: vec3f, fg: vec3f) -> f32 {
|
|
|
63483
64152
|
if (stmts.length === 0) return "";
|
|
63484
64153
|
const last = stmts.length - 1;
|
|
63485
64154
|
stmts[last] = `return ${stmts[last]}`;
|
|
63486
|
-
return stmts.join(";\n");
|
|
64155
|
+
return stmts.join(";\n") + ";";
|
|
63487
64156
|
},
|
|
63488
64157
|
...options
|
|
63489
64158
|
};
|
|
@@ -63494,7 +64163,6 @@ fn _gpu_apca(bg: vec3f, fg: vec3f) -> f32 {
|
|
|
63494
64163
|
const constants = this.getConstants();
|
|
63495
64164
|
const v2 = this.languageId === "wgsl" ? "vec2f" : "vec2";
|
|
63496
64165
|
const target = this.createTarget({
|
|
63497
|
-
hints: options.hints,
|
|
63498
64166
|
functions: (id) => {
|
|
63499
64167
|
if (userFunctions && id in userFunctions) {
|
|
63500
64168
|
const fn = userFunctions[id];
|
|
@@ -63533,89 +64201,12 @@ fn _gpu_apca(bg: vec3f, fg: vec3f) -> f32 {
|
|
|
63533
64201
|
if (code.includes("_gpu_besselJ"))
|
|
63534
64202
|
preamble += this.languageId === "wgsl" ? GPU_BESSELJ_PREAMBLE_WGSL : GPU_BESSELJ_PREAMBLE_GLSL;
|
|
63535
64203
|
if (code.includes("_fractal_")) {
|
|
63536
|
-
|
|
63537
|
-
preamble += this.languageId === "wgsl" ? GPU_DS_ARITHMETIC_PREAMBLE_WGSL : GPU_DS_ARITHMETIC_PREAMBLE_GLSL;
|
|
63538
|
-
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PT_PREAMBLE_WGSL : GPU_FRACTAL_PT_PREAMBLE_GLSL;
|
|
63539
|
-
} else if (code.includes("_fractal_mandelbrot_dp") || code.includes("_fractal_julia_dp")) {
|
|
63540
|
-
preamble += this.languageId === "wgsl" ? GPU_DS_ARITHMETIC_PREAMBLE_WGSL : GPU_DS_ARITHMETIC_PREAMBLE_GLSL;
|
|
63541
|
-
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_DP_PREAMBLE_WGSL : GPU_FRACTAL_DP_PREAMBLE_GLSL;
|
|
63542
|
-
} else {
|
|
63543
|
-
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PREAMBLE_WGSL : GPU_FRACTAL_PREAMBLE_GLSL;
|
|
63544
|
-
}
|
|
64204
|
+
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PREAMBLE_WGSL : GPU_FRACTAL_PREAMBLE_GLSL;
|
|
63545
64205
|
}
|
|
63546
64206
|
if (code.includes("_gpu_srgb_to") || code.includes("_gpu_oklab") || code.includes("_gpu_oklch") || code.includes("_gpu_color_mix") || code.includes("_gpu_apca")) {
|
|
63547
64207
|
preamble += this.languageId === "wgsl" ? GPU_COLOR_PREAMBLE_WGSL : GPU_COLOR_PREAMBLE_GLSL;
|
|
63548
64208
|
}
|
|
63549
64209
|
if (preamble) result.preamble = preamble;
|
|
63550
|
-
if (code.includes("_fractal_") && options.hints?.viewport) {
|
|
63551
|
-
const strategy = selectFractalStrategy(target);
|
|
63552
|
-
const radius = options.hints.viewport.radius;
|
|
63553
|
-
switch (strategy) {
|
|
63554
|
-
case "single":
|
|
63555
|
-
result.staleWhen = { radiusBelow: 1e-6 };
|
|
63556
|
-
break;
|
|
63557
|
-
case "double":
|
|
63558
|
-
result.staleWhen = { radiusBelow: 1e-14, radiusAbove: 1e-5 };
|
|
63559
|
-
break;
|
|
63560
|
-
case "perturbation":
|
|
63561
|
-
result.staleWhen = {
|
|
63562
|
-
radiusAbove: 1e-5,
|
|
63563
|
-
radiusBelow: radius * 0.01,
|
|
63564
|
-
centerDistance: radius * 2
|
|
63565
|
-
};
|
|
63566
|
-
break;
|
|
63567
|
-
}
|
|
63568
|
-
}
|
|
63569
|
-
if ((code.includes("_fractal_mandelbrot_dp") || code.includes("_fractal_julia_dp")) && options.hints?.viewport) {
|
|
63570
|
-
const cx = hpToNumber(options.hints.viewport.center[0]);
|
|
63571
|
-
const cy = hpToNumber(options.hints.viewport.center[1]);
|
|
63572
|
-
const size = options.hints.viewport.radius * 2;
|
|
63573
|
-
const cx_hi = Math.fround(cx);
|
|
63574
|
-
const cy_hi = Math.fround(cy);
|
|
63575
|
-
result.uniforms = {
|
|
63576
|
-
...result.uniforms,
|
|
63577
|
-
_dp_cx_hi: cx_hi,
|
|
63578
|
-
_dp_cx_lo: cx - cx_hi,
|
|
63579
|
-
_dp_cy_hi: cy_hi,
|
|
63580
|
-
_dp_cy_lo: cy - cy_hi,
|
|
63581
|
-
_dp_w: size,
|
|
63582
|
-
_dp_h: size
|
|
63583
|
-
};
|
|
63584
|
-
}
|
|
63585
|
-
if ((code.includes("_fractal_mandelbrot_pt") || code.includes("_fractal_julia_pt")) && options.hints?.viewport) {
|
|
63586
|
-
const viewport = options.hints.viewport;
|
|
63587
|
-
const size = viewport.radius * 2;
|
|
63588
|
-
result.uniforms = {
|
|
63589
|
-
...result.uniforms,
|
|
63590
|
-
_pt_offset_x: 0,
|
|
63591
|
-
_pt_offset_y: 0,
|
|
63592
|
-
_pt_w: size,
|
|
63593
|
-
_pt_h: size
|
|
63594
|
-
};
|
|
63595
|
-
const digits = Math.max(50, Math.ceil(-Math.log10(viewport.radius)) + 10);
|
|
63596
|
-
const maxIter = 1e3;
|
|
63597
|
-
const orbit = computeReferenceOrbit(
|
|
63598
|
-
viewport.center,
|
|
63599
|
-
maxIter,
|
|
63600
|
-
digits
|
|
63601
|
-
);
|
|
63602
|
-
const orbitLen = orbit.length / 2;
|
|
63603
|
-
const texWidth = Math.min(orbitLen, 4096);
|
|
63604
|
-
const texHeight = Math.ceil(orbitLen / texWidth);
|
|
63605
|
-
result.textures = {
|
|
63606
|
-
_refOrbit: {
|
|
63607
|
-
data: orbit,
|
|
63608
|
-
width: texWidth,
|
|
63609
|
-
height: texHeight,
|
|
63610
|
-
format: "rg32f"
|
|
63611
|
-
}
|
|
63612
|
-
};
|
|
63613
|
-
result.uniforms = {
|
|
63614
|
-
...result.uniforms,
|
|
63615
|
-
_refOrbitLen: orbitLen,
|
|
63616
|
-
_refOrbitTexWidth: texWidth
|
|
63617
|
-
};
|
|
63618
|
-
}
|
|
63619
64210
|
return result;
|
|
63620
64211
|
}
|
|
63621
64212
|
compileToSource(expr2, _options = {}) {
|
|
@@ -63660,7 +64251,7 @@ fn _gpu_apca(bg: vec3f, fg: vec3f) -> f32 {
|
|
|
63660
64251
|
if (body.includes("\n")) {
|
|
63661
64252
|
const indented = body.split("\n").map((l) => ` ${l}`).join("\n");
|
|
63662
64253
|
return `${returnType} ${functionName}(${params}) {
|
|
63663
|
-
${indented}
|
|
64254
|
+
${indented}
|
|
63664
64255
|
}`;
|
|
63665
64256
|
}
|
|
63666
64257
|
return `${returnType} ${functionName}(${params}) {
|
|
@@ -63771,7 +64362,7 @@ ${indented};
|
|
|
63771
64362
|
return `fn ${functionName}(${params}) -> ${toWGSLType(
|
|
63772
64363
|
returnType
|
|
63773
64364
|
)} {
|
|
63774
|
-
${indented}
|
|
64365
|
+
${indented}
|
|
63775
64366
|
}`;
|
|
63776
64367
|
}
|
|
63777
64368
|
return `fn ${functionName}(${params}) -> ${toWGSLType(returnType)} {
|
|
@@ -68178,6 +68769,7 @@ ${code}`;
|
|
|
68178
68769
|
this.pushScope(void 0, "global");
|
|
68179
68770
|
this._compilationTargets.registerDefaults();
|
|
68180
68771
|
if (options?.latexSyntax) this._latexSyntax = options.latexSyntax;
|
|
68772
|
+
if (options?.latexOptions) this._latexOptions = { ...options.latexOptions };
|
|
68181
68773
|
hidePrivateProperties(this);
|
|
68182
68774
|
}
|
|
68183
68775
|
toJSON() {
|
|
@@ -68838,6 +69430,29 @@ ${code}`;
|
|
|
68838
69430
|
);
|
|
68839
69431
|
return this._latexSyntax;
|
|
68840
69432
|
}
|
|
69433
|
+
/** @internal Engine-wide LaTeX parse/serialize options (e.g. decimalSeparator).
|
|
69434
|
+
* Merged into every `parse()` and `toLatex()` call between the LatexSyntax
|
|
69435
|
+
* instance defaults and any per-call overrides. */
|
|
69436
|
+
_latexOptions = {};
|
|
69437
|
+
/** Engine-wide LaTeX parse/serialize options.
|
|
69438
|
+
*
|
|
69439
|
+
* These options are merged into every `parse()` and `toLatex()` call.
|
|
69440
|
+
* Precedence (most-specific wins):
|
|
69441
|
+
* 1. LatexSyntax instance defaults (set at its construction)
|
|
69442
|
+
* 2. `ce.latexOptions` (this property)
|
|
69443
|
+
* 3. Per-call options passed to `ce.parse()` / `expr.toLatex()`
|
|
69444
|
+
*
|
|
69445
|
+
* Assigning replaces the whole bag. Use spread to merge:
|
|
69446
|
+
* ```ts
|
|
69447
|
+
* ce.latexOptions = { ...ce.latexOptions, decimalSeparator: '{,}' };
|
|
69448
|
+
* ```
|
|
69449
|
+
*/
|
|
69450
|
+
get latexOptions() {
|
|
69451
|
+
return this._latexOptions;
|
|
69452
|
+
}
|
|
69453
|
+
set latexOptions(options) {
|
|
69454
|
+
this._latexOptions = { ...options };
|
|
69455
|
+
}
|
|
68841
69456
|
parse(latex, options) {
|
|
68842
69457
|
if (latex === null || latex === void 0) return null;
|
|
68843
69458
|
if (typeof latex !== "string")
|
|
@@ -68845,7 +69460,6 @@ ${code}`;
|
|
|
68845
69460
|
const syntax = this._requireLatexSyntax();
|
|
68846
69461
|
const { form, ...parseOpts } = options ?? {};
|
|
68847
69462
|
const result = syntax.parse(latex, {
|
|
68848
|
-
decimalSeparator: ".",
|
|
68849
69463
|
getSymbolType: (id) => {
|
|
68850
69464
|
const def = this.lookupDefinition(id);
|
|
68851
69465
|
if (!def) return BoxedType.unknown;
|
|
@@ -68857,6 +69471,7 @@ ${code}`;
|
|
|
68857
69471
|
const def = this.lookupDefinition(id);
|
|
68858
69472
|
return !!(isValueDef(def) && def.value.subscriptEvaluate);
|
|
68859
69473
|
},
|
|
69474
|
+
...this._latexOptions,
|
|
68860
69475
|
...parseOpts
|
|
68861
69476
|
});
|
|
68862
69477
|
if (result === null) return null;
|
|
@@ -69020,14 +69635,14 @@ ${code}`;
|
|
|
69020
69635
|
_setDefaultEngineFactory(() => new ComputeEngine());
|
|
69021
69636
|
|
|
69022
69637
|
// src/compute-engine.ts
|
|
69023
|
-
var version = "0.
|
|
69638
|
+
var version = "0.56.0";
|
|
69024
69639
|
ComputeEngine._latexSyntaxFactory = () => new LatexSyntax();
|
|
69025
69640
|
_setDefaultEngineFactory(
|
|
69026
69641
|
() => new ComputeEngine({ latexSyntax: new LatexSyntax() })
|
|
69027
69642
|
);
|
|
69028
69643
|
globalThis[/* @__PURE__ */ Symbol.for("io.cortexjs.compute-engine")] = {
|
|
69029
69644
|
ComputeEngine: ComputeEngine.prototype.constructor,
|
|
69030
|
-
version: "0.
|
|
69645
|
+
version: "0.56.0"
|
|
69031
69646
|
};
|
|
69032
69647
|
return __toCommonJS(compute_engine_exports);
|
|
69033
69648
|
})();
|