@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
|
|
|
3
3
|
// node_modules/complex-esm/dist/src/complex.js
|
|
4
4
|
var cosh = Math.cosh || function(x) {
|
|
@@ -2240,6 +2240,7 @@ var SCALAR_TYPES = [
|
|
|
2240
2240
|
];
|
|
2241
2241
|
var VALUE_TYPES = [
|
|
2242
2242
|
"value",
|
|
2243
|
+
"color",
|
|
2243
2244
|
...COLLECTION_TYPES,
|
|
2244
2245
|
...SCALAR_TYPES
|
|
2245
2246
|
];
|
|
@@ -3939,6 +3940,7 @@ var PRIMITIVE_SUBTYPES = {
|
|
|
3939
3940
|
symbol: [],
|
|
3940
3941
|
boolean: [],
|
|
3941
3942
|
string: [],
|
|
3943
|
+
color: [],
|
|
3942
3944
|
expression: EXPRESSION_TYPES
|
|
3943
3945
|
};
|
|
3944
3946
|
function isPrimitiveSubtype(lhs, rhs) {
|
|
@@ -7822,9 +7824,10 @@ var _BoxedExpression = class __BoxedExpression {
|
|
|
7822
7824
|
if (!materialized.isLazyCollection) return materialized.latex;
|
|
7823
7825
|
}
|
|
7824
7826
|
const syntax = this.engine._requireLatexSyntax();
|
|
7825
|
-
|
|
7826
|
-
|
|
7827
|
-
);
|
|
7827
|
+
const json = this.toMathJson({ prettify: true, fractionalDigits: "auto" });
|
|
7828
|
+
const latexOpts = this.engine.latexOptions;
|
|
7829
|
+
if (Object.keys(latexOpts).length === 0) return syntax.serialize(json);
|
|
7830
|
+
return syntax.serialize(json, { ...latexOpts });
|
|
7828
7831
|
}
|
|
7829
7832
|
/**
|
|
7830
7833
|
* Return a LaTeX representation of this expression with custom
|
|
@@ -7848,9 +7851,13 @@ var _BoxedExpression = class __BoxedExpression {
|
|
|
7848
7851
|
fractionalDigits: "auto"
|
|
7849
7852
|
});
|
|
7850
7853
|
const syntax = this.engine._requireLatexSyntax();
|
|
7851
|
-
|
|
7852
|
-
|
|
7853
|
-
|
|
7854
|
+
const latexOpts = this.engine.latexOptions;
|
|
7855
|
+
const haveEngineOpts = Object.keys(latexOpts).length > 0;
|
|
7856
|
+
const haveCallOpts = options && Object.keys(options).length > 0;
|
|
7857
|
+
if (!haveEngineOpts && !haveCallOpts) return syntax.serialize(json);
|
|
7858
|
+
if (!haveEngineOpts) return syntax.serialize(json, options);
|
|
7859
|
+
if (!haveCallOpts) return syntax.serialize(json, { ...latexOpts });
|
|
7860
|
+
return syntax.serialize(json, { ...latexOpts, ...options });
|
|
7854
7861
|
}
|
|
7855
7862
|
/** Called by `JSON.stringify()` when serializing to json.
|
|
7856
7863
|
*
|
|
@@ -7894,11 +7901,13 @@ var _BoxedExpression = class __BoxedExpression {
|
|
|
7894
7901
|
"number",
|
|
7895
7902
|
"dictionary"
|
|
7896
7903
|
];
|
|
7897
|
-
}
|
|
7898
|
-
if (Array.isArray(options.shorthands))
|
|
7904
|
+
} else if (Array.isArray(options.shorthands)) {
|
|
7899
7905
|
defaultOptions.shorthands = options.shorthands;
|
|
7906
|
+
}
|
|
7900
7907
|
if (typeof options.metadata === "string" && options.metadata === "all" || options.metadata?.includes("all")) {
|
|
7901
7908
|
defaultOptions.metadata = ["latex", "wikidata"];
|
|
7909
|
+
} else if (Array.isArray(options.metadata)) {
|
|
7910
|
+
defaultOptions.metadata = options.metadata;
|
|
7902
7911
|
}
|
|
7903
7912
|
if (options.fractionalDigits === "auto")
|
|
7904
7913
|
defaultOptions.fractionalDigits = -this.engine.precision;
|
|
@@ -11037,10 +11046,6 @@ var DEFINITIONS_CORE = [
|
|
|
11037
11046
|
// Lagrange notation
|
|
11038
11047
|
{
|
|
11039
11048
|
name: "Derivative",
|
|
11040
|
-
// @todo: Leibniz notation: {% latex " \\frac{d^n}{dx^n} f(x)" %}
|
|
11041
|
-
// @todo: Euler modified notation: This notation is used by Mathematica. The Euler notation uses `D` instead of
|
|
11042
|
-
// `\partial`: `\partial_{x} f`, `\partial_{x,y} f`
|
|
11043
|
-
// Newton notation (\dot{v}, \ddot{v}) is implemented below
|
|
11044
11049
|
serialize: (serializer, expr2) => {
|
|
11045
11050
|
const degree = machineValue(operand(expr2, 2)) ?? 1;
|
|
11046
11051
|
const base = serializer.serialize(operand(expr2, 1));
|
|
@@ -12078,14 +12083,18 @@ var DEFINITIONS_SETS = [
|
|
|
12078
12083
|
return ["Complement", lhs];
|
|
12079
12084
|
}
|
|
12080
12085
|
// precedence: 240,
|
|
12081
|
-
// @todo: serialize for the multiple argument case
|
|
12082
12086
|
},
|
|
12083
12087
|
{
|
|
12084
12088
|
name: "Complement",
|
|
12085
12089
|
latexTrigger: ["^", "<{>", "\\complement", "<}>"],
|
|
12086
|
-
kind: "postfix"
|
|
12090
|
+
kind: "postfix",
|
|
12087
12091
|
// precedence: 240,
|
|
12088
|
-
|
|
12092
|
+
serialize: (serializer, expr2) => {
|
|
12093
|
+
return joinLatex([
|
|
12094
|
+
serializer.serialize(operand(expr2, 1)),
|
|
12095
|
+
"^\\complement"
|
|
12096
|
+
]);
|
|
12097
|
+
}
|
|
12089
12098
|
},
|
|
12090
12099
|
{
|
|
12091
12100
|
name: "Intersection",
|
|
@@ -12172,7 +12181,6 @@ var DEFINITIONS_SETS = [
|
|
|
12172
12181
|
// commands like \rbrack a, b \rbrack which are unambiguous.
|
|
12173
12182
|
{
|
|
12174
12183
|
name: "Multiple",
|
|
12175
|
-
// @todo: parse
|
|
12176
12184
|
serialize: serializeSet
|
|
12177
12185
|
},
|
|
12178
12186
|
{
|
|
@@ -12181,14 +12189,28 @@ var DEFINITIONS_SETS = [
|
|
|
12181
12189
|
kind: "infix",
|
|
12182
12190
|
precedence: 350
|
|
12183
12191
|
},
|
|
12192
|
+
// \mid as a separator/operator (used in set-builder notation: {x \mid x > 0})
|
|
12193
|
+
// Low precedence so it binds loosely — everything on each side is parsed first
|
|
12194
|
+
{
|
|
12195
|
+
name: "Divides",
|
|
12196
|
+
latexTrigger: ["\\mid"],
|
|
12197
|
+
kind: "infix",
|
|
12198
|
+
precedence: 160
|
|
12199
|
+
},
|
|
12184
12200
|
{
|
|
12185
12201
|
name: "Set",
|
|
12186
12202
|
kind: "matchfix",
|
|
12187
12203
|
openTrigger: "{",
|
|
12188
12204
|
closeTrigger: "}",
|
|
12189
|
-
// @todo: the set syntax can also include conditions...
|
|
12190
12205
|
parse: (_parser, body) => {
|
|
12191
12206
|
if (isEmptySequence(body)) return "EmptySet";
|
|
12207
|
+
const h = operator(body);
|
|
12208
|
+
if (h === "Divides" || h === "Colon") {
|
|
12209
|
+
const expr2 = operand(body, 1);
|
|
12210
|
+
const condition = operand(body, 2);
|
|
12211
|
+
if (expr2 !== null && condition !== null)
|
|
12212
|
+
return ["Set", expr2, ["Condition", condition]];
|
|
12213
|
+
}
|
|
12192
12214
|
if (operator(body) == "Delimiter" && stringValue(operand(body, 2)) === ",") {
|
|
12193
12215
|
body = operand(body, 1);
|
|
12194
12216
|
}
|
|
@@ -12196,6 +12218,17 @@ var DEFINITIONS_SETS = [
|
|
|
12196
12218
|
return ["Set", ...operands(body)];
|
|
12197
12219
|
},
|
|
12198
12220
|
serialize: (serializer, expr2) => {
|
|
12221
|
+
if (nops(expr2) === 2 && operator(operand(expr2, 2)) === "Condition") {
|
|
12222
|
+
const condition = operand(expr2, 2);
|
|
12223
|
+
return joinLatex([
|
|
12224
|
+
"\\lbrace",
|
|
12225
|
+
serializer.serialize(operand(expr2, 1)),
|
|
12226
|
+
"\\mid",
|
|
12227
|
+
// Serialize the inner expression of the Condition wrapper
|
|
12228
|
+
serializer.serialize(operand(condition, 1)),
|
|
12229
|
+
"\\rbrace"
|
|
12230
|
+
]);
|
|
12231
|
+
}
|
|
12199
12232
|
return joinLatex([
|
|
12200
12233
|
"\\lbrace",
|
|
12201
12234
|
operands(expr2).map((x) => serializer.serialize(x)).join(", "),
|
|
@@ -12362,23 +12395,6 @@ function serializeSet(serializer, expr2) {
|
|
|
12362
12395
|
if (expr2 === null) return "";
|
|
12363
12396
|
const h = operator(expr2);
|
|
12364
12397
|
if (!h) return "";
|
|
12365
|
-
if (h === "Set") {
|
|
12366
|
-
if (nops(expr2) === 0) return "\\emptyset";
|
|
12367
|
-
if (nops(expr2) === 2 && operator(operand(expr2, 2)) === "Condition") {
|
|
12368
|
-
return joinLatex([
|
|
12369
|
-
"\\left\\lbrace",
|
|
12370
|
-
serializer.serialize(operand(expr2, 1)),
|
|
12371
|
-
"\\middle\\mid",
|
|
12372
|
-
serializer.serialize(operand(expr2, 2)),
|
|
12373
|
-
"\\right\\rbrace"
|
|
12374
|
-
]);
|
|
12375
|
-
}
|
|
12376
|
-
return joinLatex([
|
|
12377
|
-
"\\left\\lbrace",
|
|
12378
|
-
...operands(expr2).map((x) => serializer.serialize(x) + " ,"),
|
|
12379
|
-
"\\right\\rbrace"
|
|
12380
|
-
]);
|
|
12381
|
-
}
|
|
12382
12398
|
if (h === "Multiple") {
|
|
12383
12399
|
}
|
|
12384
12400
|
if (h === "Range") {
|
|
@@ -13526,11 +13542,13 @@ var DEFINITIONS_ARITHMETIC = [
|
|
|
13526
13542
|
if (!parser.match("_")) return null;
|
|
13527
13543
|
const base = parser.parseGroup();
|
|
13528
13544
|
if (operator(base) !== "To") return null;
|
|
13529
|
-
const expr2 = parser.
|
|
13545
|
+
const expr2 = parser.parseExpression({
|
|
13546
|
+
minPrec: MULTIPLICATION_PRECEDENCE
|
|
13547
|
+
});
|
|
13530
13548
|
if (!expr2) return null;
|
|
13531
13549
|
return [
|
|
13532
13550
|
"Limit",
|
|
13533
|
-
["Function", expr2
|
|
13551
|
+
["Function", expr2, operand(base, 1)],
|
|
13534
13552
|
operand(base, 2)
|
|
13535
13553
|
];
|
|
13536
13554
|
},
|
|
@@ -13611,6 +13629,8 @@ var DEFINITIONS_ARITHMETIC = [
|
|
|
13611
13629
|
precedence: DIVISION_PRECEDENCE,
|
|
13612
13630
|
parse: "Mod"
|
|
13613
13631
|
},
|
|
13632
|
+
// Function-style alias: `\operatorname{mod}(a, b)`
|
|
13633
|
+
{ latexTrigger: "\\operatorname{mod}", parse: "Mod" },
|
|
13614
13634
|
{
|
|
13615
13635
|
latexTrigger: "\\pmod",
|
|
13616
13636
|
kind: "prefix",
|
|
@@ -13851,6 +13871,13 @@ var DEFINITIONS_ARITHMETIC = [
|
|
|
13851
13871
|
const rhs = serializer.wrap(operand(expr2, 2), ADDITION_PRECEDENCE + 3);
|
|
13852
13872
|
return joinLatex([lhs, "-", rhs]);
|
|
13853
13873
|
}
|
|
13874
|
+
},
|
|
13875
|
+
// Euclidean distance between two points (tuples of numbers).
|
|
13876
|
+
{
|
|
13877
|
+
name: "Distance",
|
|
13878
|
+
latexTrigger: ["\\operatorname{distance}"],
|
|
13879
|
+
kind: "function",
|
|
13880
|
+
serialize: (serializer, expr2) => "\\operatorname{distance}" + serializer.wrapArguments(expr2)
|
|
13854
13881
|
}
|
|
13855
13882
|
];
|
|
13856
13883
|
function getIndexAssignment(expr2, upper) {
|
|
@@ -15275,7 +15302,9 @@ var DEFINITIONS_STATISTICS = [
|
|
|
15275
15302
|
if (!expr2 || !symbol(expr2)) return null;
|
|
15276
15303
|
return ["Mean", expr2];
|
|
15277
15304
|
}
|
|
15278
|
-
}
|
|
15305
|
+
},
|
|
15306
|
+
// Function-style alias: `\operatorname{var}(...)`
|
|
15307
|
+
{ latexTrigger: "\\operatorname{var}", parse: "Variance" }
|
|
15279
15308
|
];
|
|
15280
15309
|
|
|
15281
15310
|
// src/compute-engine/numerics/unit-data.ts
|
|
@@ -15827,12 +15856,52 @@ var DEFINITIONS_UNITS = [
|
|
|
15827
15856
|
];
|
|
15828
15857
|
|
|
15829
15858
|
// src/compute-engine/latex-syntax/dictionary/definitions-other.ts
|
|
15859
|
+
var TEX_UNITS = [
|
|
15860
|
+
"pt",
|
|
15861
|
+
"em",
|
|
15862
|
+
"mu",
|
|
15863
|
+
"ex",
|
|
15864
|
+
"mm",
|
|
15865
|
+
"cm",
|
|
15866
|
+
"in",
|
|
15867
|
+
"bp",
|
|
15868
|
+
"sp",
|
|
15869
|
+
"dd",
|
|
15870
|
+
"cc",
|
|
15871
|
+
"pc",
|
|
15872
|
+
"nc",
|
|
15873
|
+
"nd"
|
|
15874
|
+
];
|
|
15875
|
+
function skipTexDimension(parser) {
|
|
15876
|
+
parser.skipSpace();
|
|
15877
|
+
if (parser.peek === "-" || parser.peek === "+") parser.nextToken();
|
|
15878
|
+
while (/^[\d.]$/.test(parser.peek)) parser.nextToken();
|
|
15879
|
+
for (const unit of TEX_UNITS) {
|
|
15880
|
+
if (parser.matchAll([...unit])) return;
|
|
15881
|
+
}
|
|
15882
|
+
}
|
|
15830
15883
|
function parseSingleArg(cmd) {
|
|
15831
15884
|
return (parser) => {
|
|
15832
15885
|
const arg = parser.parseGroup();
|
|
15833
15886
|
return arg === null ? [cmd] : [cmd, arg];
|
|
15834
15887
|
};
|
|
15835
15888
|
}
|
|
15889
|
+
function parseMathStyleSwitch(mathStyle) {
|
|
15890
|
+
return (parser) => {
|
|
15891
|
+
const body = parser.parseExpression();
|
|
15892
|
+
if (body !== null && !isEmptySequence(body))
|
|
15893
|
+
return ["Annotated", body, { dict: { mathStyle } }];
|
|
15894
|
+
return "Nothing";
|
|
15895
|
+
};
|
|
15896
|
+
}
|
|
15897
|
+
function parseSizeSwitch(size) {
|
|
15898
|
+
return (parser) => {
|
|
15899
|
+
const body = parser.parseExpression();
|
|
15900
|
+
if (body !== null && !isEmptySequence(body))
|
|
15901
|
+
return ["Annotated", body, { dict: { size } }];
|
|
15902
|
+
return "Nothing";
|
|
15903
|
+
};
|
|
15904
|
+
}
|
|
15836
15905
|
var DEFINITIONS_OTHERS = [
|
|
15837
15906
|
{
|
|
15838
15907
|
name: "Overscript",
|
|
@@ -16072,80 +16141,71 @@ var DEFINITIONS_OTHERS = [
|
|
|
16072
16141
|
},
|
|
16073
16142
|
{
|
|
16074
16143
|
latexTrigger: ["\\displaystyle"],
|
|
16075
|
-
parse: (
|
|
16076
|
-
// @todo: parse as ['Annotated'...]
|
|
16144
|
+
parse: parseMathStyleSwitch("normal")
|
|
16077
16145
|
},
|
|
16078
16146
|
{
|
|
16079
16147
|
latexTrigger: ["\\textstyle"],
|
|
16080
|
-
parse: (
|
|
16081
|
-
// @todo: parse as ['Annotated'...]
|
|
16148
|
+
parse: parseMathStyleSwitch("compact")
|
|
16082
16149
|
},
|
|
16083
16150
|
{
|
|
16084
16151
|
latexTrigger: ["\\scriptstyle"],
|
|
16085
|
-
parse: (
|
|
16086
|
-
// @todo: parse as ['Annotated'...]
|
|
16152
|
+
parse: parseMathStyleSwitch("script")
|
|
16087
16153
|
},
|
|
16088
16154
|
{
|
|
16089
16155
|
latexTrigger: ["\\scriptscriptstyle"],
|
|
16090
|
-
parse: (
|
|
16091
|
-
// @todo: parse as ['Annotated'...]
|
|
16156
|
+
parse: parseMathStyleSwitch("scriptscript")
|
|
16092
16157
|
},
|
|
16093
16158
|
{
|
|
16094
16159
|
latexTrigger: ["\\color"],
|
|
16095
16160
|
parse: (parser) => {
|
|
16096
|
-
parser.
|
|
16161
|
+
const color = parser.parseStringGroup();
|
|
16162
|
+
if (color !== null) {
|
|
16163
|
+
const body = parser.parseExpression();
|
|
16164
|
+
if (body !== null && !isEmptySequence(body))
|
|
16165
|
+
return ["Annotated", body, { dict: { color } }];
|
|
16166
|
+
}
|
|
16097
16167
|
return "Nothing";
|
|
16098
16168
|
}
|
|
16099
16169
|
},
|
|
16100
16170
|
{
|
|
16101
16171
|
latexTrigger: ["\\tiny"],
|
|
16102
|
-
parse: ()
|
|
16103
|
-
// @todo: parse as ['Annotated'...]
|
|
16172
|
+
parse: parseSizeSwitch(1)
|
|
16104
16173
|
},
|
|
16105
16174
|
{
|
|
16106
16175
|
latexTrigger: ["\\scriptsize"],
|
|
16107
|
-
parse: ()
|
|
16108
|
-
// @todo: parse as ['Annotated'...]
|
|
16176
|
+
parse: parseSizeSwitch(2)
|
|
16109
16177
|
},
|
|
16110
16178
|
{
|
|
16111
16179
|
latexTrigger: ["\\footnotesize"],
|
|
16112
|
-
parse: ()
|
|
16113
|
-
// @todo: parse as ['Annotated'...]
|
|
16180
|
+
parse: parseSizeSwitch(3)
|
|
16114
16181
|
},
|
|
16115
16182
|
{
|
|
16116
16183
|
latexTrigger: ["\\small"],
|
|
16117
|
-
parse: ()
|
|
16118
|
-
// @todo: parse as ['Annotated'...]
|
|
16184
|
+
parse: parseSizeSwitch(4)
|
|
16119
16185
|
},
|
|
16120
16186
|
{
|
|
16121
16187
|
latexTrigger: ["\\normalsize"],
|
|
16122
|
-
parse: ()
|
|
16123
|
-
// @todo: parse as ['Annotated'...]
|
|
16188
|
+
parse: parseSizeSwitch(5)
|
|
16124
16189
|
},
|
|
16125
16190
|
{
|
|
16126
16191
|
latexTrigger: ["\\large"],
|
|
16127
|
-
parse: ()
|
|
16128
|
-
// @todo: parse as ['Annotated'...]
|
|
16192
|
+
parse: parseSizeSwitch(6)
|
|
16129
16193
|
},
|
|
16130
16194
|
{
|
|
16131
16195
|
latexTrigger: ["\\Large"],
|
|
16132
|
-
parse: ()
|
|
16133
|
-
// @todo: parse as ['Annotated'...]
|
|
16196
|
+
parse: parseSizeSwitch(7)
|
|
16134
16197
|
},
|
|
16135
16198
|
{
|
|
16136
16199
|
latexTrigger: ["\\LARGE"],
|
|
16137
|
-
parse: ()
|
|
16138
|
-
// @todo: parse as ['Annotated'...]
|
|
16200
|
+
parse: parseSizeSwitch(8)
|
|
16139
16201
|
},
|
|
16140
16202
|
{
|
|
16141
16203
|
latexTrigger: ["\\huge"],
|
|
16142
|
-
parse: ()
|
|
16143
|
-
// @todo: parse as ['Annotated'...]
|
|
16204
|
+
parse: parseSizeSwitch(9)
|
|
16144
16205
|
},
|
|
16145
16206
|
{
|
|
16146
16207
|
latexTrigger: ["\\Huge"],
|
|
16147
|
-
parse: ()
|
|
16148
|
-
// @todo: parse as ['Annotated'...]
|
|
16208
|
+
parse: parseSizeSwitch(10)
|
|
16149
16209
|
},
|
|
16150
16210
|
{
|
|
16151
16211
|
name: "Annotated",
|
|
@@ -16157,6 +16217,10 @@ var DEFINITIONS_OTHERS = [
|
|
|
16157
16217
|
result = joinLatex(["{\\displaystyle", result, "}"]);
|
|
16158
16218
|
else if (dict.dict.mathStyle === "compact")
|
|
16159
16219
|
result = joinLatex(["{\\textstyle", result, "}"]);
|
|
16220
|
+
else if (dict.dict.mathStyle === "script")
|
|
16221
|
+
result = joinLatex(["{\\scriptstyle", result, "}"]);
|
|
16222
|
+
else if (dict.dict.mathStyle === "scriptscript")
|
|
16223
|
+
result = joinLatex(["{\\scriptscriptstyle", result, "}"]);
|
|
16160
16224
|
const v = dict.dict.size;
|
|
16161
16225
|
if (v !== null && v >= 1 && v <= 10) {
|
|
16162
16226
|
result = joinLatex([
|
|
@@ -16244,6 +16308,28 @@ var DEFINITIONS_OTHERS = [
|
|
|
16244
16308
|
latexTrigger: ["\\enspace"],
|
|
16245
16309
|
parse: () => ["HorizontalSpacing", 9]
|
|
16246
16310
|
},
|
|
16311
|
+
{
|
|
16312
|
+
latexTrigger: ["\\hspace"],
|
|
16313
|
+
parse: (parser) => {
|
|
16314
|
+
if (parser.peek === "*") parser.nextToken();
|
|
16315
|
+
parser.parseStringGroup();
|
|
16316
|
+
return ["HorizontalSpacing", 0];
|
|
16317
|
+
}
|
|
16318
|
+
},
|
|
16319
|
+
{
|
|
16320
|
+
latexTrigger: ["\\hskip"],
|
|
16321
|
+
parse: (parser) => {
|
|
16322
|
+
skipTexDimension(parser);
|
|
16323
|
+
return ["HorizontalSpacing", 0];
|
|
16324
|
+
}
|
|
16325
|
+
},
|
|
16326
|
+
{
|
|
16327
|
+
latexTrigger: ["\\kern"],
|
|
16328
|
+
parse: (parser) => {
|
|
16329
|
+
skipTexDimension(parser);
|
|
16330
|
+
return ["HorizontalSpacing", 0];
|
|
16331
|
+
}
|
|
16332
|
+
},
|
|
16247
16333
|
{
|
|
16248
16334
|
latexTrigger: ["\\phantom"],
|
|
16249
16335
|
parse: (parser) => {
|
|
@@ -16294,7 +16380,17 @@ var DEFINITIONS_OTHERS = [
|
|
|
16294
16380
|
// `["HorizontalSpacing", expr, 'op'|'bin'|rel]` -> indicate a spacing around and expression, i.e. `\mathbin{x}`, etc...
|
|
16295
16381
|
serialize: (serializer, expr2) => {
|
|
16296
16382
|
if (operand(expr2, 2) !== null) {
|
|
16297
|
-
|
|
16383
|
+
const cls = stringValue(operand(expr2, 2));
|
|
16384
|
+
const inner = serializer.serialize(operand(expr2, 1));
|
|
16385
|
+
if (cls === "bin") return `\\mathbin{${inner}}`;
|
|
16386
|
+
if (cls === "op") return `\\mathop{${inner}}`;
|
|
16387
|
+
if (cls === "rel") return `\\mathrel{${inner}}`;
|
|
16388
|
+
if (cls === "ord") return `\\mathord{${inner}}`;
|
|
16389
|
+
if (cls === "open") return `\\mathopen{${inner}}`;
|
|
16390
|
+
if (cls === "close") return `\\mathclose{${inner}}`;
|
|
16391
|
+
if (cls === "punct") return `\\mathpunct{${inner}}`;
|
|
16392
|
+
if (cls === "inner") return `\\mathinner{${inner}}`;
|
|
16393
|
+
return inner;
|
|
16298
16394
|
}
|
|
16299
16395
|
const v = machineValue(operand(expr2, 1));
|
|
16300
16396
|
if (v === null) return "";
|
|
@@ -16309,7 +16405,7 @@ var DEFINITIONS_OTHERS = [
|
|
|
16309
16405
|
36: "\\qquad"
|
|
16310
16406
|
}[v] ?? "";
|
|
16311
16407
|
}
|
|
16312
|
-
}
|
|
16408
|
+
},
|
|
16313
16409
|
// if (
|
|
16314
16410
|
// [
|
|
16315
16411
|
// '\\!',
|
|
@@ -16333,6 +16429,121 @@ var DEFINITIONS_OTHERS = [
|
|
|
16333
16429
|
// name: '',
|
|
16334
16430
|
// trigger: '\\check',
|
|
16335
16431
|
// },
|
|
16432
|
+
// ---------------------------------------------------------------------------
|
|
16433
|
+
// Function-style aliases for collection / random operators that some
|
|
16434
|
+
// notations write in lowercase (e.g. `\operatorname{shuffle}(L)`).
|
|
16435
|
+
// The capitalized library entries already exist; these are pure parse
|
|
16436
|
+
// aliases so the lowercase names don't land in `unsupported-operator`.
|
|
16437
|
+
// ---------------------------------------------------------------------------
|
|
16438
|
+
{ latexTrigger: "\\operatorname{random}", parse: "Random" },
|
|
16439
|
+
{ latexTrigger: "\\operatorname{shuffle}", parse: "Shuffle" },
|
|
16440
|
+
{ latexTrigger: "\\operatorname{repeat}", parse: "Repeat" },
|
|
16441
|
+
{ latexTrigger: "\\operatorname{join}", parse: "Join" },
|
|
16442
|
+
// ---------------------------------------------------------------------------
|
|
16443
|
+
// Geometric primitive heads. Registered as known typed heads so consumers
|
|
16444
|
+
// can branch on the operator name; CE itself doesn't render them. The
|
|
16445
|
+
// library entries (with no evaluator) live in `library/core.ts`.
|
|
16446
|
+
// ---------------------------------------------------------------------------
|
|
16447
|
+
{
|
|
16448
|
+
name: "Triangle",
|
|
16449
|
+
latexTrigger: ["\\operatorname{triangle}"],
|
|
16450
|
+
kind: "function",
|
|
16451
|
+
serialize: (serializer, expr2) => "\\operatorname{triangle}" + serializer.wrapArguments(expr2)
|
|
16452
|
+
},
|
|
16453
|
+
// Desmos's geometric `vector(p1, p2)` — a directed segment between two
|
|
16454
|
+
// points. Routed to a dedicated head (not the existing column-vector
|
|
16455
|
+
// `Vector`, which has a narrower `(number+) -> vector` signature).
|
|
16456
|
+
{
|
|
16457
|
+
name: "GeometricVector",
|
|
16458
|
+
latexTrigger: ["\\operatorname{vector}"],
|
|
16459
|
+
kind: "function",
|
|
16460
|
+
serialize: (serializer, expr2) => "\\operatorname{vector}" + serializer.wrapArguments(expr2)
|
|
16461
|
+
},
|
|
16462
|
+
{
|
|
16463
|
+
name: "Sphere",
|
|
16464
|
+
latexTrigger: ["\\operatorname{sphere}"],
|
|
16465
|
+
kind: "function",
|
|
16466
|
+
serialize: (serializer, expr2) => "\\operatorname{sphere}" + serializer.wrapArguments(expr2)
|
|
16467
|
+
},
|
|
16468
|
+
{
|
|
16469
|
+
name: "Segment",
|
|
16470
|
+
latexTrigger: ["\\operatorname{segment}"],
|
|
16471
|
+
kind: "function",
|
|
16472
|
+
serialize: (serializer, expr2) => "\\operatorname{segment}" + serializer.wrapArguments(expr2)
|
|
16473
|
+
}
|
|
16474
|
+
];
|
|
16475
|
+
|
|
16476
|
+
// src/compute-engine/latex-syntax/dictionary/definitions-colors.ts
|
|
16477
|
+
var DEFINITIONS_COLORS = [
|
|
16478
|
+
// Color constructors (one per colorspace, preserves space on evaluation)
|
|
16479
|
+
{
|
|
16480
|
+
name: "Rgb",
|
|
16481
|
+
latexTrigger: ["\\operatorname{rgb}"],
|
|
16482
|
+
kind: "function",
|
|
16483
|
+
serialize: (serializer, expr2) => "\\operatorname{rgb}" + serializer.wrapArguments(expr2)
|
|
16484
|
+
},
|
|
16485
|
+
{
|
|
16486
|
+
name: "Hsv",
|
|
16487
|
+
latexTrigger: ["\\operatorname{hsv}"],
|
|
16488
|
+
kind: "function",
|
|
16489
|
+
serialize: (serializer, expr2) => "\\operatorname{hsv}" + serializer.wrapArguments(expr2)
|
|
16490
|
+
},
|
|
16491
|
+
{
|
|
16492
|
+
name: "Hsl",
|
|
16493
|
+
latexTrigger: ["\\operatorname{hsl}"],
|
|
16494
|
+
kind: "function",
|
|
16495
|
+
serialize: (serializer, expr2) => "\\operatorname{hsl}" + serializer.wrapArguments(expr2)
|
|
16496
|
+
},
|
|
16497
|
+
{
|
|
16498
|
+
name: "Oklab",
|
|
16499
|
+
latexTrigger: ["\\operatorname{oklab}"],
|
|
16500
|
+
kind: "function",
|
|
16501
|
+
serialize: (serializer, expr2) => "\\operatorname{oklab}" + serializer.wrapArguments(expr2)
|
|
16502
|
+
},
|
|
16503
|
+
{
|
|
16504
|
+
name: "Oklch",
|
|
16505
|
+
latexTrigger: ["\\operatorname{oklch}"],
|
|
16506
|
+
kind: "function",
|
|
16507
|
+
serialize: (serializer, expr2) => "\\operatorname{oklch}" + serializer.wrapArguments(expr2)
|
|
16508
|
+
},
|
|
16509
|
+
// Conversion functions (color → color in the named space)
|
|
16510
|
+
{
|
|
16511
|
+
name: "AsRgb",
|
|
16512
|
+
latexTrigger: ["\\operatorname{asRgb}"],
|
|
16513
|
+
kind: "function",
|
|
16514
|
+
serialize: (serializer, expr2) => "\\operatorname{asRgb}" + serializer.wrapArguments(expr2)
|
|
16515
|
+
},
|
|
16516
|
+
{
|
|
16517
|
+
name: "AsHsv",
|
|
16518
|
+
latexTrigger: ["\\operatorname{asHsv}"],
|
|
16519
|
+
kind: "function",
|
|
16520
|
+
serialize: (serializer, expr2) => "\\operatorname{asHsv}" + serializer.wrapArguments(expr2)
|
|
16521
|
+
},
|
|
16522
|
+
{
|
|
16523
|
+
name: "AsHsl",
|
|
16524
|
+
latexTrigger: ["\\operatorname{asHsl}"],
|
|
16525
|
+
kind: "function",
|
|
16526
|
+
serialize: (serializer, expr2) => "\\operatorname{asHsl}" + serializer.wrapArguments(expr2)
|
|
16527
|
+
},
|
|
16528
|
+
{
|
|
16529
|
+
name: "AsOklab",
|
|
16530
|
+
latexTrigger: ["\\operatorname{asOklab}"],
|
|
16531
|
+
kind: "function",
|
|
16532
|
+
serialize: (serializer, expr2) => "\\operatorname{asOklab}" + serializer.wrapArguments(expr2)
|
|
16533
|
+
},
|
|
16534
|
+
{
|
|
16535
|
+
name: "AsOklch",
|
|
16536
|
+
latexTrigger: ["\\operatorname{asOklch}"],
|
|
16537
|
+
kind: "function",
|
|
16538
|
+
serialize: (serializer, expr2) => "\\operatorname{asOklch}" + serializer.wrapArguments(expr2)
|
|
16539
|
+
},
|
|
16540
|
+
// Perceptual difference (returns a scalar in [0, ~1])
|
|
16541
|
+
{
|
|
16542
|
+
name: "ColorDelta",
|
|
16543
|
+
latexTrigger: ["\\operatorname{colorDelta}"],
|
|
16544
|
+
kind: "function",
|
|
16545
|
+
serialize: (serializer, expr2) => "\\operatorname{colorDelta}" + serializer.wrapArguments(expr2)
|
|
16546
|
+
}
|
|
16336
16547
|
];
|
|
16337
16548
|
|
|
16338
16549
|
// src/compute-engine/latex-syntax/dictionary/default-dictionary.ts
|
|
@@ -16363,7 +16574,8 @@ var LATEX_DICTIONARY = [
|
|
|
16363
16574
|
...DEFINITIONS_STATISTICS,
|
|
16364
16575
|
...DEFINITIONS_UNITS,
|
|
16365
16576
|
...DEFINITIONS_OTHERS,
|
|
16366
|
-
...DEFINITIONS_PHYSICS
|
|
16577
|
+
...DEFINITIONS_PHYSICS,
|
|
16578
|
+
...DEFINITIONS_COLORS
|
|
16367
16579
|
];
|
|
16368
16580
|
|
|
16369
16581
|
// src/math-json/symbols.ts
|
|
@@ -16528,6 +16740,17 @@ function addEntry(result, entry, onError) {
|
|
|
16528
16740
|
} else if (Array.isArray(openTrigger) && openTrigger.length > 0) {
|
|
16529
16741
|
openTokens.push(openTrigger[0]);
|
|
16530
16742
|
}
|
|
16743
|
+
const closeTrigger = indexedEntry.closeTrigger;
|
|
16744
|
+
const closeTokens = /* @__PURE__ */ new Set();
|
|
16745
|
+
if (typeof closeTrigger === "string") {
|
|
16746
|
+
const variants = DELIMITER_SHORTHAND[closeTrigger];
|
|
16747
|
+
if (variants) for (const v of variants) closeTokens.add(v);
|
|
16748
|
+
else closeTokens.add(closeTrigger);
|
|
16749
|
+
if (closeTrigger === "||") closeTokens.add("|");
|
|
16750
|
+
} else if (Array.isArray(closeTrigger) && closeTrigger.length > 0) {
|
|
16751
|
+
closeTokens.add(closeTrigger[0]);
|
|
16752
|
+
}
|
|
16753
|
+
indexedEntry.closeTokens = closeTokens;
|
|
16531
16754
|
for (const token of openTokens) {
|
|
16532
16755
|
const existing = result.matchfixByOpen.get(token);
|
|
16533
16756
|
if (existing) {
|
|
@@ -16685,25 +16908,43 @@ function makeIndexedEntry(entry, onError) {
|
|
|
16685
16908
|
result.arguments = entry.arguments;
|
|
16686
16909
|
return result;
|
|
16687
16910
|
}
|
|
16911
|
+
function serializeTabularBody(serializer, body) {
|
|
16912
|
+
if (!body) return "";
|
|
16913
|
+
if (operator(body) !== "List") return serializer.serialize(body);
|
|
16914
|
+
const rows = operands(body);
|
|
16915
|
+
if (rows.length === 0) return "";
|
|
16916
|
+
if (!rows.every((row) => operator(row) === "List"))
|
|
16917
|
+
return serializer.serialize(body);
|
|
16918
|
+
return rows.map(
|
|
16919
|
+
(row) => operands(row).map((cell) => serializer.serialize(cell)).join(" & ")
|
|
16920
|
+
).join(" \\\\\n");
|
|
16921
|
+
}
|
|
16688
16922
|
function makeSerializeHandler(entry, latexTrigger, idTrigger) {
|
|
16689
16923
|
if (typeof entry.serialize === "function") return entry.serialize;
|
|
16690
16924
|
const kind = entry["kind"] ?? "expression";
|
|
16691
16925
|
if (kind === "environment") {
|
|
16692
16926
|
const envName = entry["symbolTrigger"] ?? entry.name ?? "unknown";
|
|
16693
|
-
return (serializer, expr2) =>
|
|
16694
|
-
|
|
16695
|
-
|
|
16696
|
-
|
|
16697
|
-
|
|
16927
|
+
return (serializer, expr2) => {
|
|
16928
|
+
const body = operand(expr2, 1);
|
|
16929
|
+
return joinLatex([
|
|
16930
|
+
`\\begin{${envName}}`,
|
|
16931
|
+
serializeTabularBody(serializer, body),
|
|
16932
|
+
`\\end{${envName}}`
|
|
16933
|
+
]);
|
|
16934
|
+
};
|
|
16698
16935
|
}
|
|
16699
16936
|
if (isMatchfixEntry(entry)) {
|
|
16700
16937
|
const openDelim = typeof entry.openTrigger === "string" ? DEFAULT_DELIMITER[entry.openTrigger] : tokensToString(entry.openTrigger);
|
|
16701
16938
|
const closeDelim = typeof entry.closeTrigger === "string" ? DEFAULT_DELIMITER[entry.closeTrigger] : tokensToString(entry.closeTrigger);
|
|
16702
|
-
return (serializer, expr2) =>
|
|
16703
|
-
|
|
16704
|
-
serializer.serialize(operand(expr2, 1))
|
|
16705
|
-
|
|
16706
|
-
|
|
16939
|
+
return (serializer, expr2) => {
|
|
16940
|
+
const style = serializer.groupStyle(expr2, serializer.level + 1);
|
|
16941
|
+
const inner = serializer.serialize(operand(expr2, 1));
|
|
16942
|
+
if (style === "scaled")
|
|
16943
|
+
return joinLatex([`\\left${openDelim}`, inner, `\\right${closeDelim}`]);
|
|
16944
|
+
if (style === "big")
|
|
16945
|
+
return joinLatex([`\\Bigl${openDelim}`, inner, `\\Bigr${closeDelim}`]);
|
|
16946
|
+
return joinLatex([openDelim, inner, closeDelim]);
|
|
16947
|
+
};
|
|
16707
16948
|
}
|
|
16708
16949
|
let latex = entry.serialize;
|
|
16709
16950
|
if (latex === void 0 && latexTrigger) latex = tokensToString(latexTrigger);
|
|
@@ -17588,6 +17829,16 @@ function parseNumber(parser, fmt) {
|
|
|
17588
17829
|
}
|
|
17589
17830
|
|
|
17590
17831
|
// src/compute-engine/latex-syntax/parse.ts
|
|
17832
|
+
var _symbolToUnicode = null;
|
|
17833
|
+
function getSymbolToUnicode() {
|
|
17834
|
+
if (!_symbolToUnicode) {
|
|
17835
|
+
_symbolToUnicode = /* @__PURE__ */ new Map();
|
|
17836
|
+
for (const [, latex, codepoint] of SYMBOLS2) {
|
|
17837
|
+
_symbolToUnicode.set(latex, String.fromCodePoint(codepoint));
|
|
17838
|
+
}
|
|
17839
|
+
}
|
|
17840
|
+
return _symbolToUnicode;
|
|
17841
|
+
}
|
|
17591
17842
|
var DELIMITER_SHORTHAND2 = {
|
|
17592
17843
|
"(": ["\\lparen", "("],
|
|
17593
17844
|
")": ["\\rparen", ")"],
|
|
@@ -18035,6 +18286,35 @@ var _Parser = class __Parser {
|
|
|
18035
18286
|
this.nextToken();
|
|
18036
18287
|
this.skipVisualSpace();
|
|
18037
18288
|
}
|
|
18289
|
+
if (this.match("\\hspace")) {
|
|
18290
|
+
this.match("*");
|
|
18291
|
+
this.parseStringGroup();
|
|
18292
|
+
this.skipVisualSpace();
|
|
18293
|
+
}
|
|
18294
|
+
if (this.match("\\hskip") || this.match("\\kern")) {
|
|
18295
|
+
this.skipSpace();
|
|
18296
|
+
if (!this.match("-")) this.match("+");
|
|
18297
|
+
while (/^[\d.]$/.test(this.peek)) this.nextToken();
|
|
18298
|
+
for (const unit of [
|
|
18299
|
+
"pt",
|
|
18300
|
+
"em",
|
|
18301
|
+
"mu",
|
|
18302
|
+
"ex",
|
|
18303
|
+
"mm",
|
|
18304
|
+
"cm",
|
|
18305
|
+
"in",
|
|
18306
|
+
"bp",
|
|
18307
|
+
"sp",
|
|
18308
|
+
"dd",
|
|
18309
|
+
"cc",
|
|
18310
|
+
"pc",
|
|
18311
|
+
"nc",
|
|
18312
|
+
"nd"
|
|
18313
|
+
]) {
|
|
18314
|
+
if (this.matchAll([...unit])) break;
|
|
18315
|
+
}
|
|
18316
|
+
this.skipVisualSpace();
|
|
18317
|
+
}
|
|
18038
18318
|
this.skipSpace();
|
|
18039
18319
|
}
|
|
18040
18320
|
match(token) {
|
|
@@ -18372,7 +18652,8 @@ var _Parser = class __Parser {
|
|
|
18372
18652
|
} else if (token === "<space>") {
|
|
18373
18653
|
result += " ";
|
|
18374
18654
|
} else if (token[0] === "\\") {
|
|
18375
|
-
|
|
18655
|
+
const unicode = getSymbolToUnicode().get(token);
|
|
18656
|
+
result += unicode ?? token;
|
|
18376
18657
|
} else {
|
|
18377
18658
|
result += token;
|
|
18378
18659
|
}
|
|
@@ -18526,6 +18807,19 @@ var _Parser = class __Parser {
|
|
|
18526
18807
|
}
|
|
18527
18808
|
for (const def of defs) {
|
|
18528
18809
|
this.index = start;
|
|
18810
|
+
if (def.closeTokens.size > 0) {
|
|
18811
|
+
let found = false;
|
|
18812
|
+
const tokens = this._tokens;
|
|
18813
|
+
for (let i = start; i < tokens.length; i++) {
|
|
18814
|
+
if (def.closeTokens.has(tokens[i])) {
|
|
18815
|
+
found = true;
|
|
18816
|
+
break;
|
|
18817
|
+
}
|
|
18818
|
+
}
|
|
18819
|
+
if (!found) continue;
|
|
18820
|
+
}
|
|
18821
|
+
if (typeof def.openTrigger === "string" && def.openTrigger === "." && !OPEN_DELIMITER_PREFIX[currentToken])
|
|
18822
|
+
continue;
|
|
18529
18823
|
const matched = this.matchDelimiter(def.openTrigger, def.closeTrigger);
|
|
18530
18824
|
if (!matched) continue;
|
|
18531
18825
|
const bodyStart = this.index;
|
|
@@ -19732,7 +20026,7 @@ var STYLE_MODIFIERS = {
|
|
|
19732
20026
|
sansserif: (s) => `\\mathsf{${s}}`,
|
|
19733
20027
|
monospace: (s) => `\\mathtt{${s}}`
|
|
19734
20028
|
};
|
|
19735
|
-
var
|
|
20029
|
+
var Serializer5 = class {
|
|
19736
20030
|
options;
|
|
19737
20031
|
dictionary;
|
|
19738
20032
|
level = -1;
|
|
@@ -19747,11 +20041,18 @@ var Serializer4 = class {
|
|
|
19747
20041
|
/**
|
|
19748
20042
|
* Serialize the expression, and if the expression is an operator
|
|
19749
20043
|
* of precedence less than or equal to prec, wrap it in some parens.
|
|
19750
|
-
*
|
|
20044
|
+
*
|
|
20045
|
+
* Skip wrapping for matchfix operators (Abs, Floor, Ceil, Norm, etc.)
|
|
20046
|
+
* and Delimiter since they already have visible delimiters.
|
|
19751
20047
|
*/
|
|
19752
20048
|
wrap(expr2, prec) {
|
|
19753
20049
|
if (expr2 === null || expr2 === void 0) return "";
|
|
19754
20050
|
if (prec === void 0) {
|
|
20051
|
+
const name2 = operator(expr2);
|
|
20052
|
+
if (name2) {
|
|
20053
|
+
const def = this.dictionary.ids.get(name2);
|
|
20054
|
+
if (def?.kind === "matchfix") return this.serialize(expr2);
|
|
20055
|
+
}
|
|
19755
20056
|
return this.wrapString(
|
|
19756
20057
|
this.serialize(expr2),
|
|
19757
20058
|
this.options.groupStyle(expr2, this.level + 1)
|
|
@@ -20045,7 +20346,7 @@ function serializeSymbol2(s, style = "auto") {
|
|
|
20045
20346
|
return body;
|
|
20046
20347
|
}
|
|
20047
20348
|
function serializeLatex(expr2, dict, options) {
|
|
20048
|
-
const serializer = new
|
|
20349
|
+
const serializer = new Serializer5(dict, options);
|
|
20049
20350
|
return serializer.serialize(expr2);
|
|
20050
20351
|
}
|
|
20051
20352
|
|
|
@@ -32081,6 +32382,29 @@ var ARITHMETIC_LIBRARY = [
|
|
|
32081
32382
|
signature: "(value*) -> number | list",
|
|
32082
32383
|
evaluate: (xs, { engine }) => evaluateMinMax(engine, xs, "Infimum")
|
|
32083
32384
|
},
|
|
32385
|
+
Distance: {
|
|
32386
|
+
description: "Euclidean distance between two points (tuples of numbers).",
|
|
32387
|
+
complexity: 6e3,
|
|
32388
|
+
signature: "(tuple, tuple) -> number",
|
|
32389
|
+
evaluate: ([a, b], { engine: ce }) => {
|
|
32390
|
+
if (!isFunction2(a) || !isFunction2(b))
|
|
32391
|
+
return ce.error("incompatible-type");
|
|
32392
|
+
if (a.operator !== "Tuple" || b.operator !== "Tuple")
|
|
32393
|
+
return ce.error("incompatible-type");
|
|
32394
|
+
if (a.ops.length !== b.ops.length || a.ops.length === 0)
|
|
32395
|
+
return ce.error("incompatible-type");
|
|
32396
|
+
let sumSq = 0;
|
|
32397
|
+
for (let i = 0; i < a.ops.length; i++) {
|
|
32398
|
+
const ai = a.ops[i].re;
|
|
32399
|
+
const bi = b.ops[i].re;
|
|
32400
|
+
if (!Number.isFinite(ai) || !Number.isFinite(bi))
|
|
32401
|
+
return ce.error("expected-value");
|
|
32402
|
+
const d = ai - bi;
|
|
32403
|
+
sumSq += d * d;
|
|
32404
|
+
}
|
|
32405
|
+
return ce.number(Math.sqrt(sumSq));
|
|
32406
|
+
}
|
|
32407
|
+
},
|
|
32084
32408
|
Product: {
|
|
32085
32409
|
description: "`Product(f, a, b)` computes the product of `f` from `a` to `b`",
|
|
32086
32410
|
wikidata: "Q901718",
|
|
@@ -32613,16 +32937,11 @@ function boxRule(ce, rule, options) {
|
|
|
32613
32937
|
);
|
|
32614
32938
|
let condFn;
|
|
32615
32939
|
if (typeof condition === "string") {
|
|
32616
|
-
const
|
|
32617
|
-
|
|
32618
|
-
const
|
|
32619
|
-
|
|
32620
|
-
|
|
32621
|
-
condFn = (x, _ce) => {
|
|
32622
|
-
const evaluated = condPattern.subs(x).evaluate();
|
|
32623
|
-
return isSymbol2(evaluated, "True");
|
|
32624
|
-
};
|
|
32625
|
-
}
|
|
32940
|
+
const condPattern = ce.parse(condition) ?? ce.expr("Nothing");
|
|
32941
|
+
condFn = (x, _ce) => {
|
|
32942
|
+
const evaluated = condPattern.subs(x).evaluate();
|
|
32943
|
+
return isSymbol2(evaluated, "True");
|
|
32944
|
+
};
|
|
32626
32945
|
} else {
|
|
32627
32946
|
if (condition !== void 0 && typeof condition !== "function")
|
|
32628
32947
|
throw new Error(
|
|
@@ -32724,6 +33043,15 @@ ${e.message}
|
|
|
32724
33043
|
function applyRule(rule, expr2, substitution, options) {
|
|
32725
33044
|
if (!rule) return null;
|
|
32726
33045
|
let canonical2 = options?.canonical ?? (expr2.isCanonical || expr2.isStructural);
|
|
33046
|
+
let { match: match2, replace: replace2, condition, id, onMatch, onBeforeMatch } = rule;
|
|
33047
|
+
const because = id ?? "";
|
|
33048
|
+
const ce = expr2.engine;
|
|
33049
|
+
if (canonical2 && match2) {
|
|
33050
|
+
const awc = getWildcards(match2);
|
|
33051
|
+
const canonicalMatch = match2.canonical;
|
|
33052
|
+
const bwc = getWildcards(canonicalMatch);
|
|
33053
|
+
if (!awc.every((x) => bwc.includes(x))) return null;
|
|
33054
|
+
}
|
|
32727
33055
|
let operandsMatched = false;
|
|
32728
33056
|
if (isFunction2(expr2) && options?.recursive) {
|
|
32729
33057
|
const newOps = expr2.ops.map((op) => {
|
|
@@ -32735,20 +33063,11 @@ function applyRule(rule, expr2, substitution, options) {
|
|
|
32735
33063
|
if (operandsMatched) {
|
|
32736
33064
|
if (!canonical2 && options?.canonical === void 0 && newOps.every((x) => x.isCanonical))
|
|
32737
33065
|
canonical2 = true;
|
|
32738
|
-
expr2 =
|
|
33066
|
+
expr2 = ce.function(expr2.operator, newOps, {
|
|
32739
33067
|
form: canonical2 ? "canonical" : "raw"
|
|
32740
33068
|
});
|
|
32741
33069
|
}
|
|
32742
33070
|
}
|
|
32743
|
-
let { match: match2, replace: replace2, condition, id, onMatch, onBeforeMatch } = rule;
|
|
32744
|
-
const because = id ?? "";
|
|
32745
|
-
if (canonical2 && match2) {
|
|
32746
|
-
const awc = getWildcards(match2);
|
|
32747
|
-
const canonicalMatch = match2.canonical;
|
|
32748
|
-
const bwc = getWildcards(canonicalMatch);
|
|
32749
|
-
if (!awc.every((x) => bwc.includes(x)))
|
|
32750
|
-
return operandsMatched ? { value: expr2, because } : null;
|
|
32751
|
-
}
|
|
32752
33071
|
const useVariations = rule.useVariations ?? options?.useVariations ?? false;
|
|
32753
33072
|
const matchPermutations = options?.matchPermutations ?? true;
|
|
32754
33073
|
onBeforeMatch?.(rule, expr2);
|
|
@@ -32767,7 +33086,7 @@ function applyRule(rule, expr2, substitution, options) {
|
|
|
32767
33086
|
...sub2
|
|
32768
33087
|
};
|
|
32769
33088
|
try {
|
|
32770
|
-
if (!condition(conditionSub,
|
|
33089
|
+
if (!condition(conditionSub, ce))
|
|
32771
33090
|
return operandsMatched ? { value: expr2, because } : null;
|
|
32772
33091
|
} catch (e) {
|
|
32773
33092
|
console.error(
|
|
@@ -32782,7 +33101,8 @@ function applyRule(rule, expr2, substitution, options) {
|
|
|
32782
33101
|
if (!canonical2 && options?.canonical === void 0 && replace2 instanceof _BoxedExpression && replace2.isCanonical)
|
|
32783
33102
|
canonical2 = true;
|
|
32784
33103
|
const result = typeof replace2 === "function" ? replace2(expr2, sub2) : replace2.subs(sub2, { canonical: canonical2 });
|
|
32785
|
-
if (!result)
|
|
33104
|
+
if (!result)
|
|
33105
|
+
return operandsMatched ? { value: canonical2 ? expr2.canonical : expr2, because } : null;
|
|
32786
33106
|
onMatch?.(rule, expr2, result);
|
|
32787
33107
|
if (isRuleStep(result))
|
|
32788
33108
|
return canonical2 ? { ...result, value: result.value.canonical } : result;
|
|
@@ -38356,6 +38676,40 @@ function rgbToHsl(r, g, b) {
|
|
|
38356
38676
|
else h = ((r - g) / d + 4) / 6;
|
|
38357
38677
|
return { h: h * 360, s, l };
|
|
38358
38678
|
}
|
|
38679
|
+
function hsvToRgb(h, s, v) {
|
|
38680
|
+
h = (h % 360 + 360) % 360;
|
|
38681
|
+
s = Math.max(0, Math.min(1, s));
|
|
38682
|
+
v = Math.max(0, Math.min(1, v));
|
|
38683
|
+
const c = v * s;
|
|
38684
|
+
const x = c * (1 - Math.abs(h / 60 % 2 - 1));
|
|
38685
|
+
const m = v - c;
|
|
38686
|
+
let r = 0, g = 0, b = 0;
|
|
38687
|
+
if (h < 60) [r, g, b] = [c, x, 0];
|
|
38688
|
+
else if (h < 120) [r, g, b] = [x, c, 0];
|
|
38689
|
+
else if (h < 180) [r, g, b] = [0, c, x];
|
|
38690
|
+
else if (h < 240) [r, g, b] = [0, x, c];
|
|
38691
|
+
else if (h < 300) [r, g, b] = [x, 0, c];
|
|
38692
|
+
else [r, g, b] = [c, 0, x];
|
|
38693
|
+
return { r: (r + m) * 255, g: (g + m) * 255, b: (b + m) * 255 };
|
|
38694
|
+
}
|
|
38695
|
+
function rgbToHsv(r, g, b) {
|
|
38696
|
+
r /= 255;
|
|
38697
|
+
g /= 255;
|
|
38698
|
+
b /= 255;
|
|
38699
|
+
const max2 = Math.max(r, g, b);
|
|
38700
|
+
const min2 = Math.min(r, g, b);
|
|
38701
|
+
const d = max2 - min2;
|
|
38702
|
+
let h = 0;
|
|
38703
|
+
if (d > 0) {
|
|
38704
|
+
if (max2 === r) h = (g - b) / d % 6;
|
|
38705
|
+
else if (max2 === g) h = (b - r) / d + 2;
|
|
38706
|
+
else h = (r - g) / d + 4;
|
|
38707
|
+
h *= 60;
|
|
38708
|
+
if (h < 0) h += 360;
|
|
38709
|
+
}
|
|
38710
|
+
const s = max2 === 0 ? 0 : d / max2;
|
|
38711
|
+
return { h, s, v: max2 };
|
|
38712
|
+
}
|
|
38359
38713
|
function parseHexColor(s) {
|
|
38360
38714
|
const hex = s.startsWith("#") ? s.substring(1) : s;
|
|
38361
38715
|
let r, g, b;
|
|
@@ -38380,6 +38734,12 @@ function parseHexColor(s) {
|
|
|
38380
38734
|
if (alpha !== void 0) result.alpha = alpha;
|
|
38381
38735
|
return result;
|
|
38382
38736
|
}
|
|
38737
|
+
function asOklch(color) {
|
|
38738
|
+
if (typeof color === "string") return rgbToOklch(parseHexColor(color));
|
|
38739
|
+
if ("C" in color) return color;
|
|
38740
|
+
if ("a" in color && "b" in color) return oklabToOklch(color);
|
|
38741
|
+
return rgbToOklch(color);
|
|
38742
|
+
}
|
|
38383
38743
|
function asRgb(color) {
|
|
38384
38744
|
if (typeof color === "number") {
|
|
38385
38745
|
return {
|
|
@@ -38811,6 +39171,13 @@ var NAMED_COLORS = {
|
|
|
38811
39171
|
};
|
|
38812
39172
|
function parseColor(s, darkMode) {
|
|
38813
39173
|
const str = s.trim().toLowerCase();
|
|
39174
|
+
const opacityMatch = str.match(/^(.+?)\s*\/\s*(\d+(?:\.\d+)?)%?\s*$/);
|
|
39175
|
+
if (opacityMatch) {
|
|
39176
|
+
const base = parseColor(opacityMatch[1].trim(), darkMode);
|
|
39177
|
+
const opacity = Math.max(0, Math.min(100, parseFloat(opacityMatch[2])));
|
|
39178
|
+
const alpha = Math.round(opacity / 100 * 255);
|
|
39179
|
+
return base & 4294967040 | alpha;
|
|
39180
|
+
}
|
|
38814
39181
|
if (str.startsWith("#")) {
|
|
38815
39182
|
const hex = str.substring(1);
|
|
38816
39183
|
let r, g, b, a = 255;
|
|
@@ -38943,14 +39310,6 @@ function parseColor(s, darkMode) {
|
|
|
38943
39310
|
console.warn(`parseColor: unrecognized color "${s}"`);
|
|
38944
39311
|
return 0;
|
|
38945
39312
|
}
|
|
38946
|
-
function parseColorToRgb01(s, darkMode) {
|
|
38947
|
-
const color = parseColor(s, darkMode);
|
|
38948
|
-
return [
|
|
38949
|
-
(color >>> 24 & 255) / 255,
|
|
38950
|
-
(color >>> 16 & 255) / 255,
|
|
38951
|
-
(color >>> 8 & 255) / 255
|
|
38952
|
-
];
|
|
38953
|
-
}
|
|
38954
39313
|
function apca(bgColor, fgColor) {
|
|
38955
39314
|
const bgRgb = asRgb(bgColor);
|
|
38956
39315
|
const fgRgb = asRgb(fgColor);
|
|
@@ -39009,6 +39368,12 @@ function contrastingColor(arg) {
|
|
|
39009
39368
|
const contrast2 = Math.abs(apca(fg2, bg));
|
|
39010
39369
|
return contrast1 >= contrast2 ? asColorNumber(fg1) : asColorNumber(fg2);
|
|
39011
39370
|
}
|
|
39371
|
+
function oklabDeltaE(a, b) {
|
|
39372
|
+
const dL = a.L - b.L;
|
|
39373
|
+
const da = a.a - b.a;
|
|
39374
|
+
const db = a.b - b.b;
|
|
39375
|
+
return Math.sqrt(dL * dL + da * da + db * db);
|
|
39376
|
+
}
|
|
39012
39377
|
function lerpOklch(c1, c2, f) {
|
|
39013
39378
|
const L = c1.L + (c2.L - c1.L) * f;
|
|
39014
39379
|
const C = c1.C + (c2.C - c1.C) * f;
|
|
@@ -41770,14 +42135,30 @@ var SEQUENTIAL_PALETTES = {
|
|
|
41770
42135
|
};
|
|
41771
42136
|
|
|
41772
42137
|
// src/compute-engine/library/colors.ts
|
|
41773
|
-
function
|
|
41774
|
-
|
|
41775
|
-
|
|
41776
|
-
|
|
41777
|
-
|
|
41778
|
-
|
|
41779
|
-
|
|
41780
|
-
|
|
42138
|
+
function normalizeAlpha(a) {
|
|
42139
|
+
if (a === void 0) return void 0;
|
|
42140
|
+
if (!Number.isFinite(a)) return void 0;
|
|
42141
|
+
if (Math.abs(a - 1) < 1e-9) return void 0;
|
|
42142
|
+
return a;
|
|
42143
|
+
}
|
|
42144
|
+
function normalizeColorHead(ce, expr2) {
|
|
42145
|
+
if (!isFunction2(expr2) || !expr2.ops || expr2.ops.length < 4) return expr2;
|
|
42146
|
+
const alphaExpr = expr2.ops[3];
|
|
42147
|
+
if (!isNumber(alphaExpr)) return expr2;
|
|
42148
|
+
if (normalizeAlpha(alphaExpr.re) === void 0) {
|
|
42149
|
+
return ce.function(expr2.operator, [expr2.ops[0], expr2.ops[1], expr2.ops[2]]);
|
|
42150
|
+
}
|
|
42151
|
+
return expr2;
|
|
42152
|
+
}
|
|
42153
|
+
function colorNumberToOklch(ce, color) {
|
|
42154
|
+
const r = color >>> 24 & 255;
|
|
42155
|
+
const g = color >>> 16 & 255;
|
|
42156
|
+
const b = color >>> 8 & 255;
|
|
42157
|
+
const a = normalizeAlpha((color & 255) / 255);
|
|
42158
|
+
const c = rgbToOklch({ r, g, b });
|
|
42159
|
+
const args = [ce.number(c.L), ce.number(c.C), ce.number(c.H)];
|
|
42160
|
+
if (a !== void 0) args.push(ce.number(a));
|
|
42161
|
+
return ce.function("Oklch", args);
|
|
41781
42162
|
}
|
|
41782
42163
|
var ALL_PALETTES = {
|
|
41783
42164
|
...SEQUENTIAL_PALETTES,
|
|
@@ -41788,45 +42169,139 @@ function samplePalette(ce, palette, t) {
|
|
|
41788
42169
|
t = Math.max(0, Math.min(1, t));
|
|
41789
42170
|
const n = palette.length;
|
|
41790
42171
|
if (n === 0) return ce.error("expected-value");
|
|
41791
|
-
if (n === 1) return
|
|
42172
|
+
if (n === 1) return colorNumberToOklch(ce, parseColor(palette[0]));
|
|
41792
42173
|
const pos = t * (n - 1);
|
|
41793
42174
|
const i = Math.floor(pos);
|
|
41794
42175
|
const frac = pos - i;
|
|
41795
|
-
if (i >= n - 1) return
|
|
41796
|
-
if (frac < 1e-9) return
|
|
41797
|
-
|
|
41798
|
-
|
|
41799
|
-
|
|
41800
|
-
|
|
41801
|
-
|
|
42176
|
+
if (i >= n - 1) return colorNumberToOklch(ce, parseColor(palette[n - 1]));
|
|
42177
|
+
if (frac < 1e-9) return colorNumberToOklch(ce, parseColor(palette[i]));
|
|
42178
|
+
return oklchToExpr(
|
|
42179
|
+
ce,
|
|
42180
|
+
asOklch(interpolateOklch(palette[i], palette[i + 1], frac))
|
|
42181
|
+
);
|
|
42182
|
+
}
|
|
42183
|
+
var COLOR_OPERATORS = /* @__PURE__ */ new Set(["Rgb", "Hsv", "Hsl", "Oklab", "Oklch"]);
|
|
42184
|
+
function readColorExpr(arg) {
|
|
42185
|
+
if (!isFunction2(arg)) return null;
|
|
42186
|
+
if (!COLOR_OPERATORS.has(arg.operator)) return null;
|
|
42187
|
+
if (!arg.ops || arg.ops.length < 3) return null;
|
|
42188
|
+
const c0 = arg.ops[0].re;
|
|
42189
|
+
const c1 = arg.ops[1].re;
|
|
42190
|
+
const c2 = arg.ops[2].re;
|
|
42191
|
+
if (!Number.isFinite(c0) || !Number.isFinite(c1) || !Number.isFinite(c2))
|
|
42192
|
+
return null;
|
|
42193
|
+
const alpha = arg.ops.length >= 4 ? normalizeAlpha(arg.ops[3].re) : void 0;
|
|
42194
|
+
return { space: arg.operator, c0, c1, c2, alpha };
|
|
42195
|
+
}
|
|
42196
|
+
function colorExprToRgb(arg) {
|
|
42197
|
+
const c = readColorExpr(arg);
|
|
42198
|
+
if (!c) return null;
|
|
42199
|
+
const withAlpha = (rgb) => c.alpha !== void 0 ? { ...rgb, alpha: c.alpha } : rgb;
|
|
42200
|
+
switch (c.space) {
|
|
42201
|
+
case "Rgb":
|
|
42202
|
+
return withAlpha({ r: c.c0 * 255, g: c.c1 * 255, b: c.c2 * 255 });
|
|
42203
|
+
case "Hsv":
|
|
42204
|
+
return withAlpha(hsvToRgb(c.c0, c.c1, c.c2));
|
|
42205
|
+
case "Hsl":
|
|
42206
|
+
return withAlpha(hslToRgb(c.c0, c.c1, c.c2));
|
|
42207
|
+
case "Oklab":
|
|
42208
|
+
return withAlpha(oklabToRgb({ L: c.c0, a: c.c1, b: c.c2 }));
|
|
42209
|
+
case "Oklch":
|
|
42210
|
+
return withAlpha(oklchToRgb({ L: c.c0, C: c.c1, H: c.c2 }));
|
|
42211
|
+
}
|
|
42212
|
+
return null;
|
|
42213
|
+
}
|
|
42214
|
+
function colorExprToOklch(arg) {
|
|
42215
|
+
const c = readColorExpr(arg);
|
|
42216
|
+
if (!c) return null;
|
|
42217
|
+
switch (c.space) {
|
|
42218
|
+
case "Oklch":
|
|
42219
|
+
return asOklch({ L: c.c0, C: c.c1, H: c.c2, alpha: c.alpha });
|
|
42220
|
+
case "Oklab":
|
|
42221
|
+
return asOklch({ L: c.c0, a: c.c1, b: c.c2, alpha: c.alpha });
|
|
42222
|
+
case "Rgb":
|
|
42223
|
+
return asOklch({
|
|
42224
|
+
r: c.c0 * 255,
|
|
42225
|
+
g: c.c1 * 255,
|
|
42226
|
+
b: c.c2 * 255,
|
|
42227
|
+
alpha: c.alpha
|
|
42228
|
+
});
|
|
42229
|
+
case "Hsv": {
|
|
42230
|
+
const rgb = hsvToRgb(c.c0, c.c1, c.c2);
|
|
42231
|
+
return asOklch({ ...rgb, alpha: c.alpha });
|
|
42232
|
+
}
|
|
42233
|
+
case "Hsl": {
|
|
42234
|
+
const rgb = hslToRgb(c.c0, c.c1, c.c2);
|
|
42235
|
+
return asOklch({ r: rgb.r, g: rgb.g, b: rgb.b, alpha: c.alpha });
|
|
42236
|
+
}
|
|
42237
|
+
}
|
|
42238
|
+
return null;
|
|
42239
|
+
}
|
|
42240
|
+
function toOklch(ce, arg) {
|
|
42241
|
+
const direct = colorExprToOklch(arg);
|
|
42242
|
+
if (direct) return direct;
|
|
42243
|
+
const rgb = extractRgb(ce, arg);
|
|
42244
|
+
return rgb ? asOklch(rgb) : null;
|
|
42245
|
+
}
|
|
42246
|
+
function lerpOklchColor(a, b, t) {
|
|
42247
|
+
const L = a.L + (b.L - a.L) * t;
|
|
42248
|
+
const C = a.C + (b.C - a.C) * t;
|
|
42249
|
+
const aAchromatic = a.C < 1e-6;
|
|
42250
|
+
const bAchromatic = b.C < 1e-6;
|
|
42251
|
+
let H;
|
|
42252
|
+
if (aAchromatic && bAchromatic) H = a.H;
|
|
42253
|
+
else if (aAchromatic) H = b.H;
|
|
42254
|
+
else if (bAchromatic) H = a.H;
|
|
42255
|
+
else {
|
|
42256
|
+
let dH = b.H - a.H;
|
|
42257
|
+
if (dH > 180) dH -= 360;
|
|
42258
|
+
if (dH < -180) dH += 360;
|
|
42259
|
+
H = a.H + dH * t;
|
|
42260
|
+
if (H < 0) H += 360;
|
|
42261
|
+
if (H >= 360) H -= 360;
|
|
42262
|
+
}
|
|
42263
|
+
const alphaA = a.alpha ?? 1;
|
|
42264
|
+
const alphaB = b.alpha ?? 1;
|
|
42265
|
+
return { L, C, H, alpha: normalizeAlpha(alphaA + (alphaB - alphaA) * t) };
|
|
42266
|
+
}
|
|
42267
|
+
function oklchToExpr(ce, c) {
|
|
42268
|
+
const args = [ce.number(c.L), ce.number(c.C), ce.number(c.H)];
|
|
42269
|
+
if (c.alpha !== void 0) args.push(ce.number(c.alpha));
|
|
42270
|
+
return ce.function("Oklch", args);
|
|
41802
42271
|
}
|
|
41803
42272
|
function extractRgb(ce, arg) {
|
|
41804
42273
|
if (isString(arg)) {
|
|
41805
42274
|
const s = arg.string;
|
|
41806
42275
|
if (!s) return void 0;
|
|
41807
42276
|
const color = parseColor(s);
|
|
41808
|
-
|
|
42277
|
+
const rgb = {
|
|
41809
42278
|
r: color >>> 24 & 255,
|
|
41810
42279
|
g: color >>> 16 & 255,
|
|
41811
|
-
b: color >>> 8 & 255
|
|
41812
|
-
alpha: (color & 255) / 255
|
|
42280
|
+
b: color >>> 8 & 255
|
|
41813
42281
|
};
|
|
42282
|
+
const alpha = normalizeAlpha((color & 255) / 255);
|
|
42283
|
+
if (alpha !== void 0) rgb.alpha = alpha;
|
|
42284
|
+
return rgb;
|
|
41814
42285
|
}
|
|
42286
|
+
const fromTyped = colorExprToRgb(arg);
|
|
42287
|
+
if (fromTyped) return fromTyped;
|
|
41815
42288
|
if (arg.operator === "Tuple" && arg.ops && arg.ops.length >= 3) {
|
|
41816
42289
|
const rgb = {
|
|
41817
42290
|
r: arg.ops[0].re * 255,
|
|
41818
42291
|
g: arg.ops[1].re * 255,
|
|
41819
42292
|
b: arg.ops[2].re * 255
|
|
41820
42293
|
};
|
|
41821
|
-
if (arg.ops.length >= 4)
|
|
42294
|
+
if (arg.ops.length >= 4) {
|
|
42295
|
+
const alpha = normalizeAlpha(arg.ops[3].re);
|
|
42296
|
+
if (alpha !== void 0) rgb.alpha = alpha;
|
|
42297
|
+
}
|
|
41822
42298
|
return rgb;
|
|
41823
42299
|
}
|
|
41824
42300
|
return void 0;
|
|
41825
42301
|
}
|
|
41826
42302
|
function componentsTuple(ce, components, alpha) {
|
|
41827
42303
|
const args = components.map((v) => ce.number(v));
|
|
41828
|
-
if (alpha !== void 0
|
|
41829
|
-
args.push(ce.number(alpha));
|
|
42304
|
+
if (alpha !== void 0) args.push(ce.number(alpha));
|
|
41830
42305
|
return ce.tuple(...args);
|
|
41831
42306
|
}
|
|
41832
42307
|
function rgbToHex(rgb) {
|
|
@@ -41834,7 +42309,7 @@ function rgbToHex(rgb) {
|
|
|
41834
42309
|
const g = Math.round(Math.max(0, Math.min(255, rgb.g)));
|
|
41835
42310
|
const b = Math.round(Math.max(0, Math.min(255, rgb.b)));
|
|
41836
42311
|
const hex = `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
|
|
41837
|
-
if (rgb.alpha !== void 0
|
|
42312
|
+
if (rgb.alpha !== void 0) {
|
|
41838
42313
|
const a = Math.round(Math.max(0, Math.min(255, rgb.alpha * 255)));
|
|
41839
42314
|
return hex + a.toString(16).padStart(2, "0");
|
|
41840
42315
|
}
|
|
@@ -41842,22 +42317,29 @@ function rgbToHex(rgb) {
|
|
|
41842
42317
|
}
|
|
41843
42318
|
var COLORS_LIBRARY = {
|
|
41844
42319
|
Color: {
|
|
41845
|
-
description: "
|
|
42320
|
+
description: "Parse a CSS-style color string to an Oklch color",
|
|
41846
42321
|
complexity: 8e3,
|
|
41847
|
-
signature: "(string) ->
|
|
42322
|
+
signature: "(string) -> color",
|
|
41848
42323
|
evaluate: (ops, { engine: ce }) => {
|
|
41849
42324
|
const input = isString(ops[0]) ? ops[0].string : void 0;
|
|
41850
42325
|
if (!input) return ce.error("incompatible-type");
|
|
41851
42326
|
const color = parseColor(input);
|
|
41852
42327
|
if (color === 0 && input.trim().toLowerCase() !== "transparent")
|
|
41853
42328
|
return ce.error("incompatible-type");
|
|
41854
|
-
|
|
42329
|
+
const r = color >>> 24 & 255;
|
|
42330
|
+
const g = color >>> 16 & 255;
|
|
42331
|
+
const b = color >>> 8 & 255;
|
|
42332
|
+
const a = normalizeAlpha((color & 255) / 255);
|
|
42333
|
+
const c = rgbToOklch({ r, g, b });
|
|
42334
|
+
const args = [ce.number(c.L), ce.number(c.C), ce.number(c.H)];
|
|
42335
|
+
if (a !== void 0) args.push(ce.number(a));
|
|
42336
|
+
return ce.function("Oklch", args);
|
|
41855
42337
|
}
|
|
41856
42338
|
},
|
|
41857
42339
|
ColorToString: {
|
|
41858
42340
|
description: "Convert a color to a string in the specified format",
|
|
41859
42341
|
complexity: 8e3,
|
|
41860
|
-
signature: "(
|
|
42342
|
+
signature: "(color | string | tuple, string?) -> string",
|
|
41861
42343
|
evaluate: (ops, { engine: ce }) => {
|
|
41862
42344
|
const rgb = extractRgb(ce, ops[0]);
|
|
41863
42345
|
if (!rgb) return ce.error("incompatible-type");
|
|
@@ -41869,7 +42351,7 @@ var COLORS_LIBRARY = {
|
|
|
41869
42351
|
const r = Math.round(rgb.r);
|
|
41870
42352
|
const g = Math.round(rgb.g);
|
|
41871
42353
|
const b = Math.round(rgb.b);
|
|
41872
|
-
if (rgb.alpha !== void 0
|
|
42354
|
+
if (rgb.alpha !== void 0)
|
|
41873
42355
|
return ce.string(`rgb(${r} ${g} ${b} / ${rgb.alpha})`);
|
|
41874
42356
|
return ce.string(`rgb(${r} ${g} ${b})`);
|
|
41875
42357
|
}
|
|
@@ -41878,17 +42360,17 @@ var COLORS_LIBRARY = {
|
|
|
41878
42360
|
const h = Math.round(hsl.h * 10) / 10;
|
|
41879
42361
|
const s = Math.round(hsl.s * 1e3) / 10;
|
|
41880
42362
|
const l = Math.round(hsl.l * 1e3) / 10;
|
|
41881
|
-
if (rgb.alpha !== void 0
|
|
42363
|
+
if (rgb.alpha !== void 0)
|
|
41882
42364
|
return ce.string(`hsl(${h} ${s}% ${l}% / ${rgb.alpha})`);
|
|
41883
42365
|
return ce.string(`hsl(${h} ${s}% ${l}%)`);
|
|
41884
42366
|
}
|
|
41885
42367
|
case "oklch": {
|
|
41886
|
-
const c =
|
|
42368
|
+
const c = colorExprToOklch(ops[0]) ?? asOklch(rgb);
|
|
41887
42369
|
const L = Math.round(c.L * 1e3) / 1e3;
|
|
41888
42370
|
const C = Math.round(c.C * 1e3) / 1e3;
|
|
41889
42371
|
const H = Math.round(c.H * 10) / 10;
|
|
41890
|
-
if (
|
|
41891
|
-
return ce.string(`oklch(${L} ${C} ${H} / ${
|
|
42372
|
+
if (c.alpha !== void 0)
|
|
42373
|
+
return ce.string(`oklch(${L} ${C} ${H} / ${c.alpha})`);
|
|
41892
42374
|
return ce.string(`oklch(${L} ${C} ${H})`);
|
|
41893
42375
|
}
|
|
41894
42376
|
default:
|
|
@@ -41899,60 +42381,44 @@ var COLORS_LIBRARY = {
|
|
|
41899
42381
|
ColorMix: {
|
|
41900
42382
|
description: "Mix two colors in OKLCh space",
|
|
41901
42383
|
complexity: 8e3,
|
|
41902
|
-
signature: "(
|
|
42384
|
+
signature: "(color | string | tuple, color | string | tuple, number?) -> color",
|
|
41903
42385
|
evaluate: (ops, { engine: ce }) => {
|
|
41904
|
-
const rgb1 = extractRgb(ce, ops[0]);
|
|
41905
|
-
const rgb2 = extractRgb(ce, ops[1]);
|
|
41906
|
-
if (!rgb1 || !rgb2) return ce.error("incompatible-type");
|
|
41907
42386
|
let ratio = 0.5;
|
|
41908
42387
|
if (ops.length >= 3 && ops[2] !== void 0) {
|
|
41909
42388
|
ratio = ops[2].re;
|
|
41910
42389
|
if (!Number.isFinite(ratio)) return ce.error("expected-value");
|
|
41911
42390
|
ratio = Math.max(0, Math.min(1, ratio));
|
|
41912
42391
|
}
|
|
41913
|
-
const
|
|
41914
|
-
const
|
|
41915
|
-
|
|
41916
|
-
|
|
41917
|
-
const g = mixed.g / 255;
|
|
41918
|
-
const b = mixed.b / 255;
|
|
41919
|
-
const a1 = rgb1.alpha ?? 1;
|
|
41920
|
-
const a2 = rgb2.alpha ?? 1;
|
|
41921
|
-
const alpha = a1 + (a2 - a1) * ratio;
|
|
41922
|
-
if (Math.abs(alpha - 1) > 1e-4)
|
|
41923
|
-
return ce.tuple(
|
|
41924
|
-
ce.number(r),
|
|
41925
|
-
ce.number(g),
|
|
41926
|
-
ce.number(b),
|
|
41927
|
-
ce.number(alpha)
|
|
41928
|
-
);
|
|
41929
|
-
return ce.tuple(ce.number(r), ce.number(g), ce.number(b));
|
|
42392
|
+
const oklch1 = toOklch(ce, ops[0]);
|
|
42393
|
+
const oklch2 = toOklch(ce, ops[1]);
|
|
42394
|
+
if (!oklch1 || !oklch2) return ce.error("incompatible-type");
|
|
42395
|
+
return oklchToExpr(ce, lerpOklchColor(oklch1, oklch2, ratio));
|
|
41930
42396
|
}
|
|
41931
42397
|
},
|
|
41932
42398
|
Colormap: {
|
|
41933
42399
|
description: "Sample colors from a named palette",
|
|
41934
42400
|
complexity: 8e3,
|
|
41935
|
-
signature: "(string, number?) ->
|
|
42401
|
+
signature: "(string, number?) -> color | list<color>",
|
|
41936
42402
|
evaluate: (ops, { engine: ce }) => {
|
|
41937
42403
|
const name = isString(ops[0]) ? ops[0].string : void 0;
|
|
41938
42404
|
if (!name) return ce.error("incompatible-type");
|
|
41939
42405
|
const palette = ALL_PALETTES[name];
|
|
41940
42406
|
if (!palette) return ce.error("expected-value", name);
|
|
41941
42407
|
if (ops.length < 2 || ops[1] === void 0) {
|
|
41942
|
-
const
|
|
41943
|
-
(hex) =>
|
|
42408
|
+
const colors = palette.map(
|
|
42409
|
+
(hex) => colorNumberToOklch(ce, parseColor(hex))
|
|
41944
42410
|
);
|
|
41945
|
-
return ce.function("List",
|
|
42411
|
+
return ce.function("List", colors);
|
|
41946
42412
|
}
|
|
41947
42413
|
const val = ops[1].re;
|
|
41948
42414
|
if (!Number.isFinite(val)) return ce.error("expected-value");
|
|
41949
42415
|
if (Number.isInteger(val) && val >= 2) {
|
|
41950
42416
|
const n = val;
|
|
41951
|
-
const
|
|
42417
|
+
const colors = [];
|
|
41952
42418
|
for (let i = 0; i < n; i++) {
|
|
41953
|
-
|
|
42419
|
+
colors.push(samplePalette(ce, palette, i / (n - 1)));
|
|
41954
42420
|
}
|
|
41955
|
-
return ce.function("List",
|
|
42421
|
+
return ce.function("List", colors);
|
|
41956
42422
|
}
|
|
41957
42423
|
return samplePalette(ce, palette, val);
|
|
41958
42424
|
}
|
|
@@ -41960,12 +42426,25 @@ var COLORS_LIBRARY = {
|
|
|
41960
42426
|
ColorToColorspace: {
|
|
41961
42427
|
description: "Convert a color to components in a target color space",
|
|
41962
42428
|
complexity: 8e3,
|
|
41963
|
-
signature: "(
|
|
42429
|
+
signature: "(color | string | tuple, string) -> tuple",
|
|
41964
42430
|
evaluate: (ops, { engine: ce }) => {
|
|
41965
|
-
const rgb = extractRgb(ce, ops[0]);
|
|
41966
|
-
if (!rgb) return ce.error("incompatible-type");
|
|
41967
42431
|
const space = isString(ops[1]) ? ops[1].string?.toLowerCase() : void 0;
|
|
41968
42432
|
if (!space) return ce.error("incompatible-type");
|
|
42433
|
+
if (space === "oklch" || space === "oklab" || space === "lab") {
|
|
42434
|
+
const oklch2 = colorExprToOklch(ops[0]);
|
|
42435
|
+
if (oklch2) {
|
|
42436
|
+
if (space === "oklch")
|
|
42437
|
+
return componentsTuple(
|
|
42438
|
+
ce,
|
|
42439
|
+
[oklch2.L, oklch2.C, oklch2.H],
|
|
42440
|
+
oklch2.alpha
|
|
42441
|
+
);
|
|
42442
|
+
const lab = oklchToOklab(oklch2);
|
|
42443
|
+
return componentsTuple(ce, [lab.L, lab.a, lab.b], lab.alpha);
|
|
42444
|
+
}
|
|
42445
|
+
}
|
|
42446
|
+
const rgb = extractRgb(ce, ops[0]);
|
|
42447
|
+
if (!rgb) return ce.error("incompatible-type");
|
|
41969
42448
|
const alpha = rgb.alpha;
|
|
41970
42449
|
switch (space) {
|
|
41971
42450
|
case "rgb":
|
|
@@ -41995,17 +42474,27 @@ var COLORS_LIBRARY = {
|
|
|
41995
42474
|
ColorFromColorspace: {
|
|
41996
42475
|
description: "Convert color space components to a canonical sRGB tuple",
|
|
41997
42476
|
complexity: 8e3,
|
|
41998
|
-
signature: "(tuple, string) -> tuple",
|
|
42477
|
+
signature: "(color | tuple, string) -> tuple",
|
|
41999
42478
|
evaluate: (ops, { engine: ce }) => {
|
|
42000
|
-
const tuple = ops[0];
|
|
42001
|
-
if (!isFunction2(tuple) || tuple.operator !== "Tuple" || tuple.ops.length < 3)
|
|
42002
|
-
return ce.error("incompatible-type");
|
|
42003
|
-
const c0 = tuple.ops[0].re;
|
|
42004
|
-
const c1 = tuple.ops[1].re;
|
|
42005
|
-
const c2 = tuple.ops[2].re;
|
|
42006
|
-
const alpha = tuple.ops.length >= 4 ? tuple.ops[3].re : void 0;
|
|
42007
42479
|
const space = isString(ops[1]) ? ops[1].string?.toLowerCase() : void 0;
|
|
42008
42480
|
if (!space) return ce.error("incompatible-type");
|
|
42481
|
+
let c0, c1, c2;
|
|
42482
|
+
let alpha;
|
|
42483
|
+
const arg = ops[0];
|
|
42484
|
+
const typed = readColorExpr(arg);
|
|
42485
|
+
if (typed) {
|
|
42486
|
+
c0 = typed.c0;
|
|
42487
|
+
c1 = typed.c1;
|
|
42488
|
+
c2 = typed.c2;
|
|
42489
|
+
alpha = typed.alpha;
|
|
42490
|
+
} else if (isFunction2(arg) && arg.operator === "Tuple" && arg.ops.length >= 3) {
|
|
42491
|
+
c0 = arg.ops[0].re;
|
|
42492
|
+
c1 = arg.ops[1].re;
|
|
42493
|
+
c2 = arg.ops[2].re;
|
|
42494
|
+
alpha = arg.ops.length >= 4 ? arg.ops[3].re : void 0;
|
|
42495
|
+
} else {
|
|
42496
|
+
return ce.error("incompatible-type");
|
|
42497
|
+
}
|
|
42009
42498
|
let rgb;
|
|
42010
42499
|
switch (space) {
|
|
42011
42500
|
case "rgb":
|
|
@@ -42041,7 +42530,7 @@ var COLORS_LIBRARY = {
|
|
|
42041
42530
|
ColorContrast: {
|
|
42042
42531
|
description: "APCA contrast ratio between two colors",
|
|
42043
42532
|
complexity: 8e3,
|
|
42044
|
-
signature: "(
|
|
42533
|
+
signature: "(color | string | tuple, color | string | tuple) -> number",
|
|
42045
42534
|
evaluate: (ops, { engine: ce }) => {
|
|
42046
42535
|
const bgRgb = extractRgb(ce, ops[0]);
|
|
42047
42536
|
const fgRgb = extractRgb(ce, ops[1]);
|
|
@@ -42052,19 +42541,186 @@ var COLORS_LIBRARY = {
|
|
|
42052
42541
|
ContrastingColor: {
|
|
42053
42542
|
description: "Choose the foreground color with better APCA contrast against a background",
|
|
42054
42543
|
complexity: 8e3,
|
|
42055
|
-
signature: "(
|
|
42544
|
+
signature: "(color | string | tuple, (color | string | tuple)?, (color | string | tuple)?) -> color",
|
|
42056
42545
|
evaluate: (ops, { engine: ce }) => {
|
|
42057
42546
|
const bgRgb = extractRgb(ce, ops[0]);
|
|
42058
42547
|
if (!bgRgb) return ce.error("incompatible-type");
|
|
42548
|
+
let packed;
|
|
42059
42549
|
if (ops.length >= 3 && ops[1] !== void 0 && ops[2] !== void 0) {
|
|
42060
42550
|
const fg1 = extractRgb(ce, ops[1]);
|
|
42061
42551
|
const fg2 = extractRgb(ce, ops[2]);
|
|
42062
42552
|
if (!fg1 || !fg2) return ce.error("incompatible-type");
|
|
42063
|
-
|
|
42064
|
-
|
|
42553
|
+
packed = contrastingColor({ bg: bgRgb, fg1, fg2 });
|
|
42554
|
+
} else {
|
|
42555
|
+
packed = contrastingColor(bgRgb);
|
|
42556
|
+
}
|
|
42557
|
+
const r = (packed >>> 24 & 255) / 255;
|
|
42558
|
+
const g = (packed >>> 16 & 255) / 255;
|
|
42559
|
+
const b = (packed >>> 8 & 255) / 255;
|
|
42560
|
+
const alpha = normalizeAlpha((packed & 255) / 255);
|
|
42561
|
+
const args = [ce.number(r), ce.number(g), ce.number(b)];
|
|
42562
|
+
if (alpha !== void 0) args.push(ce.number(alpha));
|
|
42563
|
+
return ce.function("Rgb", args);
|
|
42564
|
+
}
|
|
42565
|
+
},
|
|
42566
|
+
// ---------------------------------------------------------------------------
|
|
42567
|
+
// Color constructors. Each preserves its colorspace on evaluation; the
|
|
42568
|
+
// operator name is the discriminator. Components are interpreted per
|
|
42569
|
+
// colorspace conventions (Rgb channels 0-1, Hsv/Hsl hue in degrees with
|
|
42570
|
+
// sat/value 0-1, Oklab/Oklch L 0-1 with standard a/b/C/H ranges). The
|
|
42571
|
+
// optional 4th argument is alpha in [0, 1]. No clamping at evaluation time.
|
|
42572
|
+
// ---------------------------------------------------------------------------
|
|
42573
|
+
Rgb: {
|
|
42574
|
+
description: "sRGB color (channels 0-1, optional alpha 0-1)",
|
|
42575
|
+
complexity: 8e3,
|
|
42576
|
+
signature: "(number, number, number, number?) -> color"
|
|
42577
|
+
},
|
|
42578
|
+
Hsv: {
|
|
42579
|
+
description: "HSV color (hue degrees, saturation/value 0-1, optional alpha)",
|
|
42580
|
+
complexity: 8e3,
|
|
42581
|
+
signature: "(number, number, number, number?) -> color"
|
|
42582
|
+
},
|
|
42583
|
+
Hsl: {
|
|
42584
|
+
description: "HSL color (hue degrees, saturation/lightness 0-1, optional alpha)",
|
|
42585
|
+
complexity: 8e3,
|
|
42586
|
+
signature: "(number, number, number, number?) -> color"
|
|
42587
|
+
},
|
|
42588
|
+
Oklab: {
|
|
42589
|
+
description: "OKLab color (L 0-1, a/b ~ -0.4..0.4, optional alpha)",
|
|
42590
|
+
complexity: 8e3,
|
|
42591
|
+
signature: "(number, number, number, number?) -> color"
|
|
42592
|
+
},
|
|
42593
|
+
Oklch: {
|
|
42594
|
+
description: "OKLCh color (L 0-1, C 0-~0.4, hue degrees, optional alpha)",
|
|
42595
|
+
complexity: 8e3,
|
|
42596
|
+
signature: "(number, number, number, number?) -> color"
|
|
42597
|
+
},
|
|
42598
|
+
// ---------------------------------------------------------------------------
|
|
42599
|
+
// Color-space conversions. Each accepts any of the five color heads and
|
|
42600
|
+
// returns the same color in the named space. If the input is already in
|
|
42601
|
+
// the target space, returns the input unchanged.
|
|
42602
|
+
// ---------------------------------------------------------------------------
|
|
42603
|
+
AsRgb: {
|
|
42604
|
+
description: "Convert any color to sRGB (channels 0-1)",
|
|
42605
|
+
complexity: 8e3,
|
|
42606
|
+
signature: "(color) -> color",
|
|
42607
|
+
evaluate: (ops, { engine: ce }) => {
|
|
42608
|
+
const arg = ops[0];
|
|
42609
|
+
if (isFunction2(arg) && arg.operator === "Rgb")
|
|
42610
|
+
return normalizeColorHead(ce, arg);
|
|
42611
|
+
const rgb = colorExprToRgb(arg);
|
|
42612
|
+
if (!rgb) return ce.error("incompatible-type");
|
|
42613
|
+
const args = [
|
|
42614
|
+
ce.number(rgb.r / 255),
|
|
42615
|
+
ce.number(rgb.g / 255),
|
|
42616
|
+
ce.number(rgb.b / 255)
|
|
42617
|
+
];
|
|
42618
|
+
if (rgb.alpha !== void 0) args.push(ce.number(rgb.alpha));
|
|
42619
|
+
return ce.function("Rgb", args);
|
|
42620
|
+
}
|
|
42621
|
+
},
|
|
42622
|
+
AsHsv: {
|
|
42623
|
+
description: "Convert any color to HSV (hue degrees, s/v 0-1)",
|
|
42624
|
+
complexity: 8e3,
|
|
42625
|
+
signature: "(color) -> color",
|
|
42626
|
+
evaluate: (ops, { engine: ce }) => {
|
|
42627
|
+
const arg = ops[0];
|
|
42628
|
+
if (isFunction2(arg) && arg.operator === "Hsv")
|
|
42629
|
+
return normalizeColorHead(ce, arg);
|
|
42630
|
+
const rgb = colorExprToRgb(arg);
|
|
42631
|
+
if (!rgb) return ce.error("incompatible-type");
|
|
42632
|
+
const hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
|
|
42633
|
+
const args = [ce.number(hsv.h), ce.number(hsv.s), ce.number(hsv.v)];
|
|
42634
|
+
if (rgb.alpha !== void 0) args.push(ce.number(rgb.alpha));
|
|
42635
|
+
return ce.function("Hsv", args);
|
|
42636
|
+
}
|
|
42637
|
+
},
|
|
42638
|
+
AsHsl: {
|
|
42639
|
+
description: "Convert any color to HSL (hue degrees, s/l 0-1)",
|
|
42640
|
+
complexity: 8e3,
|
|
42641
|
+
signature: "(color) -> color",
|
|
42642
|
+
evaluate: (ops, { engine: ce }) => {
|
|
42643
|
+
const arg = ops[0];
|
|
42644
|
+
if (isFunction2(arg) && arg.operator === "Hsl")
|
|
42645
|
+
return normalizeColorHead(ce, arg);
|
|
42646
|
+
const rgb = colorExprToRgb(arg);
|
|
42647
|
+
if (!rgb) return ce.error("incompatible-type");
|
|
42648
|
+
const hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);
|
|
42649
|
+
const args = [ce.number(hsl.h), ce.number(hsl.s), ce.number(hsl.l)];
|
|
42650
|
+
if (rgb.alpha !== void 0) args.push(ce.number(rgb.alpha));
|
|
42651
|
+
return ce.function("Hsl", args);
|
|
42652
|
+
}
|
|
42653
|
+
},
|
|
42654
|
+
AsOklab: {
|
|
42655
|
+
description: "Convert any color to OKLab",
|
|
42656
|
+
complexity: 8e3,
|
|
42657
|
+
signature: "(color) -> color",
|
|
42658
|
+
evaluate: (ops, { engine: ce }) => {
|
|
42659
|
+
const arg = ops[0];
|
|
42660
|
+
if (isFunction2(arg) && arg.operator === "Oklab")
|
|
42661
|
+
return normalizeColorHead(ce, arg);
|
|
42662
|
+
if (isFunction2(arg) && arg.operator === "Oklch") {
|
|
42663
|
+
const c = readColorExpr(arg);
|
|
42664
|
+
if (!c) return ce.error("incompatible-type");
|
|
42665
|
+
const lab2 = oklchToOklab({ L: c.c0, C: c.c1, H: c.c2, alpha: c.alpha });
|
|
42666
|
+
const args2 = [ce.number(lab2.L), ce.number(lab2.a), ce.number(lab2.b)];
|
|
42667
|
+
if (lab2.alpha !== void 0) args2.push(ce.number(lab2.alpha));
|
|
42668
|
+
return ce.function("Oklab", args2);
|
|
42669
|
+
}
|
|
42670
|
+
const rgb = colorExprToRgb(arg);
|
|
42671
|
+
if (!rgb) return ce.error("incompatible-type");
|
|
42672
|
+
const lab = rgbToOklab(rgb);
|
|
42673
|
+
const args = [ce.number(lab.L), ce.number(lab.a), ce.number(lab.b)];
|
|
42674
|
+
if (rgb.alpha !== void 0) args.push(ce.number(rgb.alpha));
|
|
42675
|
+
return ce.function("Oklab", args);
|
|
42676
|
+
}
|
|
42677
|
+
},
|
|
42678
|
+
AsOklch: {
|
|
42679
|
+
description: "Convert any color to OKLCh",
|
|
42680
|
+
complexity: 8e3,
|
|
42681
|
+
signature: "(color) -> color",
|
|
42682
|
+
evaluate: (ops, { engine: ce }) => {
|
|
42683
|
+
const arg = ops[0];
|
|
42684
|
+
if (isFunction2(arg) && arg.operator === "Oklch")
|
|
42685
|
+
return normalizeColorHead(ce, arg);
|
|
42686
|
+
if (isFunction2(arg) && arg.operator === "Oklab") {
|
|
42687
|
+
const c2 = readColorExpr(arg);
|
|
42688
|
+
if (!c2) return ce.error("incompatible-type");
|
|
42689
|
+
const oklch2 = oklabToOklch({
|
|
42690
|
+
L: c2.c0,
|
|
42691
|
+
a: c2.c1,
|
|
42692
|
+
b: c2.c2,
|
|
42693
|
+
alpha: c2.alpha
|
|
42694
|
+
});
|
|
42695
|
+
const args2 = [
|
|
42696
|
+
ce.number(oklch2.L),
|
|
42697
|
+
ce.number(oklch2.C),
|
|
42698
|
+
ce.number(oklch2.H)
|
|
42699
|
+
];
|
|
42700
|
+
if (oklch2.alpha !== void 0) args2.push(ce.number(oklch2.alpha));
|
|
42701
|
+
return ce.function("Oklch", args2);
|
|
42065
42702
|
}
|
|
42066
|
-
const
|
|
42067
|
-
return
|
|
42703
|
+
const rgb = colorExprToRgb(arg);
|
|
42704
|
+
if (!rgb) return ce.error("incompatible-type");
|
|
42705
|
+
const c = rgbToOklch(rgb);
|
|
42706
|
+
const args = [ce.number(c.L), ce.number(c.C), ce.number(c.H)];
|
|
42707
|
+
if (rgb.alpha !== void 0) args.push(ce.number(rgb.alpha));
|
|
42708
|
+
return ce.function("Oklch", args);
|
|
42709
|
+
}
|
|
42710
|
+
},
|
|
42711
|
+
// ---------------------------------------------------------------------------
|
|
42712
|
+
// Perceptual difference. Returns ΔE_OK (Euclidean distance in OKLab),
|
|
42713
|
+
// an approximately perceptually uniform scalar.
|
|
42714
|
+
// ---------------------------------------------------------------------------
|
|
42715
|
+
ColorDelta: {
|
|
42716
|
+
description: "Perceptual color difference (\u0394E_OK) between two colors",
|
|
42717
|
+
complexity: 8e3,
|
|
42718
|
+
signature: "(color | string | tuple, color | string | tuple) -> number",
|
|
42719
|
+
evaluate: (ops, { engine: ce }) => {
|
|
42720
|
+
const a = toOklch(ce, ops[0]);
|
|
42721
|
+
const b = toOklch(ce, ops[1]);
|
|
42722
|
+
if (!a || !b) return ce.error("incompatible-type");
|
|
42723
|
+
return ce.number(oklabDeltaE(oklchToOklab(a), oklchToOklab(b)));
|
|
42068
42724
|
}
|
|
42069
42725
|
}
|
|
42070
42726
|
};
|
|
@@ -42084,12 +42740,14 @@ var CONTROL_STRUCTURES_LIBRARY = [
|
|
|
42084
42740
|
canonical: canonicalBlock,
|
|
42085
42741
|
evaluate: evaluateBlock
|
|
42086
42742
|
},
|
|
42087
|
-
// A condition expression tests for one or more conditions of an expression
|
|
42088
|
-
//
|
|
42743
|
+
// A condition expression tests for one or more conditions of an expression.
|
|
42744
|
+
// Two forms:
|
|
42745
|
+
// ['Condition', value, "positive"] — tests value against named condition(s)
|
|
42746
|
+
// ['Condition', predicate] — set-builder predicate (e.g. x > 0)
|
|
42089
42747
|
Condition: {
|
|
42090
42748
|
description: "Test whether a value satisfies one or more conditions.",
|
|
42091
42749
|
lazy: true,
|
|
42092
|
-
signature: "(
|
|
42750
|
+
signature: "(expression, symbol?) -> boolean",
|
|
42093
42751
|
evaluate: ([value, conds], { engine }) => {
|
|
42094
42752
|
let conditions = [];
|
|
42095
42753
|
if (isSymbol2(conds)) {
|
|
@@ -44542,6 +45200,34 @@ var CORE_LIBRARY = [
|
|
|
44542
45200
|
signature: "() -> expression",
|
|
44543
45201
|
evaluate: (_ops, { engine }) => engine.expr(randomExpression())
|
|
44544
45202
|
}
|
|
45203
|
+
},
|
|
45204
|
+
// ---------------------------------------------------------------------------
|
|
45205
|
+
// Opaque typed heads — registered so the names are in the standard set
|
|
45206
|
+
// (consumers can branch on the operator name); CE itself does not evaluate
|
|
45207
|
+
// them. Geometric primitives `Triangle`/`Sphere`/`Segment` and the action
|
|
45208
|
+
// arrow `To` (`a \to b`).
|
|
45209
|
+
// ---------------------------------------------------------------------------
|
|
45210
|
+
{
|
|
45211
|
+
Triangle: {
|
|
45212
|
+
description: "Triangle primitive \u2014 opaque typed head.",
|
|
45213
|
+
signature: "(any+) -> expression"
|
|
45214
|
+
},
|
|
45215
|
+
GeometricVector: {
|
|
45216
|
+
description: "Geometric vector (directed segment between two points) \u2014 opaque typed head. Distinct from the column-vector `Vector` operator.",
|
|
45217
|
+
signature: "(any, any) -> expression"
|
|
45218
|
+
},
|
|
45219
|
+
Sphere: {
|
|
45220
|
+
description: "Sphere primitive \u2014 opaque typed head.",
|
|
45221
|
+
signature: "(any+) -> expression"
|
|
45222
|
+
},
|
|
45223
|
+
Segment: {
|
|
45224
|
+
description: "Segment primitive \u2014 opaque typed head.",
|
|
45225
|
+
signature: "(any+) -> expression"
|
|
45226
|
+
},
|
|
45227
|
+
To: {
|
|
45228
|
+
description: "Action arrow / mapping (`a \\to b`) \u2014 opaque typed head.",
|
|
45229
|
+
signature: "(any, any) -> nothing"
|
|
45230
|
+
}
|
|
44545
45231
|
}
|
|
44546
45232
|
];
|
|
44547
45233
|
|
|
@@ -51678,6 +52364,7 @@ function orderConvexHull(points) {
|
|
|
51678
52364
|
|
|
51679
52365
|
// src/compute-engine/boxed-expression/cache.ts
|
|
51680
52366
|
function cachedValue(v, generation, fn) {
|
|
52367
|
+
if (v.generation === generation && v.value !== null) return v.value;
|
|
51681
52368
|
v.generation = generation;
|
|
51682
52369
|
v.value = fn();
|
|
51683
52370
|
return v.value;
|
|
@@ -53455,6 +54142,12 @@ function _setProduct(fn) {
|
|
|
53455
54142
|
function _escapeJsonString(s) {
|
|
53456
54143
|
return s;
|
|
53457
54144
|
}
|
|
54145
|
+
function _serializeLatexMetadata(ce, expr2) {
|
|
54146
|
+
const syntax = ce.latexSyntax;
|
|
54147
|
+
const opts = ce.latexOptions;
|
|
54148
|
+
if (Object.keys(opts).length === 0) return syntax.serialize(expr2);
|
|
54149
|
+
return syntax.serialize(expr2, { ...opts });
|
|
54150
|
+
}
|
|
53458
54151
|
function serializeSubtract(ce, a, b, options, metadata) {
|
|
53459
54152
|
if (isNumber(a) && a.isNegative) {
|
|
53460
54153
|
const v = a.numericValue;
|
|
@@ -53759,7 +54452,7 @@ function serializeJsonFunction(ce, name, args, options, metadata) {
|
|
|
53759
54452
|
];
|
|
53760
54453
|
const md = { ...metadata ?? {} };
|
|
53761
54454
|
if (options.metadata.includes("latex") && ce.latexSyntax) {
|
|
53762
|
-
md.latex = _escapeJsonString(md.latex ?? ce
|
|
54455
|
+
md.latex = _escapeJsonString(md.latex ?? _serializeLatexMetadata(ce, fn));
|
|
53763
54456
|
} else md.latex = "";
|
|
53764
54457
|
if (!options.metadata.includes("wikidata")) md.wikidata = "";
|
|
53765
54458
|
if (!md.latex && !md.wikidata && options.shorthands.includes("function"))
|
|
@@ -53784,7 +54477,7 @@ function serializeJsonSymbol(ce, sym2, options, metadata) {
|
|
|
53784
54477
|
}
|
|
53785
54478
|
metadata = { ...metadata };
|
|
53786
54479
|
if (options.metadata.includes("latex") && ce.latexSyntax) {
|
|
53787
|
-
metadata.latex = metadata.latex ?? ce
|
|
54480
|
+
metadata.latex = metadata.latex ?? _serializeLatexMetadata(ce, sym2);
|
|
53788
54481
|
if (metadata.latex !== void 0)
|
|
53789
54482
|
metadata.latex = _escapeJsonString(metadata.latex);
|
|
53790
54483
|
} else metadata.latex = void 0;
|
|
@@ -53946,7 +54639,7 @@ function serializeJsonNumber(ce, value, options, metadata) {
|
|
|
53946
54639
|
}
|
|
53947
54640
|
}
|
|
53948
54641
|
if (options.metadata.includes("latex") && ce.latexSyntax)
|
|
53949
|
-
metadata.latex = metadata.latex ?? ce
|
|
54642
|
+
metadata.latex = metadata.latex ?? _serializeLatexMetadata(ce, result2 ?? { num });
|
|
53950
54643
|
if (result2) {
|
|
53951
54644
|
if (metadata.latex !== void 0)
|
|
53952
54645
|
return { sym: result2, latex: metadata.latex };
|
|
@@ -53962,7 +54655,7 @@ function serializeJsonNumber(ce, value, options, metadata) {
|
|
|
53962
54655
|
if (value.isNaN()) {
|
|
53963
54656
|
num = "NaN";
|
|
53964
54657
|
if (options.metadata.includes("latex") && ce.latexSyntax)
|
|
53965
|
-
metadata.latex = metadata.latex ?? ce
|
|
54658
|
+
metadata.latex = metadata.latex ?? _serializeLatexMetadata(ce, { num });
|
|
53966
54659
|
return metadata.latex !== void 0 ? { num, latex: metadata.latex } : { num };
|
|
53967
54660
|
}
|
|
53968
54661
|
return serializeJsonFunction(
|
|
@@ -53996,7 +54689,7 @@ function serializeJsonNumber(ce, value, options, metadata) {
|
|
|
53996
54689
|
value = Number(value);
|
|
53997
54690
|
} else {
|
|
53998
54691
|
if (options.metadata.includes("latex") && ce.latexSyntax)
|
|
53999
|
-
metadata.latex = metadata.latex ?? ce
|
|
54692
|
+
metadata.latex = metadata.latex ?? _serializeLatexMetadata(ce, {
|
|
54000
54693
|
num: value.toString()
|
|
54001
54694
|
});
|
|
54002
54695
|
if (metadata.latex !== void 0)
|
|
@@ -54010,7 +54703,7 @@ function serializeJsonNumber(ce, value, options, metadata) {
|
|
|
54010
54703
|
result = value > 0 ? "PositiveInfinity" : "NegativeInfinity";
|
|
54011
54704
|
else num = serializeRepeatingDecimals(value.toString(), options);
|
|
54012
54705
|
if (options.metadata.includes("latex") && ce.latexSyntax)
|
|
54013
|
-
metadata.latex = metadata.latex ?? ce
|
|
54706
|
+
metadata.latex = metadata.latex ?? _serializeLatexMetadata(ce, { num });
|
|
54014
54707
|
if (result) {
|
|
54015
54708
|
if (metadata.latex !== void 0)
|
|
54016
54709
|
return { sym: result, latex: metadata.latex };
|
|
@@ -54763,8 +55456,7 @@ function compile(expr2, options) {
|
|
|
54763
55456
|
vars: options?.vars,
|
|
54764
55457
|
imports: options?.imports,
|
|
54765
55458
|
preamble: options?.preamble,
|
|
54766
|
-
realOnly: options?.realOnly
|
|
54767
|
-
hints: options?.hints
|
|
55459
|
+
realOnly: options?.realOnly
|
|
54768
55460
|
});
|
|
54769
55461
|
} catch (e) {
|
|
54770
55462
|
if (options?.fallback ?? true) {
|
|
@@ -54776,8 +55468,7 @@ function compile(expr2, options) {
|
|
|
54776
55468
|
ce.pushScope();
|
|
54777
55469
|
try {
|
|
54778
55470
|
if (vars && typeof vars === "object") {
|
|
54779
|
-
for (const [k, v] of Object.entries(vars))
|
|
54780
|
-
ce.assign(k, v);
|
|
55471
|
+
for (const [k, v] of Object.entries(vars)) ce.assign(k, v);
|
|
54781
55472
|
}
|
|
54782
55473
|
return expr2.evaluate().re;
|
|
54783
55474
|
} finally {
|
|
@@ -60007,8 +60698,7 @@ function tryGetComplexParts(expr2, compile3) {
|
|
|
60007
60698
|
return { re: null, im: formatFloat(iScale) };
|
|
60008
60699
|
}
|
|
60009
60700
|
const compiledFactors = remaining.map((r) => compile3(r));
|
|
60010
|
-
if (iScale !== 1)
|
|
60011
|
-
compiledFactors.unshift(formatFloat(iScale));
|
|
60701
|
+
if (iScale !== 1) compiledFactors.unshift(formatFloat(iScale));
|
|
60012
60702
|
const imCode = foldTerms(compiledFactors, "1.0", "*");
|
|
60013
60703
|
return { re: null, im: imCode };
|
|
60014
60704
|
}
|
|
@@ -60612,39 +61302,130 @@ var JAVASCRIPT_FUNCTIONS = {
|
|
|
60612
61302
|
if (args.length >= 2)
|
|
60613
61303
|
return `_SYS.colormap(${compile3(args[0])}, ${compile3(args[1])})`;
|
|
60614
61304
|
return `_SYS.colormap(${compile3(args[0])})`;
|
|
61305
|
+
},
|
|
61306
|
+
// -----------------------------------------------------------------------
|
|
61307
|
+
// Color constructor heads. All compile to OKLCh arrays at runtime — the
|
|
61308
|
+
// canonical color representation in this target. The constructors take
|
|
61309
|
+
// their own colorspace's components and convert internally.
|
|
61310
|
+
// (Mirrors the GPU target's design: color values are vec3 OKLCh.)
|
|
61311
|
+
// -----------------------------------------------------------------------
|
|
61312
|
+
Rgb: (args, compile3) => {
|
|
61313
|
+
if (args.length < 3) throw new Error("Rgb: need 3 components");
|
|
61314
|
+
return `_SYS.rgb(${args.map(compile3).join(", ")})`;
|
|
61315
|
+
},
|
|
61316
|
+
Hsv: (args, compile3) => {
|
|
61317
|
+
if (args.length < 3) throw new Error("Hsv: need 3 components");
|
|
61318
|
+
return `_SYS.hsv(${args.map(compile3).join(", ")})`;
|
|
61319
|
+
},
|
|
61320
|
+
Hsl: (args, compile3) => {
|
|
61321
|
+
if (args.length < 3) throw new Error("Hsl: need 3 components");
|
|
61322
|
+
return `_SYS.hsl(${args.map(compile3).join(", ")})`;
|
|
61323
|
+
},
|
|
61324
|
+
Oklab: (args, compile3) => {
|
|
61325
|
+
if (args.length < 3) throw new Error("Oklab: need 3 components");
|
|
61326
|
+
return `_SYS.oklab(${args.map(compile3).join(", ")})`;
|
|
61327
|
+
},
|
|
61328
|
+
Oklch: (args, compile3) => {
|
|
61329
|
+
if (args.length < 3) throw new Error("Oklch: need 3 components");
|
|
61330
|
+
return `_SYS.oklch(${args.map(compile3).join(", ")})`;
|
|
61331
|
+
},
|
|
61332
|
+
// -----------------------------------------------------------------------
|
|
61333
|
+
// As* converters. Compile-time output convention matches the engine and
|
|
61334
|
+
// the GPU target: each returns components in the named space as a 3- or
|
|
61335
|
+
// 4-element array. `AsRgb` uses 0-1 sRGB channels (consistent across all
|
|
61336
|
+
// layers). `AsOklch` is the identity (canonical form).
|
|
61337
|
+
// -----------------------------------------------------------------------
|
|
61338
|
+
AsRgb: ([c], compile3) => {
|
|
61339
|
+
if (c === null) throw new Error("AsRgb: no argument");
|
|
61340
|
+
return `_SYS.asRgb(${compile3(c)})`;
|
|
61341
|
+
},
|
|
61342
|
+
AsHsv: ([c], compile3) => {
|
|
61343
|
+
if (c === null) throw new Error("AsHsv: no argument");
|
|
61344
|
+
return `_SYS.asHsv(${compile3(c)})`;
|
|
61345
|
+
},
|
|
61346
|
+
AsHsl: ([c], compile3) => {
|
|
61347
|
+
if (c === null) throw new Error("AsHsl: no argument");
|
|
61348
|
+
return `_SYS.asHsl(${compile3(c)})`;
|
|
61349
|
+
},
|
|
61350
|
+
AsOklab: ([c], compile3) => {
|
|
61351
|
+
if (c === null) throw new Error("AsOklab: no argument");
|
|
61352
|
+
return `_SYS.asOklab(${compile3(c)})`;
|
|
61353
|
+
},
|
|
61354
|
+
AsOklch: ([c], compile3) => {
|
|
61355
|
+
if (c === null) throw new Error("AsOklch: no argument");
|
|
61356
|
+
return compile3(c);
|
|
61357
|
+
},
|
|
61358
|
+
// Perceptual color difference (ΔE_OK).
|
|
61359
|
+
ColorDelta: ([a, b], compile3) => {
|
|
61360
|
+
if (a === null || b === null)
|
|
61361
|
+
throw new Error("ColorDelta: need two colors");
|
|
61362
|
+
return `_SYS.colorDelta(${compile3(a)}, ${compile3(b)})`;
|
|
61363
|
+
},
|
|
61364
|
+
// Euclidean distance between two tuples (any positive dimension).
|
|
61365
|
+
// The GPU target maps `Distance` to the GLSL/WGSL `distance()` builtin
|
|
61366
|
+
// (vec-only); this JS handler works on plain arrays of any length.
|
|
61367
|
+
Distance: ([a, b], compile3) => {
|
|
61368
|
+
if (a === null || b === null) throw new Error("Distance: need two points");
|
|
61369
|
+
return `_SYS.distance(${compile3(a)}, ${compile3(b)})`;
|
|
60615
61370
|
}
|
|
60616
61371
|
};
|
|
60617
61372
|
function toRI(c) {
|
|
60618
61373
|
return { re: c.re, im: c.im };
|
|
60619
61374
|
}
|
|
61375
|
+
function normalizeAlpha2(a) {
|
|
61376
|
+
if (a === void 0) return void 0;
|
|
61377
|
+
if (!Number.isFinite(a)) return void 0;
|
|
61378
|
+
if (Math.abs(a - 1) < 1e-9) return void 0;
|
|
61379
|
+
return a;
|
|
61380
|
+
}
|
|
60620
61381
|
function toRgb255(input) {
|
|
60621
61382
|
if (typeof input === "string") {
|
|
60622
61383
|
const c = parseColor(input);
|
|
60623
|
-
|
|
61384
|
+
const rgb2 = {
|
|
60624
61385
|
r: c >>> 24 & 255,
|
|
60625
61386
|
g: c >>> 16 & 255,
|
|
60626
|
-
b: c >>> 8 & 255
|
|
60627
|
-
alpha: (c & 255) / 255
|
|
61387
|
+
b: c >>> 8 & 255
|
|
60628
61388
|
};
|
|
61389
|
+
const alpha = normalizeAlpha2((c & 255) / 255);
|
|
61390
|
+
if (alpha !== void 0) rgb2.alpha = alpha;
|
|
61391
|
+
return rgb2;
|
|
61392
|
+
}
|
|
61393
|
+
const rgb = oklchToRgb({ L: input[0], C: input[1], H: input[2] });
|
|
61394
|
+
if (input.length >= 4) {
|
|
61395
|
+
const alpha = normalizeAlpha2(input[3]);
|
|
61396
|
+
if (alpha !== void 0) rgb.alpha = alpha;
|
|
60629
61397
|
}
|
|
60630
|
-
const rgb = {
|
|
60631
|
-
r: input[0] * 255,
|
|
60632
|
-
g: input[1] * 255,
|
|
60633
|
-
b: input[2] * 255
|
|
60634
|
-
};
|
|
60635
|
-
if (input.length >= 4) rgb.alpha = input[3];
|
|
60636
61398
|
return rgb;
|
|
60637
61399
|
}
|
|
60638
|
-
function
|
|
60639
|
-
|
|
60640
|
-
|
|
60641
|
-
|
|
60642
|
-
|
|
60643
|
-
|
|
61400
|
+
function toOklch2(input) {
|
|
61401
|
+
if (typeof input === "string") {
|
|
61402
|
+
const c = parseColor(input);
|
|
61403
|
+
const r = c >>> 24 & 255;
|
|
61404
|
+
const g = c >>> 16 & 255;
|
|
61405
|
+
const b = c >>> 8 & 255;
|
|
61406
|
+
const oklch2 = rgbToOklch({ r, g, b });
|
|
61407
|
+
const alpha = normalizeAlpha2((c & 255) / 255);
|
|
61408
|
+
if (alpha !== void 0) oklch2.alpha = alpha;
|
|
61409
|
+
return oklch2;
|
|
61410
|
+
}
|
|
61411
|
+
return {
|
|
61412
|
+
L: input[0],
|
|
61413
|
+
C: input[1],
|
|
61414
|
+
H: input[2],
|
|
61415
|
+
alpha: input.length >= 4 ? normalizeAlpha2(input[3]) : void 0
|
|
61416
|
+
};
|
|
61417
|
+
}
|
|
61418
|
+
function packedToOklch(c) {
|
|
61419
|
+
const r = c >>> 24 & 255;
|
|
61420
|
+
const g = c >>> 16 & 255;
|
|
61421
|
+
const b = c >>> 8 & 255;
|
|
61422
|
+
const oklch2 = rgbToOklch({ r, g, b });
|
|
61423
|
+
const alpha = normalizeAlpha2((c & 255) / 255);
|
|
61424
|
+
return alpha !== void 0 ? [oklch2.L, oklch2.C, oklch2.H, alpha] : [oklch2.L, oklch2.C, oklch2.H];
|
|
60644
61425
|
}
|
|
60645
61426
|
var colorHelpers = {
|
|
60646
61427
|
color(input) {
|
|
60647
|
-
return
|
|
61428
|
+
return packedToOklch(parseColor(input));
|
|
60648
61429
|
},
|
|
60649
61430
|
colorToString(input, format) {
|
|
60650
61431
|
const rgb = toRgb255(input);
|
|
@@ -60655,7 +61436,7 @@ var colorHelpers = {
|
|
|
60655
61436
|
const g = Math.round(Math.max(0, Math.min(255, rgb.g)));
|
|
60656
61437
|
const b = Math.round(Math.max(0, Math.min(255, rgb.b)));
|
|
60657
61438
|
let hex = `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
|
|
60658
|
-
if (rgb.alpha !== void 0
|
|
61439
|
+
if (rgb.alpha !== void 0) {
|
|
60659
61440
|
const a = Math.round(Math.max(0, Math.min(255, rgb.alpha * 255)));
|
|
60660
61441
|
hex += a.toString(16).padStart(2, "0");
|
|
60661
61442
|
}
|
|
@@ -60665,7 +61446,7 @@ var colorHelpers = {
|
|
|
60665
61446
|
const r = Math.round(rgb.r);
|
|
60666
61447
|
const g = Math.round(rgb.g);
|
|
60667
61448
|
const b = Math.round(rgb.b);
|
|
60668
|
-
if (rgb.alpha !== void 0
|
|
61449
|
+
if (rgb.alpha !== void 0)
|
|
60669
61450
|
return `rgb(${r} ${g} ${b} / ${rgb.alpha})`;
|
|
60670
61451
|
return `rgb(${r} ${g} ${b})`;
|
|
60671
61452
|
}
|
|
@@ -60674,7 +61455,7 @@ var colorHelpers = {
|
|
|
60674
61455
|
const h = Math.round(hsl.h * 10) / 10;
|
|
60675
61456
|
const s = Math.round(hsl.s * 1e3) / 10;
|
|
60676
61457
|
const l = Math.round(hsl.l * 1e3) / 10;
|
|
60677
|
-
if (rgb.alpha !== void 0
|
|
61458
|
+
if (rgb.alpha !== void 0)
|
|
60678
61459
|
return `hsl(${h} ${s}% ${l}% / ${rgb.alpha})`;
|
|
60679
61460
|
return `hsl(${h} ${s}% ${l}%)`;
|
|
60680
61461
|
}
|
|
@@ -60683,7 +61464,7 @@ var colorHelpers = {
|
|
|
60683
61464
|
const L = Math.round(c.L * 1e3) / 1e3;
|
|
60684
61465
|
const C = Math.round(c.C * 1e3) / 1e3;
|
|
60685
61466
|
const H = Math.round(c.H * 10) / 10;
|
|
60686
|
-
if (rgb.alpha !== void 0
|
|
61467
|
+
if (rgb.alpha !== void 0)
|
|
60687
61468
|
return `oklch(${L} ${C} ${H} / ${rgb.alpha})`;
|
|
60688
61469
|
return `oklch(${L} ${C} ${H})`;
|
|
60689
61470
|
}
|
|
@@ -60692,29 +61473,29 @@ var colorHelpers = {
|
|
|
60692
61473
|
}
|
|
60693
61474
|
},
|
|
60694
61475
|
colorMix(input1, input2, ratio = 0.5) {
|
|
60695
|
-
const
|
|
60696
|
-
const
|
|
61476
|
+
const c1 = toOklch2(input1);
|
|
61477
|
+
const c2 = toOklch2(input2);
|
|
60697
61478
|
ratio = Math.max(0, Math.min(1, ratio));
|
|
60698
|
-
const
|
|
60699
|
-
const
|
|
60700
|
-
let
|
|
60701
|
-
if (
|
|
60702
|
-
if (
|
|
60703
|
-
|
|
60704
|
-
|
|
60705
|
-
|
|
60706
|
-
|
|
60707
|
-
|
|
60708
|
-
|
|
60709
|
-
H
|
|
60710
|
-
|
|
60711
|
-
|
|
60712
|
-
const
|
|
60713
|
-
const
|
|
60714
|
-
const a1 =
|
|
60715
|
-
const a2 =
|
|
60716
|
-
const alpha = a1 + (a2 - a1) * ratio;
|
|
60717
|
-
return
|
|
61479
|
+
const c1Achromatic = c1.C < 1e-6;
|
|
61480
|
+
const c2Achromatic = c2.C < 1e-6;
|
|
61481
|
+
let H;
|
|
61482
|
+
if (c1Achromatic && c2Achromatic) H = c1.H;
|
|
61483
|
+
else if (c1Achromatic) H = c2.H;
|
|
61484
|
+
else if (c2Achromatic) H = c1.H;
|
|
61485
|
+
else {
|
|
61486
|
+
let dh = c2.H - c1.H;
|
|
61487
|
+
if (dh > 180) dh -= 360;
|
|
61488
|
+
if (dh < -180) dh += 360;
|
|
61489
|
+
H = c1.H + dh * ratio;
|
|
61490
|
+
if (H < 0) H += 360;
|
|
61491
|
+
if (H >= 360) H -= 360;
|
|
61492
|
+
}
|
|
61493
|
+
const L = c1.L + (c2.L - c1.L) * ratio;
|
|
61494
|
+
const C = c1.C + (c2.C - c1.C) * ratio;
|
|
61495
|
+
const a1 = c1.alpha ?? 1;
|
|
61496
|
+
const a2 = c2.alpha ?? 1;
|
|
61497
|
+
const alpha = normalizeAlpha2(a1 + (a2 - a1) * ratio);
|
|
61498
|
+
return alpha !== void 0 ? [L, C, H, alpha] : [L, C, H];
|
|
60718
61499
|
},
|
|
60719
61500
|
colorContrast(bg, fg) {
|
|
60720
61501
|
return apca(toRgb255(bg), toRgb255(fg));
|
|
@@ -60722,11 +61503,11 @@ var colorHelpers = {
|
|
|
60722
61503
|
contrastingColor(bg, fg1, fg2) {
|
|
60723
61504
|
const bgRgb = toRgb255(bg);
|
|
60724
61505
|
if (fg1 !== void 0 && fg2 !== void 0) {
|
|
60725
|
-
return
|
|
61506
|
+
return packedToOklch(
|
|
60726
61507
|
contrastingColor({ bg: bgRgb, fg1: toRgb255(fg1), fg2: toRgb255(fg2) })
|
|
60727
61508
|
);
|
|
60728
61509
|
}
|
|
60729
|
-
return
|
|
61510
|
+
return packedToOklch(contrastingColor(bgRgb));
|
|
60730
61511
|
},
|
|
60731
61512
|
colorToColorspace(input, space) {
|
|
60732
61513
|
const rgb = toRgb255(input);
|
|
@@ -60755,7 +61536,7 @@ var colorHelpers = {
|
|
|
60755
61536
|
default:
|
|
60756
61537
|
throw new Error(`Unknown color space: ${space}`);
|
|
60757
61538
|
}
|
|
60758
|
-
if (alpha !== void 0
|
|
61539
|
+
if (alpha !== void 0) result.push(alpha);
|
|
60759
61540
|
return result;
|
|
60760
61541
|
},
|
|
60761
61542
|
colormap(name, arg) {
|
|
@@ -60767,7 +61548,7 @@ var colorHelpers = {
|
|
|
60767
61548
|
const palette = allPalettes[name];
|
|
60768
61549
|
if (!palette) throw new Error(`Unknown palette: ${name}`);
|
|
60769
61550
|
const colors = palette.map(
|
|
60770
|
-
(hex) =>
|
|
61551
|
+
(hex) => packedToOklch(parseColor(hex))
|
|
60771
61552
|
);
|
|
60772
61553
|
if (arg === void 0) return colors;
|
|
60773
61554
|
if (Number.isInteger(arg) && arg >= 2) {
|
|
@@ -60791,62 +61572,128 @@ var colorHelpers = {
|
|
|
60791
61572
|
const frac = pos - i;
|
|
60792
61573
|
if (frac === 0 || i >= colors.length - 1)
|
|
60793
61574
|
return [...colors[Math.min(i, colors.length - 1)]];
|
|
60794
|
-
const
|
|
60795
|
-
|
|
60796
|
-
|
|
60797
|
-
|
|
60798
|
-
|
|
60799
|
-
|
|
60800
|
-
|
|
60801
|
-
|
|
60802
|
-
|
|
60803
|
-
|
|
60804
|
-
|
|
60805
|
-
|
|
60806
|
-
|
|
60807
|
-
|
|
60808
|
-
|
|
60809
|
-
|
|
60810
|
-
|
|
60811
|
-
if (H >= 360) H -= 360;
|
|
60812
|
-
const mixed = oklchToRgb({
|
|
60813
|
-
L: c1.L + (c2.L - c1.L) * frac,
|
|
60814
|
-
C: c1.C + (c2.C - c1.C) * frac,
|
|
60815
|
-
H
|
|
60816
|
-
});
|
|
60817
|
-
return [mixed.r / 255, mixed.g / 255, mixed.b / 255];
|
|
61575
|
+
const [L1, C1, H1] = colors[i];
|
|
61576
|
+
const [L2, C2, H2] = colors[i + 1];
|
|
61577
|
+
const c1Achromatic = C1 < 1e-6;
|
|
61578
|
+
const c2Achromatic = C2 < 1e-6;
|
|
61579
|
+
let H;
|
|
61580
|
+
if (c1Achromatic && c2Achromatic) H = H1;
|
|
61581
|
+
else if (c1Achromatic) H = H2;
|
|
61582
|
+
else if (c2Achromatic) H = H1;
|
|
61583
|
+
else {
|
|
61584
|
+
let dh = H2 - H1;
|
|
61585
|
+
if (dh > 180) dh -= 360;
|
|
61586
|
+
if (dh < -180) dh += 360;
|
|
61587
|
+
H = H1 + dh * frac;
|
|
61588
|
+
if (H < 0) H += 360;
|
|
61589
|
+
if (H >= 360) H -= 360;
|
|
61590
|
+
}
|
|
61591
|
+
return [L1 + (L2 - L1) * frac, C1 + (C2 - C1) * frac, H];
|
|
60818
61592
|
},
|
|
60819
61593
|
colorFromColorspace(components, space) {
|
|
60820
61594
|
const c0 = components[0];
|
|
60821
61595
|
const c1 = components[1];
|
|
60822
61596
|
const c2 = components[2];
|
|
60823
61597
|
const alpha = components.length >= 4 ? components[3] : void 0;
|
|
60824
|
-
let
|
|
61598
|
+
let oklch2;
|
|
60825
61599
|
switch (space.toLowerCase()) {
|
|
60826
61600
|
case "rgb":
|
|
60827
|
-
|
|
61601
|
+
oklch2 = rgbToOklch({ r: c0 * 255, g: c1 * 255, b: c2 * 255 });
|
|
60828
61602
|
break;
|
|
60829
61603
|
case "hsl": {
|
|
60830
|
-
const
|
|
60831
|
-
|
|
61604
|
+
const rgb = hslToRgb(c0, c1, c2);
|
|
61605
|
+
oklch2 = rgbToOklch(rgb);
|
|
60832
61606
|
break;
|
|
60833
61607
|
}
|
|
60834
|
-
case "oklch":
|
|
60835
|
-
|
|
60836
|
-
result = [r.r / 255, r.g / 255, r.b / 255];
|
|
61608
|
+
case "oklch":
|
|
61609
|
+
oklch2 = { L: c0, C: c1, H: c2 };
|
|
60837
61610
|
break;
|
|
60838
|
-
}
|
|
60839
61611
|
case "oklab":
|
|
60840
|
-
case "lab":
|
|
60841
|
-
|
|
60842
|
-
result = [r.r / 255, r.g / 255, r.b / 255];
|
|
61612
|
+
case "lab":
|
|
61613
|
+
oklch2 = oklabToOklch({ L: c0, a: c1, b: c2 });
|
|
60843
61614
|
break;
|
|
60844
|
-
}
|
|
60845
61615
|
default:
|
|
60846
61616
|
throw new Error(`Unknown color space: ${space}`);
|
|
60847
61617
|
}
|
|
60848
|
-
|
|
60849
|
-
|
|
61618
|
+
return alpha !== void 0 ? [oklch2.L, oklch2.C, oklch2.H, alpha] : [oklch2.L, oklch2.C, oklch2.H];
|
|
61619
|
+
},
|
|
61620
|
+
// -----------------------------------------------------------------------
|
|
61621
|
+
// Color constructors. Each accepts components in its colorspace's natural
|
|
61622
|
+
// units and returns the canonical OKLCh array `[L, C, H]` (or with alpha).
|
|
61623
|
+
// -----------------------------------------------------------------------
|
|
61624
|
+
rgb(r, g, b, alpha) {
|
|
61625
|
+
const c = rgbToOklch({ r: r * 255, g: g * 255, b: b * 255 });
|
|
61626
|
+
const a = normalizeAlpha2(alpha);
|
|
61627
|
+
return a !== void 0 ? [c.L, c.C, c.H, a] : [c.L, c.C, c.H];
|
|
61628
|
+
},
|
|
61629
|
+
hsv(h, s, v, alpha) {
|
|
61630
|
+
const rgb = hsvToRgb(h, s, v);
|
|
61631
|
+
const c = rgbToOklch(rgb);
|
|
61632
|
+
const a = normalizeAlpha2(alpha);
|
|
61633
|
+
return a !== void 0 ? [c.L, c.C, c.H, a] : [c.L, c.C, c.H];
|
|
61634
|
+
},
|
|
61635
|
+
hsl(h, s, l, alpha) {
|
|
61636
|
+
const rgb = hslToRgb(h, s, l);
|
|
61637
|
+
const c = rgbToOklch({ r: rgb.r, g: rgb.g, b: rgb.b });
|
|
61638
|
+
const a = normalizeAlpha2(alpha);
|
|
61639
|
+
return a !== void 0 ? [c.L, c.C, c.H, a] : [c.L, c.C, c.H];
|
|
61640
|
+
},
|
|
61641
|
+
oklab(L, a, b, alpha) {
|
|
61642
|
+
const c = oklabToOklch({ L, a, b });
|
|
61643
|
+
const al = normalizeAlpha2(alpha);
|
|
61644
|
+
return al !== void 0 ? [c.L, c.C, c.H, al] : [c.L, c.C, c.H];
|
|
61645
|
+
},
|
|
61646
|
+
oklch(L, C, H, alpha) {
|
|
61647
|
+
const a = normalizeAlpha2(alpha);
|
|
61648
|
+
return a !== void 0 ? [L, C, H, a] : [L, C, H];
|
|
61649
|
+
},
|
|
61650
|
+
// -----------------------------------------------------------------------
|
|
61651
|
+
// As* converters. Inputs are anything `toOklch` accepts (string, packed
|
|
61652
|
+
// int, or OKLCh array). Outputs are 3- or 4-element arrays in the named
|
|
61653
|
+
// space. sRGB-based outputs (asRgb/asHsv/asHsl) use 0-1 channels for
|
|
61654
|
+
// consistency with the GPU target's shader convention.
|
|
61655
|
+
// -----------------------------------------------------------------------
|
|
61656
|
+
asRgb(input) {
|
|
61657
|
+
const rgb = toRgb255(input);
|
|
61658
|
+
const r = rgb.r / 255;
|
|
61659
|
+
const g = rgb.g / 255;
|
|
61660
|
+
const b = rgb.b / 255;
|
|
61661
|
+
return rgb.alpha !== void 0 ? [r, g, b, rgb.alpha] : [r, g, b];
|
|
61662
|
+
},
|
|
61663
|
+
asHsv(input) {
|
|
61664
|
+
const rgb = toRgb255(input);
|
|
61665
|
+
const hsv = rgbToHsv(rgb.r, rgb.g, rgb.b);
|
|
61666
|
+
return rgb.alpha !== void 0 ? [hsv.h, hsv.s, hsv.v, rgb.alpha] : [hsv.h, hsv.s, hsv.v];
|
|
61667
|
+
},
|
|
61668
|
+
asHsl(input) {
|
|
61669
|
+
const rgb = toRgb255(input);
|
|
61670
|
+
const hsl = rgbToHsl(rgb.r, rgb.g, rgb.b);
|
|
61671
|
+
return rgb.alpha !== void 0 ? [hsl.h, hsl.s, hsl.l, rgb.alpha] : [hsl.h, hsl.s, hsl.l];
|
|
61672
|
+
},
|
|
61673
|
+
asOklab(input) {
|
|
61674
|
+
const c = toOklch2(input);
|
|
61675
|
+
const lab = oklchToOklab({ L: c.L, C: c.C, H: c.H });
|
|
61676
|
+
return c.alpha !== void 0 ? [lab.L, lab.a, lab.b, c.alpha] : [lab.L, lab.a, lab.b];
|
|
61677
|
+
},
|
|
61678
|
+
// asOklch is identity — handled at compile time as a pass-through
|
|
61679
|
+
// Perceptual color difference (ΔE_OK).
|
|
61680
|
+
colorDelta(a, b) {
|
|
61681
|
+
const labA = oklchToOklab(toOklch2(a));
|
|
61682
|
+
const labB = oklchToOklab(toOklch2(b));
|
|
61683
|
+
return oklabDeltaE(labA, labB);
|
|
61684
|
+
},
|
|
61685
|
+
// Euclidean distance between two tuples. Plain numeric — not a color
|
|
61686
|
+
// operation despite living in the same helpers block.
|
|
61687
|
+
distance(a, b) {
|
|
61688
|
+
if (!Array.isArray(a) || !Array.isArray(b))
|
|
61689
|
+
throw new Error("Distance: expected two arrays");
|
|
61690
|
+
if (a.length !== b.length) throw new Error("Distance: dimension mismatch");
|
|
61691
|
+
let sumSq = 0;
|
|
61692
|
+
for (let i = 0; i < a.length; i++) {
|
|
61693
|
+
const d = a[i] - b[i];
|
|
61694
|
+
sumSq += d * d;
|
|
61695
|
+
}
|
|
61696
|
+
return Math.sqrt(sumSq);
|
|
60850
61697
|
}
|
|
60851
61698
|
};
|
|
60852
61699
|
var SYS_HELPERS = {
|
|
@@ -61264,43 +62111,6 @@ function fibonacci(n) {
|
|
|
61264
62111
|
return b;
|
|
61265
62112
|
}
|
|
61266
62113
|
|
|
61267
|
-
// src/compute-engine/compilation/fractal-orbit.ts
|
|
61268
|
-
function toBigDecimal(v) {
|
|
61269
|
-
if (typeof v === "object" && "hi" in v)
|
|
61270
|
-
return new BigDecimal(v.hi).add(new BigDecimal(v.lo));
|
|
61271
|
-
return new BigDecimal(v);
|
|
61272
|
-
}
|
|
61273
|
-
function hpToNumber(v) {
|
|
61274
|
-
if (typeof v === "number") return v;
|
|
61275
|
-
if (typeof v === "string") return Number(v);
|
|
61276
|
-
return v.hi + v.lo;
|
|
61277
|
-
}
|
|
61278
|
-
function computeReferenceOrbit(center, maxIter, precision) {
|
|
61279
|
-
const prevPrecision = BigDecimal.precision;
|
|
61280
|
-
BigDecimal.precision = precision;
|
|
61281
|
-
try {
|
|
61282
|
-
const cr = toBigDecimal(center[0]);
|
|
61283
|
-
const ci = toBigDecimal(center[1]);
|
|
61284
|
-
let zr = BigDecimal.ZERO;
|
|
61285
|
-
let zi = BigDecimal.ZERO;
|
|
61286
|
-
const ESCAPE = new BigDecimal(256);
|
|
61287
|
-
const points = [];
|
|
61288
|
-
for (let i = 0; i < maxIter; i++) {
|
|
61289
|
-
points.push(zr.toNumber(), zi.toNumber());
|
|
61290
|
-
const zr2 = zr.mul(zr).toPrecision(precision);
|
|
61291
|
-
const zi2 = zi.mul(zi).toPrecision(precision);
|
|
61292
|
-
const mag2 = zr2.add(zi2);
|
|
61293
|
-
if (mag2.cmp(ESCAPE) > 0) break;
|
|
61294
|
-
const new_zi = zr.mul(zi).toPrecision(precision).mul(2).add(ci);
|
|
61295
|
-
zr = zr2.sub(zi2).add(cr);
|
|
61296
|
-
zi = new_zi;
|
|
61297
|
-
}
|
|
61298
|
-
return new Float32Array(points);
|
|
61299
|
-
} finally {
|
|
61300
|
-
BigDecimal.precision = prevPrecision;
|
|
61301
|
-
}
|
|
61302
|
-
}
|
|
61303
|
-
|
|
61304
62114
|
// src/compute-engine/compilation/gpu-target.ts
|
|
61305
62115
|
var GPU_OPERATORS = {
|
|
61306
62116
|
Add: ["+", 11],
|
|
@@ -61322,6 +62132,13 @@ var GPU_OPERATORS = {
|
|
|
61322
62132
|
function gpuVec2(target) {
|
|
61323
62133
|
return target?.language === "wgsl" ? "vec2f" : "vec2";
|
|
61324
62134
|
}
|
|
62135
|
+
function gpuVec3(target) {
|
|
62136
|
+
return target?.language === "wgsl" ? "vec3f" : "vec3";
|
|
62137
|
+
}
|
|
62138
|
+
function readStringLiteral(expr2) {
|
|
62139
|
+
if (!isString(expr2)) return null;
|
|
62140
|
+
return expr2.string?.toLowerCase() ?? null;
|
|
62141
|
+
}
|
|
61325
62142
|
function compileIntArg(expr2, compile3, target) {
|
|
61326
62143
|
const c = tryGetConstant(expr2);
|
|
61327
62144
|
if (c !== void 0 && Number.isInteger(c)) return c.toString();
|
|
@@ -61380,17 +62197,10 @@ function compileGPUSumProduct(kind, args, _compile2, target) {
|
|
|
61380
62197
|
`for (${indexDecl} = ${lowerStr}; ${index} <= ${upperStr}; ${index}++) {`,
|
|
61381
62198
|
` ${acc} ${op}= ${body};`,
|
|
61382
62199
|
`}`,
|
|
61383
|
-
`return ${acc}
|
|
62200
|
+
`return ${acc};`
|
|
61384
62201
|
];
|
|
61385
62202
|
return lines.join("\n");
|
|
61386
62203
|
}
|
|
61387
|
-
function selectFractalStrategy(target) {
|
|
61388
|
-
const radius = target.hints?.viewport?.radius;
|
|
61389
|
-
if (radius === void 0) return "single";
|
|
61390
|
-
if (radius > 1e-6) return "single";
|
|
61391
|
-
if (radius > 1e-14) return "double";
|
|
61392
|
-
return "perturbation";
|
|
61393
|
-
}
|
|
61394
62204
|
var GPU_FUNCTIONS = {
|
|
61395
62205
|
// Variadic arithmetic (for function-call form, e.g., with vectors)
|
|
61396
62206
|
Add: (args, compile3, target) => {
|
|
@@ -61441,8 +62251,7 @@ var GPU_FUNCTIONS = {
|
|
|
61441
62251
|
const iScale = isSymbol2(iFactor, "ImaginaryUnit") ? 1 : iFactor.im;
|
|
61442
62252
|
const realFactors = args.filter((_, i) => i !== iIndex);
|
|
61443
62253
|
const v2 = gpuVec2(target);
|
|
61444
|
-
if (realFactors.length === 0)
|
|
61445
|
-
return `${v2}(0.0, ${formatFloat(iScale)})`;
|
|
62254
|
+
if (realFactors.length === 0) return `${v2}(0.0, ${formatFloat(iScale)})`;
|
|
61446
62255
|
const factors = realFactors.map((f) => compile3(f));
|
|
61447
62256
|
if (iScale !== 1) factors.unshift(formatFloat(iScale));
|
|
61448
62257
|
const imCode = foldTerms(factors, "1.0", "*");
|
|
@@ -61495,8 +62304,7 @@ var GPU_FUNCTIONS = {
|
|
|
61495
62304
|
if (isNumber(x) && x.im !== 0) {
|
|
61496
62305
|
return `${gpuVec2(target)}(${formatFloat(-x.re)}, ${formatFloat(-x.im)})`;
|
|
61497
62306
|
}
|
|
61498
|
-
if (isSymbol2(x, "ImaginaryUnit"))
|
|
61499
|
-
return `${gpuVec2(target)}(0.0, -1.0)`;
|
|
62307
|
+
if (isSymbol2(x, "ImaginaryUnit")) return `${gpuVec2(target)}(0.0, -1.0)`;
|
|
61500
62308
|
return `(-${compile3(x)})`;
|
|
61501
62309
|
},
|
|
61502
62310
|
// Standard math functions with complex dispatch
|
|
@@ -61869,49 +62677,139 @@ var GPU_FUNCTIONS = {
|
|
|
61869
62677
|
}
|
|
61870
62678
|
const isWGSL = target?.language === "wgsl";
|
|
61871
62679
|
const v3 = isWGSL ? "vec3f" : "vec3";
|
|
61872
|
-
|
|
62680
|
+
const black = `${v3}(0.0)`;
|
|
62681
|
+
const white = `${v3}(1.0, 0.0, 0.0)`;
|
|
62682
|
+
return `((_gpu_apca(${bg}, ${black}) > 50.0) ? ${black} : ${white})`;
|
|
61873
62683
|
},
|
|
61874
62684
|
ColorToColorspace: ([color, space], compile3) => {
|
|
61875
62685
|
if (color === null || space === null)
|
|
61876
62686
|
throw new Error("ColorToColorspace: need color and space");
|
|
61877
|
-
|
|
62687
|
+
const spaceName = readStringLiteral(space);
|
|
62688
|
+
if (spaceName === null)
|
|
62689
|
+
throw new Error("ColorToColorspace: space must be a string literal");
|
|
62690
|
+
const c = compile3(color);
|
|
62691
|
+
switch (spaceName) {
|
|
62692
|
+
case "oklch":
|
|
62693
|
+
return c;
|
|
62694
|
+
case "oklab":
|
|
62695
|
+
case "lab":
|
|
62696
|
+
return `_gpu_oklch_to_oklab(${c})`;
|
|
62697
|
+
case "rgb":
|
|
62698
|
+
return `_gpu_oklch_to_srgb(${c})`;
|
|
62699
|
+
case "hsl":
|
|
62700
|
+
return `_gpu_rgb_to_hsl(_gpu_oklch_to_srgb(${c}))`;
|
|
62701
|
+
case "hsv":
|
|
62702
|
+
return `_gpu_rgb_to_hsv(_gpu_oklch_to_srgb(${c}))`;
|
|
62703
|
+
default:
|
|
62704
|
+
throw new Error(
|
|
62705
|
+
`ColorToColorspace: unsupported space "${spaceName}" on GPU target`
|
|
62706
|
+
);
|
|
62707
|
+
}
|
|
61878
62708
|
},
|
|
61879
62709
|
ColorFromColorspace: ([components, space], compile3) => {
|
|
61880
62710
|
if (components === null || space === null)
|
|
61881
62711
|
throw new Error("ColorFromColorspace: need components and space");
|
|
61882
|
-
|
|
62712
|
+
const spaceName = readStringLiteral(space);
|
|
62713
|
+
if (spaceName === null)
|
|
62714
|
+
throw new Error("ColorFromColorspace: space must be a string literal");
|
|
62715
|
+
const c = compile3(components);
|
|
62716
|
+
switch (spaceName) {
|
|
62717
|
+
case "oklch":
|
|
62718
|
+
return c;
|
|
62719
|
+
case "oklab":
|
|
62720
|
+
case "lab":
|
|
62721
|
+
return `_gpu_oklab_to_oklch(${c})`;
|
|
62722
|
+
case "rgb":
|
|
62723
|
+
return `_gpu_srgb_to_oklch(${c})`;
|
|
62724
|
+
case "hsl":
|
|
62725
|
+
return `_gpu_srgb_to_oklch(_gpu_hsl_to_rgb(${c}))`;
|
|
62726
|
+
case "hsv":
|
|
62727
|
+
return `_gpu_srgb_to_oklch(_gpu_hsv_to_rgb(${c}))`;
|
|
62728
|
+
default:
|
|
62729
|
+
throw new Error(
|
|
62730
|
+
`ColorFromColorspace: unsupported space "${spaceName}" on GPU target`
|
|
62731
|
+
);
|
|
62732
|
+
}
|
|
62733
|
+
},
|
|
62734
|
+
// ---------------------------------------------------------------------------
|
|
62735
|
+
// Color literals. Each typed head compiles to a canonical OKLCh vec3.
|
|
62736
|
+
// Alpha (4th argument) is dropped — GPU color values are vec3 only. Pass
|
|
62737
|
+
// alpha as a separate uniform if it's needed at the framebuffer boundary.
|
|
62738
|
+
// ---------------------------------------------------------------------------
|
|
62739
|
+
Color: ([s], _compile2, target) => {
|
|
62740
|
+
if (s === null) throw new Error("Color: no argument");
|
|
62741
|
+
const str = readStringLiteral(s);
|
|
62742
|
+
if (str === null)
|
|
62743
|
+
throw new Error("Color: argument must be a string literal on GPU target");
|
|
62744
|
+
const packed = parseColor(str);
|
|
62745
|
+
if (packed === 0 && str.trim().toLowerCase() !== "transparent")
|
|
62746
|
+
throw new Error(`Color: invalid color string "${str}"`);
|
|
62747
|
+
const r = packed >>> 24 & 255;
|
|
62748
|
+
const g = packed >>> 16 & 255;
|
|
62749
|
+
const b = packed >>> 8 & 255;
|
|
62750
|
+
const oklch2 = rgbToOklch({ r, g, b });
|
|
62751
|
+
return `${gpuVec3(target)}(${formatFloat(oklch2.L)}, ${formatFloat(oklch2.C)}, ${formatFloat(oklch2.H)})`;
|
|
62752
|
+
},
|
|
62753
|
+
Rgb: (args, compile3, target) => {
|
|
62754
|
+
if (args.length < 3) throw new Error("Rgb: need 3 components");
|
|
62755
|
+
const v3 = gpuVec3(target);
|
|
62756
|
+
return `_gpu_srgb_to_oklch(${v3}(${compile3(args[0])}, ${compile3(args[1])}, ${compile3(args[2])}))`;
|
|
62757
|
+
},
|
|
62758
|
+
Hsv: (args, compile3, target) => {
|
|
62759
|
+
if (args.length < 3) throw new Error("Hsv: need 3 components");
|
|
62760
|
+
const v3 = gpuVec3(target);
|
|
62761
|
+
return `_gpu_srgb_to_oklch(_gpu_hsv_to_rgb(${v3}(${compile3(args[0])}, ${compile3(args[1])}, ${compile3(args[2])})))`;
|
|
62762
|
+
},
|
|
62763
|
+
Hsl: (args, compile3, target) => {
|
|
62764
|
+
if (args.length < 3) throw new Error("Hsl: need 3 components");
|
|
62765
|
+
const v3 = gpuVec3(target);
|
|
62766
|
+
return `_gpu_srgb_to_oklch(_gpu_hsl_to_rgb(${v3}(${compile3(args[0])}, ${compile3(args[1])}, ${compile3(args[2])})))`;
|
|
62767
|
+
},
|
|
62768
|
+
Oklab: (args, compile3, target) => {
|
|
62769
|
+
if (args.length < 3) throw new Error("Oklab: need 3 components");
|
|
62770
|
+
const v3 = gpuVec3(target);
|
|
62771
|
+
return `_gpu_oklab_to_oklch(${v3}(${compile3(args[0])}, ${compile3(args[1])}, ${compile3(args[2])}))`;
|
|
62772
|
+
},
|
|
62773
|
+
Oklch: (args, compile3, target) => {
|
|
62774
|
+
if (args.length < 3) throw new Error("Oklch: need 3 components");
|
|
62775
|
+
const v3 = gpuVec3(target);
|
|
62776
|
+
return `${v3}(${compile3(args[0])}, ${compile3(args[1])}, ${compile3(args[2])})`;
|
|
62777
|
+
},
|
|
62778
|
+
// ---------------------------------------------------------------------------
|
|
62779
|
+
// As* operators. AsOklch is identity (canonical). The other As* return
|
|
62780
|
+
// components in the named space, equivalent to ColorToColorspace(c, 'x').
|
|
62781
|
+
// ---------------------------------------------------------------------------
|
|
62782
|
+
AsOklch: ([c], compile3) => {
|
|
62783
|
+
if (c === null) throw new Error("AsOklch: no argument");
|
|
62784
|
+
return compile3(c);
|
|
62785
|
+
},
|
|
62786
|
+
AsOklab: ([c], compile3) => {
|
|
62787
|
+
if (c === null) throw new Error("AsOklab: no argument");
|
|
62788
|
+
return `_gpu_oklch_to_oklab(${compile3(c)})`;
|
|
62789
|
+
},
|
|
62790
|
+
AsRgb: ([c], compile3) => {
|
|
62791
|
+
if (c === null) throw new Error("AsRgb: no argument");
|
|
62792
|
+
return `_gpu_oklch_to_srgb(${compile3(c)})`;
|
|
62793
|
+
},
|
|
62794
|
+
AsHsv: ([c], compile3) => {
|
|
62795
|
+
if (c === null) throw new Error("AsHsv: no argument");
|
|
62796
|
+
return `_gpu_rgb_to_hsv(_gpu_oklch_to_srgb(${compile3(c)}))`;
|
|
62797
|
+
},
|
|
62798
|
+
AsHsl: ([c], compile3) => {
|
|
62799
|
+
if (c === null) throw new Error("AsHsl: no argument");
|
|
62800
|
+
return `_gpu_rgb_to_hsl(_gpu_oklch_to_srgb(${compile3(c)}))`;
|
|
61883
62801
|
},
|
|
61884
62802
|
// Fractal functions
|
|
61885
62803
|
Mandelbrot: ([c, maxIter], compile3, target) => {
|
|
61886
62804
|
if (c === null || maxIter === null)
|
|
61887
62805
|
throw new Error("Mandelbrot: missing arguments");
|
|
61888
62806
|
const iterCode = compileIntArg(maxIter, compile3, target);
|
|
61889
|
-
const strategy = selectFractalStrategy(target);
|
|
61890
|
-
if (strategy === "double") {
|
|
61891
|
-
const dpCoord = target?.language === "wgsl" ? "_dp_coord(v_uv)" : "_dp_coord()";
|
|
61892
|
-
return `_fractal_mandelbrot_dp(${dpCoord}, ${iterCode})`;
|
|
61893
|
-
}
|
|
61894
|
-
if (strategy === "perturbation") {
|
|
61895
|
-
const ptDelta = target?.language === "wgsl" ? "_pt_delta(v_uv)" : "_pt_delta()";
|
|
61896
|
-
return `_fractal_mandelbrot_pt(${ptDelta}, ${iterCode})`;
|
|
61897
|
-
}
|
|
61898
62807
|
return `_fractal_mandelbrot(${compile3(c)}, ${iterCode})`;
|
|
61899
62808
|
},
|
|
61900
62809
|
Julia: ([z, c, maxIter], compile3, target) => {
|
|
61901
62810
|
if (z === null || c === null || maxIter === null)
|
|
61902
62811
|
throw new Error("Julia: missing arguments");
|
|
61903
62812
|
const iterCode = compileIntArg(maxIter, compile3, target);
|
|
61904
|
-
const strategy = selectFractalStrategy(target);
|
|
61905
|
-
if (strategy === "double") {
|
|
61906
|
-
const dpCoord = target?.language === "wgsl" ? "_dp_coord(v_uv)" : "_dp_coord()";
|
|
61907
|
-
const cCode = compile3(c);
|
|
61908
|
-
return `_fractal_julia_dp(${dpCoord}, vec4(${cCode}, vec2(0.0)), ${iterCode})`;
|
|
61909
|
-
}
|
|
61910
|
-
if (strategy === "perturbation") {
|
|
61911
|
-
const ptDelta = target?.language === "wgsl" ? "_pt_delta(v_uv)" : "_pt_delta()";
|
|
61912
|
-
const cCode = compile3(c);
|
|
61913
|
-
return `_fractal_julia_pt(${ptDelta}, ${cCode}, ${iterCode})`;
|
|
61914
|
-
}
|
|
61915
62813
|
return `_fractal_julia(${compile3(z)}, ${compile3(c)}, ${iterCode})`;
|
|
61916
62814
|
},
|
|
61917
62815
|
// Vector/Matrix operations
|
|
@@ -62509,232 +63407,6 @@ fn _gpu_besselJ(n_in: i32, x_in: f32) -> f32 {
|
|
|
62509
63407
|
return sgn * vals[n] / norm;
|
|
62510
63408
|
}
|
|
62511
63409
|
`;
|
|
62512
|
-
var GPU_DS_ARITHMETIC_PREAMBLE_GLSL = `
|
|
62513
|
-
// Split a float into high and low parts for exact multiplication
|
|
62514
|
-
vec2 ds_split(float a) {
|
|
62515
|
-
const float SPLIT = 4097.0; // 2^12 + 1
|
|
62516
|
-
float t = SPLIT * a;
|
|
62517
|
-
float hi = t - (t - a);
|
|
62518
|
-
float lo = a - hi;
|
|
62519
|
-
return vec2(hi, lo);
|
|
62520
|
-
}
|
|
62521
|
-
|
|
62522
|
-
// Create a double-single from a single float
|
|
62523
|
-
vec2 ds_from(float a) {
|
|
62524
|
-
return vec2(a, 0.0);
|
|
62525
|
-
}
|
|
62526
|
-
|
|
62527
|
-
// Error-free addition (Knuth TwoSum)
|
|
62528
|
-
vec2 ds_add(vec2 a, vec2 b) {
|
|
62529
|
-
float s = a.x + b.x;
|
|
62530
|
-
float v = s - a.x;
|
|
62531
|
-
float e = (a.x - (s - v)) + (b.x - v);
|
|
62532
|
-
float lo = (a.y + b.y) + e;
|
|
62533
|
-
float hi = s + lo;
|
|
62534
|
-
lo = lo - (hi - s);
|
|
62535
|
-
return vec2(hi, lo);
|
|
62536
|
-
}
|
|
62537
|
-
|
|
62538
|
-
// Double-single subtraction
|
|
62539
|
-
vec2 ds_sub(vec2 a, vec2 b) {
|
|
62540
|
-
return ds_add(a, vec2(-b.x, -b.y));
|
|
62541
|
-
}
|
|
62542
|
-
|
|
62543
|
-
// Error-free multiplication (Dekker TwoProduct)
|
|
62544
|
-
vec2 ds_mul(vec2 a, vec2 b) {
|
|
62545
|
-
float p = a.x * b.x;
|
|
62546
|
-
vec2 sa = ds_split(a.x);
|
|
62547
|
-
vec2 sb = ds_split(b.x);
|
|
62548
|
-
float err = ((sa.x * sb.x - p) + sa.x * sb.y + sa.y * sb.x) + sa.y * sb.y;
|
|
62549
|
-
err += a.x * b.y + a.y * b.x;
|
|
62550
|
-
float hi = p + err;
|
|
62551
|
-
float lo = err - (hi - p);
|
|
62552
|
-
return vec2(hi, lo);
|
|
62553
|
-
}
|
|
62554
|
-
|
|
62555
|
-
// Optimized self-multiply
|
|
62556
|
-
vec2 ds_sqr(vec2 a) {
|
|
62557
|
-
float p = a.x * a.x;
|
|
62558
|
-
vec2 sa = ds_split(a.x);
|
|
62559
|
-
float err = ((sa.x * sa.x - p) + 2.0 * sa.x * sa.y) + sa.y * sa.y;
|
|
62560
|
-
err += 2.0 * a.x * a.y;
|
|
62561
|
-
float hi = p + err;
|
|
62562
|
-
float lo = err - (hi - p);
|
|
62563
|
-
return vec2(hi, lo);
|
|
62564
|
-
}
|
|
62565
|
-
|
|
62566
|
-
// Compare magnitude: returns -1, 0, or 1
|
|
62567
|
-
float ds_cmp(vec2 a, vec2 b) {
|
|
62568
|
-
float d = a.x - b.x;
|
|
62569
|
-
if (d != 0.0) return sign(d);
|
|
62570
|
-
return sign(a.y - b.y);
|
|
62571
|
-
}
|
|
62572
|
-
`;
|
|
62573
|
-
var GPU_DS_ARITHMETIC_PREAMBLE_WGSL = `
|
|
62574
|
-
fn ds_split(a: f32) -> vec2f {
|
|
62575
|
-
const SPLIT: f32 = 4097.0;
|
|
62576
|
-
let t = SPLIT * a;
|
|
62577
|
-
let hi = t - (t - a);
|
|
62578
|
-
let lo = a - hi;
|
|
62579
|
-
return vec2f(hi, lo);
|
|
62580
|
-
}
|
|
62581
|
-
|
|
62582
|
-
fn ds_from(a: f32) -> vec2f {
|
|
62583
|
-
return vec2f(a, 0.0);
|
|
62584
|
-
}
|
|
62585
|
-
|
|
62586
|
-
fn ds_add(a: vec2f, b: vec2f) -> vec2f {
|
|
62587
|
-
let s = a.x + b.x;
|
|
62588
|
-
let v = s - a.x;
|
|
62589
|
-
let e = (a.x - (s - v)) + (b.x - v);
|
|
62590
|
-
let lo_t = (a.y + b.y) + e;
|
|
62591
|
-
let hi = s + lo_t;
|
|
62592
|
-
let lo = lo_t - (hi - s);
|
|
62593
|
-
return vec2f(hi, lo);
|
|
62594
|
-
}
|
|
62595
|
-
|
|
62596
|
-
fn ds_sub(a: vec2f, b: vec2f) -> vec2f {
|
|
62597
|
-
return ds_add(a, vec2f(-b.x, -b.y));
|
|
62598
|
-
}
|
|
62599
|
-
|
|
62600
|
-
fn ds_mul(a: vec2f, b: vec2f) -> vec2f {
|
|
62601
|
-
let p = a.x * b.x;
|
|
62602
|
-
let sa = ds_split(a.x);
|
|
62603
|
-
let sb = ds_split(b.x);
|
|
62604
|
-
var err = ((sa.x * sb.x - p) + sa.x * sb.y + sa.y * sb.x) + sa.y * sb.y;
|
|
62605
|
-
err += a.x * b.y + a.y * b.x;
|
|
62606
|
-
let hi = p + err;
|
|
62607
|
-
let lo = err - (hi - p);
|
|
62608
|
-
return vec2f(hi, lo);
|
|
62609
|
-
}
|
|
62610
|
-
|
|
62611
|
-
fn ds_sqr(a: vec2f) -> vec2f {
|
|
62612
|
-
let p = a.x * a.x;
|
|
62613
|
-
let sa = ds_split(a.x);
|
|
62614
|
-
var err = ((sa.x * sa.x - p) + 2.0 * sa.x * sa.y) + sa.y * sa.y;
|
|
62615
|
-
err += 2.0 * a.x * a.y;
|
|
62616
|
-
let hi = p + err;
|
|
62617
|
-
let lo = err - (hi - p);
|
|
62618
|
-
return vec2f(hi, lo);
|
|
62619
|
-
}
|
|
62620
|
-
|
|
62621
|
-
fn ds_cmp(a: vec2f, b: vec2f) -> f32 {
|
|
62622
|
-
let d = a.x - b.x;
|
|
62623
|
-
if (d != 0.0) { return sign(d); }
|
|
62624
|
-
return sign(a.y - b.y);
|
|
62625
|
-
}
|
|
62626
|
-
`;
|
|
62627
|
-
var GPU_FRACTAL_DP_PREAMBLE_GLSL = `
|
|
62628
|
-
uniform float _dp_cx_hi;
|
|
62629
|
-
uniform float _dp_cx_lo;
|
|
62630
|
-
uniform float _dp_cy_hi;
|
|
62631
|
-
uniform float _dp_cy_lo;
|
|
62632
|
-
uniform float _dp_w;
|
|
62633
|
-
uniform float _dp_h;
|
|
62634
|
-
|
|
62635
|
-
vec4 _dp_coord() {
|
|
62636
|
-
// Per-pixel offset from center \u2014 small, so float-precise
|
|
62637
|
-
float dx = (v_uv.x - 0.5) * _dp_w;
|
|
62638
|
-
float dy = (v_uv.y - 0.5) * _dp_h;
|
|
62639
|
-
// Combine center (hi+lo) + delta with emulated double precision
|
|
62640
|
-
vec2 cre = ds_add(vec2(_dp_cx_hi, _dp_cx_lo), ds_from(dx));
|
|
62641
|
-
vec2 cim = ds_add(vec2(_dp_cy_hi, _dp_cy_lo), ds_from(dy));
|
|
62642
|
-
return vec4(cre.x, cim.x, cre.y, cim.y);
|
|
62643
|
-
}
|
|
62644
|
-
|
|
62645
|
-
float _fractal_mandelbrot_dp(vec4 c, int maxIter) {
|
|
62646
|
-
// c = (re_hi, im_hi, re_lo, im_lo)
|
|
62647
|
-
vec2 cr = vec2(c.x, c.z); // real part as ds
|
|
62648
|
-
vec2 ci = vec2(c.y, c.w); // imag part as ds
|
|
62649
|
-
vec2 zr = vec2(0.0, 0.0);
|
|
62650
|
-
vec2 zi = vec2(0.0, 0.0);
|
|
62651
|
-
for (int i = 0; i < maxIter; i++) {
|
|
62652
|
-
vec2 zr2 = ds_sqr(zr);
|
|
62653
|
-
vec2 zi2 = ds_sqr(zi);
|
|
62654
|
-
// |z|^2 > 4.0 ?
|
|
62655
|
-
vec2 mag2 = ds_add(zr2, zi2);
|
|
62656
|
-
if (mag2.x > 4.0)
|
|
62657
|
-
return clamp((float(i) - log2(log2(mag2.x)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
62658
|
-
// z = z^2 + c
|
|
62659
|
-
vec2 new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci); // 2*zr*zi + ci
|
|
62660
|
-
zr = ds_add(ds_sub(zr2, zi2), cr); // zr^2 - zi^2 + cr
|
|
62661
|
-
zi = new_zi;
|
|
62662
|
-
}
|
|
62663
|
-
return 1.0;
|
|
62664
|
-
}
|
|
62665
|
-
|
|
62666
|
-
float _fractal_julia_dp(vec4 z_in, vec4 c, int maxIter) {
|
|
62667
|
-
vec2 zr = vec2(z_in.x, z_in.z);
|
|
62668
|
-
vec2 zi = vec2(z_in.y, z_in.w);
|
|
62669
|
-
vec2 cr = vec2(c.x, c.z);
|
|
62670
|
-
vec2 ci = vec2(c.y, c.w);
|
|
62671
|
-
for (int i = 0; i < maxIter; i++) {
|
|
62672
|
-
vec2 zr2 = ds_sqr(zr);
|
|
62673
|
-
vec2 zi2 = ds_sqr(zi);
|
|
62674
|
-
vec2 mag2 = ds_add(zr2, zi2);
|
|
62675
|
-
if (mag2.x > 4.0)
|
|
62676
|
-
return clamp((float(i) - log2(log2(mag2.x)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
62677
|
-
vec2 new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
|
|
62678
|
-
zr = ds_add(ds_sub(zr2, zi2), cr);
|
|
62679
|
-
zi = new_zi;
|
|
62680
|
-
}
|
|
62681
|
-
return 1.0;
|
|
62682
|
-
}
|
|
62683
|
-
`;
|
|
62684
|
-
var GPU_FRACTAL_DP_PREAMBLE_WGSL = `
|
|
62685
|
-
@group(0) @binding(10) var<uniform> _dp_cx_hi: f32;
|
|
62686
|
-
@group(0) @binding(11) var<uniform> _dp_cx_lo: f32;
|
|
62687
|
-
@group(0) @binding(12) var<uniform> _dp_cy_hi: f32;
|
|
62688
|
-
@group(0) @binding(13) var<uniform> _dp_cy_lo: f32;
|
|
62689
|
-
@group(0) @binding(14) var<uniform> _dp_w: f32;
|
|
62690
|
-
@group(0) @binding(15) var<uniform> _dp_h: f32;
|
|
62691
|
-
|
|
62692
|
-
fn _dp_coord(uv: vec2f) -> vec4f {
|
|
62693
|
-
let dx = (uv.x - 0.5) * _dp_w;
|
|
62694
|
-
let dy = (uv.y - 0.5) * _dp_h;
|
|
62695
|
-
let cre = ds_add(vec2f(_dp_cx_hi, _dp_cx_lo), ds_from(dx));
|
|
62696
|
-
let cim = ds_add(vec2f(_dp_cy_hi, _dp_cy_lo), ds_from(dy));
|
|
62697
|
-
return vec4f(cre.x, cim.x, cre.y, cim.y);
|
|
62698
|
-
}
|
|
62699
|
-
|
|
62700
|
-
fn _fractal_mandelbrot_dp(c: vec4f, maxIter: i32) -> f32 {
|
|
62701
|
-
let cr = vec2f(c.x, c.z);
|
|
62702
|
-
let ci = vec2f(c.y, c.w);
|
|
62703
|
-
var zr = vec2f(0.0, 0.0);
|
|
62704
|
-
var zi = vec2f(0.0, 0.0);
|
|
62705
|
-
for (var i: i32 = 0; i < maxIter; i++) {
|
|
62706
|
-
let zr2 = ds_sqr(zr);
|
|
62707
|
-
let zi2 = ds_sqr(zi);
|
|
62708
|
-
let mag2 = ds_add(zr2, zi2);
|
|
62709
|
-
if (mag2.x > 4.0) {
|
|
62710
|
-
return clamp((f32(i) - log2(log2(mag2.x)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
62711
|
-
}
|
|
62712
|
-
let new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
|
|
62713
|
-
zr = ds_add(ds_sub(zr2, zi2), cr);
|
|
62714
|
-
zi = new_zi;
|
|
62715
|
-
}
|
|
62716
|
-
return 1.0;
|
|
62717
|
-
}
|
|
62718
|
-
|
|
62719
|
-
fn _fractal_julia_dp(z_in: vec4f, c: vec4f, maxIter: i32) -> f32 {
|
|
62720
|
-
var zr = vec2f(z_in.x, z_in.z);
|
|
62721
|
-
var zi = vec2f(z_in.y, z_in.w);
|
|
62722
|
-
let cr = vec2f(c.x, c.z);
|
|
62723
|
-
let ci = vec2f(c.y, c.w);
|
|
62724
|
-
for (var i: i32 = 0; i < maxIter; i++) {
|
|
62725
|
-
let zr2 = ds_sqr(zr);
|
|
62726
|
-
let zi2 = ds_sqr(zi);
|
|
62727
|
-
let mag2 = ds_add(zr2, zi2);
|
|
62728
|
-
if (mag2.x > 4.0) {
|
|
62729
|
-
return clamp((f32(i) - log2(log2(mag2.x)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
62730
|
-
}
|
|
62731
|
-
let new_zi = ds_add(ds_mul(ds_add(zr, zr), zi), ci);
|
|
62732
|
-
zr = ds_add(ds_sub(zr2, zi2), cr);
|
|
62733
|
-
zi = new_zi;
|
|
62734
|
-
}
|
|
62735
|
-
return 1.0;
|
|
62736
|
-
}
|
|
62737
|
-
`;
|
|
62738
63410
|
var GPU_FRACTAL_PREAMBLE_GLSL = `
|
|
62739
63411
|
float _fractal_mandelbrot(vec2 c, int maxIter) {
|
|
62740
63412
|
vec2 z = vec2(0.0, 0.0);
|
|
@@ -62778,208 +63450,6 @@ fn _fractal_julia(z_in: vec2f, c: vec2f, maxIter: i32) -> f32 {
|
|
|
62778
63450
|
return 1.0;
|
|
62779
63451
|
}
|
|
62780
63452
|
`;
|
|
62781
|
-
var GPU_FRACTAL_PT_PREAMBLE_GLSL = `
|
|
62782
|
-
uniform sampler2D _refOrbit;
|
|
62783
|
-
uniform int _refOrbitLen;
|
|
62784
|
-
uniform int _refOrbitTexWidth;
|
|
62785
|
-
uniform float _pt_offset_x;
|
|
62786
|
-
uniform float _pt_offset_y;
|
|
62787
|
-
uniform float _pt_w;
|
|
62788
|
-
uniform float _pt_h;
|
|
62789
|
-
|
|
62790
|
-
vec2 _pt_delta() {
|
|
62791
|
-
float dx = _pt_offset_x + (v_uv.x - 0.5) * _pt_w;
|
|
62792
|
-
float dy = _pt_offset_y + (v_uv.y - 0.5) * _pt_h;
|
|
62793
|
-
return vec2(dx, dy);
|
|
62794
|
-
}
|
|
62795
|
-
|
|
62796
|
-
vec2 _pt_fetch_orbit(int i) {
|
|
62797
|
-
int y = i / _refOrbitTexWidth;
|
|
62798
|
-
int x = i - y * _refOrbitTexWidth;
|
|
62799
|
-
return texelFetch(_refOrbit, ivec2(x, y), 0).rg;
|
|
62800
|
-
}
|
|
62801
|
-
|
|
62802
|
-
float _fractal_mandelbrot_pt(vec2 delta_c, int maxIter) {
|
|
62803
|
-
float dr = 0.0;
|
|
62804
|
-
float di = 0.0;
|
|
62805
|
-
int orbitLen = min(maxIter, _refOrbitLen);
|
|
62806
|
-
for (int i = 0; i < orbitLen; i++) {
|
|
62807
|
-
vec2 Zn = _pt_fetch_orbit(i);
|
|
62808
|
-
// delta_{n+1} = 2*Z_n*delta_n + delta_n^2 + delta_c
|
|
62809
|
-
float new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
62810
|
-
float new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
62811
|
-
dr = new_dr;
|
|
62812
|
-
di = new_di;
|
|
62813
|
-
// Full z = Z_{n+1} + delta for escape check
|
|
62814
|
-
vec2 Zn1 = (i + 1 < orbitLen) ? _pt_fetch_orbit(i + 1) : vec2(0.0);
|
|
62815
|
-
float zr = Zn1.x + dr;
|
|
62816
|
-
float zi = Zn1.y + di;
|
|
62817
|
-
float mag2 = zr * zr + zi * zi;
|
|
62818
|
-
if (mag2 > 4.0)
|
|
62819
|
-
return clamp((float(i) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
62820
|
-
// Glitch detection: |delta|^2 > |Z|^2
|
|
62821
|
-
float dmag2 = dr * dr + di * di;
|
|
62822
|
-
float Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
62823
|
-
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
62824
|
-
// Rebase to absolute coordinates and continue with single-float
|
|
62825
|
-
float abs_zr = Zn1.x + dr;
|
|
62826
|
-
float abs_zi = Zn1.y + di;
|
|
62827
|
-
// Reconstruct absolute c from reference + delta
|
|
62828
|
-
// (Use ds_from for the concept, but single-float suffices for fallback)
|
|
62829
|
-
float cx = abs_zr - dr + delta_c.x;
|
|
62830
|
-
float cy = abs_zi - di + delta_c.y;
|
|
62831
|
-
for (int j = i + 1; j < maxIter; j++) {
|
|
62832
|
-
float new_zr = abs_zr * abs_zr - abs_zi * abs_zi + cx;
|
|
62833
|
-
abs_zi = 2.0 * abs_zr * abs_zi + cy;
|
|
62834
|
-
abs_zr = new_zr;
|
|
62835
|
-
mag2 = abs_zr * abs_zr + abs_zi * abs_zi;
|
|
62836
|
-
if (mag2 > 4.0)
|
|
62837
|
-
return clamp((float(j) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
62838
|
-
}
|
|
62839
|
-
return 1.0;
|
|
62840
|
-
}
|
|
62841
|
-
}
|
|
62842
|
-
return 1.0;
|
|
62843
|
-
}
|
|
62844
|
-
|
|
62845
|
-
float _fractal_julia_pt(vec2 z_delta, vec2 delta_c, int maxIter) {
|
|
62846
|
-
float dr = z_delta.x;
|
|
62847
|
-
float di = z_delta.y;
|
|
62848
|
-
int orbitLen = min(maxIter, _refOrbitLen);
|
|
62849
|
-
for (int i = 0; i < orbitLen; i++) {
|
|
62850
|
-
vec2 Zn = _pt_fetch_orbit(i);
|
|
62851
|
-
float new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
62852
|
-
float new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
62853
|
-
dr = new_dr;
|
|
62854
|
-
di = new_di;
|
|
62855
|
-
vec2 Zn1 = (i + 1 < orbitLen) ? _pt_fetch_orbit(i + 1) : vec2(0.0);
|
|
62856
|
-
float zr = Zn1.x + dr;
|
|
62857
|
-
float zi = Zn1.y + di;
|
|
62858
|
-
float mag2 = zr * zr + zi * zi;
|
|
62859
|
-
if (mag2 > 4.0)
|
|
62860
|
-
return clamp((float(i) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
62861
|
-
float dmag2 = dr * dr + di * di;
|
|
62862
|
-
float Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
62863
|
-
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
62864
|
-
float abs_zr = Zn1.x + dr;
|
|
62865
|
-
float abs_zi = Zn1.y + di;
|
|
62866
|
-
float cx = delta_c.x;
|
|
62867
|
-
float cy = delta_c.y;
|
|
62868
|
-
for (int j = i + 1; j < maxIter; j++) {
|
|
62869
|
-
float new_zr = abs_zr * abs_zr - abs_zi * abs_zi + cx;
|
|
62870
|
-
abs_zi = 2.0 * abs_zr * abs_zi + cy;
|
|
62871
|
-
abs_zr = new_zr;
|
|
62872
|
-
mag2 = abs_zr * abs_zr + abs_zi * abs_zi;
|
|
62873
|
-
if (mag2 > 4.0)
|
|
62874
|
-
return clamp((float(j) - log2(log2(mag2)) + 4.0) / float(maxIter), 0.0, 1.0);
|
|
62875
|
-
}
|
|
62876
|
-
return 1.0;
|
|
62877
|
-
}
|
|
62878
|
-
}
|
|
62879
|
-
return 1.0;
|
|
62880
|
-
}
|
|
62881
|
-
`;
|
|
62882
|
-
var GPU_FRACTAL_PT_PREAMBLE_WGSL = `
|
|
62883
|
-
@group(0) @binding(1) var _refOrbit: texture_2d<f32>;
|
|
62884
|
-
var<uniform> _refOrbitLen: i32;
|
|
62885
|
-
var<uniform> _refOrbitTexWidth: i32;
|
|
62886
|
-
var<uniform> _pt_offset_x: f32;
|
|
62887
|
-
var<uniform> _pt_offset_y: f32;
|
|
62888
|
-
var<uniform> _pt_w: f32;
|
|
62889
|
-
var<uniform> _pt_h: f32;
|
|
62890
|
-
|
|
62891
|
-
fn _pt_delta(uv: vec2f) -> vec2f {
|
|
62892
|
-
let dx = _pt_offset_x + (uv.x - 0.5) * _pt_w;
|
|
62893
|
-
let dy = _pt_offset_y + (uv.y - 0.5) * _pt_h;
|
|
62894
|
-
return vec2f(dx, dy);
|
|
62895
|
-
}
|
|
62896
|
-
|
|
62897
|
-
fn _pt_fetch_orbit(i: i32) -> vec2f {
|
|
62898
|
-
let y = i / _refOrbitTexWidth;
|
|
62899
|
-
let x = i - y * _refOrbitTexWidth;
|
|
62900
|
-
return textureLoad(_refOrbit, vec2i(x, y), 0).rg;
|
|
62901
|
-
}
|
|
62902
|
-
|
|
62903
|
-
fn _fractal_mandelbrot_pt(delta_c: vec2f, maxIter: i32) -> f32 {
|
|
62904
|
-
var dr: f32 = 0.0;
|
|
62905
|
-
var di: f32 = 0.0;
|
|
62906
|
-
let orbitLen = min(maxIter, _refOrbitLen);
|
|
62907
|
-
for (var i: i32 = 0; i < orbitLen; i++) {
|
|
62908
|
-
let Zn = _pt_fetch_orbit(i);
|
|
62909
|
-
let new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
62910
|
-
let new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
62911
|
-
dr = new_dr;
|
|
62912
|
-
di = new_di;
|
|
62913
|
-
var Zn1 = vec2f(0.0);
|
|
62914
|
-
if (i + 1 < orbitLen) { Zn1 = _pt_fetch_orbit(i + 1); }
|
|
62915
|
-
let zr = Zn1.x + dr;
|
|
62916
|
-
let zi = Zn1.y + di;
|
|
62917
|
-
var mag2 = zr * zr + zi * zi;
|
|
62918
|
-
if (mag2 > 4.0) {
|
|
62919
|
-
return clamp((f32(i) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
62920
|
-
}
|
|
62921
|
-
let dmag2 = dr * dr + di * di;
|
|
62922
|
-
let Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
62923
|
-
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
62924
|
-
var f_zr = Zn1.x + dr;
|
|
62925
|
-
var f_zi = Zn1.y + di;
|
|
62926
|
-
let cx = delta_c.x;
|
|
62927
|
-
let cy = delta_c.y;
|
|
62928
|
-
for (var j: i32 = i + 1; j < maxIter; j++) {
|
|
62929
|
-
let t_zr = f_zr * f_zr - f_zi * f_zi + cx;
|
|
62930
|
-
f_zi = 2.0 * f_zr * f_zi + cy;
|
|
62931
|
-
f_zr = t_zr;
|
|
62932
|
-
mag2 = f_zr * f_zr + f_zi * f_zi;
|
|
62933
|
-
if (mag2 > 4.0) {
|
|
62934
|
-
return clamp((f32(j) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
62935
|
-
}
|
|
62936
|
-
}
|
|
62937
|
-
return 1.0;
|
|
62938
|
-
}
|
|
62939
|
-
}
|
|
62940
|
-
return 1.0;
|
|
62941
|
-
}
|
|
62942
|
-
|
|
62943
|
-
fn _fractal_julia_pt(z_delta: vec2f, delta_c: vec2f, maxIter: i32) -> f32 {
|
|
62944
|
-
var dr = z_delta.x;
|
|
62945
|
-
var di = z_delta.y;
|
|
62946
|
-
let orbitLen = min(maxIter, _refOrbitLen);
|
|
62947
|
-
for (var i: i32 = 0; i < orbitLen; i++) {
|
|
62948
|
-
let Zn = _pt_fetch_orbit(i);
|
|
62949
|
-
let new_dr = 2.0 * (Zn.x * dr - Zn.y * di) + dr * dr - di * di + delta_c.x;
|
|
62950
|
-
let new_di = 2.0 * (Zn.x * di + Zn.y * dr) + 2.0 * dr * di + delta_c.y;
|
|
62951
|
-
dr = new_dr;
|
|
62952
|
-
di = new_di;
|
|
62953
|
-
var Zn1 = vec2f(0.0);
|
|
62954
|
-
if (i + 1 < orbitLen) { Zn1 = _pt_fetch_orbit(i + 1); }
|
|
62955
|
-
let zr = Zn1.x + dr;
|
|
62956
|
-
let zi = Zn1.y + di;
|
|
62957
|
-
var mag2 = zr * zr + zi * zi;
|
|
62958
|
-
if (mag2 > 4.0) {
|
|
62959
|
-
return clamp((f32(i) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
62960
|
-
}
|
|
62961
|
-
let dmag2 = dr * dr + di * di;
|
|
62962
|
-
let Zmag2 = Zn.x * Zn.x + Zn.y * Zn.y;
|
|
62963
|
-
if (dmag2 > Zmag2 && Zmag2 > 0.0) {
|
|
62964
|
-
var f_zr = Zn1.x + dr;
|
|
62965
|
-
var f_zi = Zn1.y + di;
|
|
62966
|
-
let cx = delta_c.x;
|
|
62967
|
-
let cy = delta_c.y;
|
|
62968
|
-
for (var j: i32 = i + 1; j < maxIter; j++) {
|
|
62969
|
-
let t_zr = f_zr * f_zr - f_zi * f_zi + cx;
|
|
62970
|
-
f_zi = 2.0 * f_zr * f_zi + cy;
|
|
62971
|
-
f_zr = t_zr;
|
|
62972
|
-
mag2 = f_zr * f_zr + f_zi * f_zi;
|
|
62973
|
-
if (mag2 > 4.0) {
|
|
62974
|
-
return clamp((f32(j) - log2(log2(mag2)) + 4.0) / f32(maxIter), 0.0, 1.0);
|
|
62975
|
-
}
|
|
62976
|
-
}
|
|
62977
|
-
return 1.0;
|
|
62978
|
-
}
|
|
62979
|
-
}
|
|
62980
|
-
return 1.0;
|
|
62981
|
-
}
|
|
62982
|
-
`;
|
|
62983
63453
|
var GPU_COLOR_PREAMBLE_GLSL = `
|
|
62984
63454
|
float _gpu_srgb_to_linear(float c) {
|
|
62985
63455
|
if (c <= 0.04045) return c / 12.92;
|
|
@@ -63020,28 +63490,124 @@ vec3 _gpu_oklab_to_srgb(vec3 lab) {
|
|
|
63020
63490
|
|
|
63021
63491
|
vec3 _gpu_oklab_to_oklch(vec3 lab) {
|
|
63022
63492
|
float C = length(lab.yz);
|
|
63023
|
-
float H = atan(lab.z, lab.y);
|
|
63493
|
+
float H = atan(lab.z, lab.y) * (180.0 / 3.14159265359);
|
|
63494
|
+
if (H < 0.0) H += 360.0;
|
|
63024
63495
|
return vec3(lab.x, C, H);
|
|
63025
63496
|
}
|
|
63026
63497
|
|
|
63027
63498
|
vec3 _gpu_oklch_to_oklab(vec3 lch) {
|
|
63028
|
-
|
|
63499
|
+
float h_rad = lch.z * (3.14159265359 / 180.0);
|
|
63500
|
+
return vec3(lch.x, lch.y * cos(h_rad), lch.y * sin(h_rad));
|
|
63501
|
+
}
|
|
63502
|
+
|
|
63503
|
+
vec3 _gpu_srgb_to_oklch(vec3 rgb) {
|
|
63504
|
+
return _gpu_oklab_to_oklch(_gpu_srgb_to_oklab(rgb));
|
|
63505
|
+
}
|
|
63506
|
+
|
|
63507
|
+
vec3 _gpu_oklch_to_srgb(vec3 lch) {
|
|
63508
|
+
return _gpu_oklab_to_srgb(_gpu_oklch_to_oklab(lch));
|
|
63509
|
+
}
|
|
63510
|
+
|
|
63511
|
+
// HSL conversion. Hue in degrees, saturation/lightness in 0-1.
|
|
63512
|
+
vec3 _gpu_hsl_to_rgb(vec3 hsl) {
|
|
63513
|
+
float h = hsl.x;
|
|
63514
|
+
float s = hsl.y;
|
|
63515
|
+
float l = hsl.z;
|
|
63516
|
+
float c = (1.0 - abs(2.0 * l - 1.0)) * s;
|
|
63517
|
+
float h6 = h / 60.0;
|
|
63518
|
+
float x = c * (1.0 - abs(mod(h6, 2.0) - 1.0));
|
|
63519
|
+
float r = 0.0;
|
|
63520
|
+
float g = 0.0;
|
|
63521
|
+
float b = 0.0;
|
|
63522
|
+
if (h6 < 1.0) { r = c; g = x; b = 0.0; }
|
|
63523
|
+
else if (h6 < 2.0) { r = x; g = c; b = 0.0; }
|
|
63524
|
+
else if (h6 < 3.0) { r = 0.0; g = c; b = x; }
|
|
63525
|
+
else if (h6 < 4.0) { r = 0.0; g = x; b = c; }
|
|
63526
|
+
else if (h6 < 5.0) { r = x; g = 0.0; b = c; }
|
|
63527
|
+
else { r = c; g = 0.0; b = x; }
|
|
63528
|
+
float m = l - c / 2.0;
|
|
63529
|
+
return vec3(r + m, g + m, b + m);
|
|
63530
|
+
}
|
|
63531
|
+
|
|
63532
|
+
vec3 _gpu_rgb_to_hsl(vec3 rgb) {
|
|
63533
|
+
float maxc = max(max(rgb.x, rgb.y), rgb.z);
|
|
63534
|
+
float minc = min(min(rgb.x, rgb.y), rgb.z);
|
|
63535
|
+
float l = (maxc + minc) / 2.0;
|
|
63536
|
+
float d = maxc - minc;
|
|
63537
|
+
if (d < 1e-6) return vec3(0.0, 0.0, l);
|
|
63538
|
+
float s = d / (1.0 - abs(2.0 * l - 1.0));
|
|
63539
|
+
float h;
|
|
63540
|
+
if (maxc == rgb.x) h = mod((rgb.y - rgb.z) / d, 6.0);
|
|
63541
|
+
else if (maxc == rgb.y) h = (rgb.z - rgb.x) / d + 2.0;
|
|
63542
|
+
else h = (rgb.x - rgb.y) / d + 4.0;
|
|
63543
|
+
h *= 60.0;
|
|
63544
|
+
if (h < 0.0) h += 360.0;
|
|
63545
|
+
return vec3(h, s, l);
|
|
63546
|
+
}
|
|
63547
|
+
|
|
63548
|
+
// HSV conversion. Hue in degrees, saturation/value in 0-1.
|
|
63549
|
+
vec3 _gpu_hsv_to_rgb(vec3 hsv) {
|
|
63550
|
+
float h = hsv.x;
|
|
63551
|
+
float s = hsv.y;
|
|
63552
|
+
float v = hsv.z;
|
|
63553
|
+
float c = v * s;
|
|
63554
|
+
float h6 = h / 60.0;
|
|
63555
|
+
float x = c * (1.0 - abs(mod(h6, 2.0) - 1.0));
|
|
63556
|
+
float r = 0.0;
|
|
63557
|
+
float g = 0.0;
|
|
63558
|
+
float b = 0.0;
|
|
63559
|
+
if (h6 < 1.0) { r = c; g = x; b = 0.0; }
|
|
63560
|
+
else if (h6 < 2.0) { r = x; g = c; b = 0.0; }
|
|
63561
|
+
else if (h6 < 3.0) { r = 0.0; g = c; b = x; }
|
|
63562
|
+
else if (h6 < 4.0) { r = 0.0; g = x; b = c; }
|
|
63563
|
+
else if (h6 < 5.0) { r = x; g = 0.0; b = c; }
|
|
63564
|
+
else { r = c; g = 0.0; b = x; }
|
|
63565
|
+
float m = v - c;
|
|
63566
|
+
return vec3(r + m, g + m, b + m);
|
|
63567
|
+
}
|
|
63568
|
+
|
|
63569
|
+
vec3 _gpu_rgb_to_hsv(vec3 rgb) {
|
|
63570
|
+
float maxc = max(max(rgb.x, rgb.y), rgb.z);
|
|
63571
|
+
float minc = min(min(rgb.x, rgb.y), rgb.z);
|
|
63572
|
+
float v = maxc;
|
|
63573
|
+
float d = maxc - minc;
|
|
63574
|
+
if (d < 1e-6) return vec3(0.0, 0.0, v);
|
|
63575
|
+
float s = (maxc < 1e-6) ? 0.0 : d / maxc;
|
|
63576
|
+
float h;
|
|
63577
|
+
if (maxc == rgb.x) h = mod((rgb.y - rgb.z) / d, 6.0);
|
|
63578
|
+
else if (maxc == rgb.y) h = (rgb.z - rgb.x) / d + 2.0;
|
|
63579
|
+
else h = (rgb.x - rgb.y) / d + 4.0;
|
|
63580
|
+
h *= 60.0;
|
|
63581
|
+
if (h < 0.0) h += 360.0;
|
|
63582
|
+
return vec3(h, s, v);
|
|
63029
63583
|
}
|
|
63030
63584
|
|
|
63031
|
-
vec3 _gpu_color_mix(vec3
|
|
63032
|
-
vec3 lch1 = _gpu_oklab_to_oklch(_gpu_srgb_to_oklab(rgb1));
|
|
63033
|
-
vec3 lch2 = _gpu_oklab_to_oklch(_gpu_srgb_to_oklab(rgb2));
|
|
63585
|
+
vec3 _gpu_color_mix(vec3 lch1, vec3 lch2, float t) {
|
|
63034
63586
|
float L = mix(lch1.x, lch2.x, t);
|
|
63035
63587
|
float C = mix(lch1.y, lch2.y, t);
|
|
63036
|
-
|
|
63037
|
-
|
|
63038
|
-
|
|
63039
|
-
if (
|
|
63040
|
-
|
|
63041
|
-
|
|
63588
|
+
bool a1 = lch1.y < 1e-6;
|
|
63589
|
+
bool a2 = lch2.y < 1e-6;
|
|
63590
|
+
float H;
|
|
63591
|
+
if (a1 && a2) {
|
|
63592
|
+
H = lch1.z;
|
|
63593
|
+
} else if (a1) {
|
|
63594
|
+
H = lch2.z;
|
|
63595
|
+
} else if (a2) {
|
|
63596
|
+
H = lch1.z;
|
|
63597
|
+
} else {
|
|
63598
|
+
float dh = lch2.z - lch1.z;
|
|
63599
|
+
if (dh > 180.0) dh -= 360.0;
|
|
63600
|
+
if (dh < -180.0) dh += 360.0;
|
|
63601
|
+
H = lch1.z + dh * t;
|
|
63602
|
+
if (H < 0.0) H += 360.0;
|
|
63603
|
+
if (H >= 360.0) H -= 360.0;
|
|
63604
|
+
}
|
|
63605
|
+
return vec3(L, C, H);
|
|
63042
63606
|
}
|
|
63043
63607
|
|
|
63044
|
-
float _gpu_apca(vec3
|
|
63608
|
+
float _gpu_apca(vec3 lch_bg, vec3 lch_fg) {
|
|
63609
|
+
vec3 bg = _gpu_oklch_to_srgb(lch_bg);
|
|
63610
|
+
vec3 fg = _gpu_oklch_to_srgb(lch_fg);
|
|
63045
63611
|
float bgR = _gpu_srgb_to_linear(bg.x);
|
|
63046
63612
|
float bgG = _gpu_srgb_to_linear(bg.y);
|
|
63047
63613
|
float bgB = _gpu_srgb_to_linear(bg.z);
|
|
@@ -63052,9 +63618,7 @@ float _gpu_apca(vec3 bg, vec3 fg) {
|
|
|
63052
63618
|
float fgY = 0.2126729 * fgR + 0.7151522 * fgG + 0.0721750 * fgB;
|
|
63053
63619
|
float bgC = pow(bgY, 0.56);
|
|
63054
63620
|
float fgC = pow(fgY, 0.57);
|
|
63055
|
-
float contrast = (bgC
|
|
63056
|
-
? (bgC - fgC) * 1.14
|
|
63057
|
-
: (bgC - fgC) * 1.14;
|
|
63621
|
+
float contrast = (bgC - fgC) * 1.14;
|
|
63058
63622
|
return contrast * 100.0;
|
|
63059
63623
|
}
|
|
63060
63624
|
`;
|
|
@@ -63098,28 +63662,133 @@ fn _gpu_oklab_to_srgb(lab: vec3f) -> vec3f {
|
|
|
63098
63662
|
|
|
63099
63663
|
fn _gpu_oklab_to_oklch(lab: vec3f) -> vec3f {
|
|
63100
63664
|
let C = length(lab.yz);
|
|
63101
|
-
|
|
63665
|
+
var H = atan2(lab.z, lab.y) * (180.0 / 3.14159265359);
|
|
63666
|
+
if (H < 0.0) { H = H + 360.0; }
|
|
63102
63667
|
return vec3f(lab.x, C, H);
|
|
63103
63668
|
}
|
|
63104
63669
|
|
|
63105
63670
|
fn _gpu_oklch_to_oklab(lch: vec3f) -> vec3f {
|
|
63106
|
-
|
|
63671
|
+
let h_rad = lch.z * (3.14159265359 / 180.0);
|
|
63672
|
+
return vec3f(lch.x, lch.y * cos(h_rad), lch.y * sin(h_rad));
|
|
63673
|
+
}
|
|
63674
|
+
|
|
63675
|
+
fn _gpu_srgb_to_oklch(rgb: vec3f) -> vec3f {
|
|
63676
|
+
return _gpu_oklab_to_oklch(_gpu_srgb_to_oklab(rgb));
|
|
63677
|
+
}
|
|
63678
|
+
|
|
63679
|
+
fn _gpu_oklch_to_srgb(lch: vec3f) -> vec3f {
|
|
63680
|
+
return _gpu_oklab_to_srgb(_gpu_oklch_to_oklab(lch));
|
|
63681
|
+
}
|
|
63682
|
+
|
|
63683
|
+
fn _gpu_hsl_to_rgb(hsl: vec3f) -> vec3f {
|
|
63684
|
+
let h = hsl.x;
|
|
63685
|
+
let s = hsl.y;
|
|
63686
|
+
let l = hsl.z;
|
|
63687
|
+
let c = (1.0 - abs(2.0 * l - 1.0)) * s;
|
|
63688
|
+
let h6 = h / 60.0;
|
|
63689
|
+
let x = c * (1.0 - abs((h6 - 2.0 * floor(h6 / 2.0)) - 1.0));
|
|
63690
|
+
var r: f32 = 0.0;
|
|
63691
|
+
var g: f32 = 0.0;
|
|
63692
|
+
var b: f32 = 0.0;
|
|
63693
|
+
if (h6 < 1.0) { r = c; g = x; b = 0.0; }
|
|
63694
|
+
else if (h6 < 2.0) { r = x; g = c; b = 0.0; }
|
|
63695
|
+
else if (h6 < 3.0) { r = 0.0; g = c; b = x; }
|
|
63696
|
+
else if (h6 < 4.0) { r = 0.0; g = x; b = c; }
|
|
63697
|
+
else if (h6 < 5.0) { r = x; g = 0.0; b = c; }
|
|
63698
|
+
else { r = c; g = 0.0; b = x; }
|
|
63699
|
+
let m = l - c / 2.0;
|
|
63700
|
+
return vec3f(r + m, g + m, b + m);
|
|
63701
|
+
}
|
|
63702
|
+
|
|
63703
|
+
fn _gpu_rgb_to_hsl(rgb: vec3f) -> vec3f {
|
|
63704
|
+
let maxc = max(max(rgb.x, rgb.y), rgb.z);
|
|
63705
|
+
let minc = min(min(rgb.x, rgb.y), rgb.z);
|
|
63706
|
+
let l = (maxc + minc) / 2.0;
|
|
63707
|
+
let d = maxc - minc;
|
|
63708
|
+
if (d < 1e-6) { return vec3f(0.0, 0.0, l); }
|
|
63709
|
+
let s = d / (1.0 - abs(2.0 * l - 1.0));
|
|
63710
|
+
var h: f32;
|
|
63711
|
+
if (maxc == rgb.x) {
|
|
63712
|
+
let v = (rgb.y - rgb.z) / d;
|
|
63713
|
+
h = v - 6.0 * floor(v / 6.0);
|
|
63714
|
+
} else if (maxc == rgb.y) {
|
|
63715
|
+
h = (rgb.z - rgb.x) / d + 2.0;
|
|
63716
|
+
} else {
|
|
63717
|
+
h = (rgb.x - rgb.y) / d + 4.0;
|
|
63718
|
+
}
|
|
63719
|
+
h = h * 60.0;
|
|
63720
|
+
if (h < 0.0) { h = h + 360.0; }
|
|
63721
|
+
return vec3f(h, s, l);
|
|
63722
|
+
}
|
|
63723
|
+
|
|
63724
|
+
fn _gpu_hsv_to_rgb(hsv: vec3f) -> vec3f {
|
|
63725
|
+
let h = hsv.x;
|
|
63726
|
+
let s = hsv.y;
|
|
63727
|
+
let v = hsv.z;
|
|
63728
|
+
let c = v * s;
|
|
63729
|
+
let h6 = h / 60.0;
|
|
63730
|
+
let x = c * (1.0 - abs((h6 - 2.0 * floor(h6 / 2.0)) - 1.0));
|
|
63731
|
+
var r: f32 = 0.0;
|
|
63732
|
+
var g: f32 = 0.0;
|
|
63733
|
+
var b: f32 = 0.0;
|
|
63734
|
+
if (h6 < 1.0) { r = c; g = x; b = 0.0; }
|
|
63735
|
+
else if (h6 < 2.0) { r = x; g = c; b = 0.0; }
|
|
63736
|
+
else if (h6 < 3.0) { r = 0.0; g = c; b = x; }
|
|
63737
|
+
else if (h6 < 4.0) { r = 0.0; g = x; b = c; }
|
|
63738
|
+
else if (h6 < 5.0) { r = x; g = 0.0; b = c; }
|
|
63739
|
+
else { r = c; g = 0.0; b = x; }
|
|
63740
|
+
let m = v - c;
|
|
63741
|
+
return vec3f(r + m, g + m, b + m);
|
|
63107
63742
|
}
|
|
63108
63743
|
|
|
63109
|
-
fn
|
|
63110
|
-
let
|
|
63111
|
-
let
|
|
63744
|
+
fn _gpu_rgb_to_hsv(rgb: vec3f) -> vec3f {
|
|
63745
|
+
let maxc = max(max(rgb.x, rgb.y), rgb.z);
|
|
63746
|
+
let minc = min(min(rgb.x, rgb.y), rgb.z);
|
|
63747
|
+
let v = maxc;
|
|
63748
|
+
let d = maxc - minc;
|
|
63749
|
+
if (d < 1e-6) { return vec3f(0.0, 0.0, v); }
|
|
63750
|
+
var s: f32 = 0.0;
|
|
63751
|
+
if (maxc >= 1e-6) { s = d / maxc; }
|
|
63752
|
+
var h: f32;
|
|
63753
|
+
if (maxc == rgb.x) {
|
|
63754
|
+
let q = (rgb.y - rgb.z) / d;
|
|
63755
|
+
h = q - 6.0 * floor(q / 6.0);
|
|
63756
|
+
} else if (maxc == rgb.y) {
|
|
63757
|
+
h = (rgb.z - rgb.x) / d + 2.0;
|
|
63758
|
+
} else {
|
|
63759
|
+
h = (rgb.x - rgb.y) / d + 4.0;
|
|
63760
|
+
}
|
|
63761
|
+
h = h * 60.0;
|
|
63762
|
+
if (h < 0.0) { h = h + 360.0; }
|
|
63763
|
+
return vec3f(h, s, v);
|
|
63764
|
+
}
|
|
63765
|
+
|
|
63766
|
+
fn _gpu_color_mix(lch1: vec3f, lch2: vec3f, t: f32) -> vec3f {
|
|
63112
63767
|
let L = mix(lch1.x, lch2.x, t);
|
|
63113
63768
|
let C = mix(lch1.y, lch2.y, t);
|
|
63114
|
-
let
|
|
63115
|
-
|
|
63116
|
-
|
|
63117
|
-
if (
|
|
63118
|
-
|
|
63119
|
-
|
|
63769
|
+
let a1 = lch1.y < 1e-6;
|
|
63770
|
+
let a2 = lch2.y < 1e-6;
|
|
63771
|
+
var H: f32;
|
|
63772
|
+
if (a1 && a2) {
|
|
63773
|
+
H = lch1.z;
|
|
63774
|
+
} else if (a1) {
|
|
63775
|
+
H = lch2.z;
|
|
63776
|
+
} else if (a2) {
|
|
63777
|
+
H = lch1.z;
|
|
63778
|
+
} else {
|
|
63779
|
+
var dh = lch2.z - lch1.z;
|
|
63780
|
+
if (dh > 180.0) { dh = dh - 360.0; }
|
|
63781
|
+
if (dh < -180.0) { dh = dh + 360.0; }
|
|
63782
|
+
H = lch1.z + dh * t;
|
|
63783
|
+
if (H < 0.0) { H = H + 360.0; }
|
|
63784
|
+
if (H >= 360.0) { H = H - 360.0; }
|
|
63785
|
+
}
|
|
63786
|
+
return vec3f(L, C, H);
|
|
63120
63787
|
}
|
|
63121
63788
|
|
|
63122
|
-
fn _gpu_apca(
|
|
63789
|
+
fn _gpu_apca(lch_bg: vec3f, lch_fg: vec3f) -> f32 {
|
|
63790
|
+
let bg = _gpu_oklch_to_srgb(lch_bg);
|
|
63791
|
+
let fg = _gpu_oklch_to_srgb(lch_fg);
|
|
63123
63792
|
let bgR = _gpu_srgb_to_linear(bg.x);
|
|
63124
63793
|
let bgG = _gpu_srgb_to_linear(bg.y);
|
|
63125
63794
|
let bgB = _gpu_srgb_to_linear(bg.z);
|
|
@@ -63407,7 +64076,7 @@ var GPUShaderTarget = class {
|
|
|
63407
64076
|
if (stmts.length === 0) return "";
|
|
63408
64077
|
const last = stmts.length - 1;
|
|
63409
64078
|
stmts[last] = `return ${stmts[last]}`;
|
|
63410
|
-
return stmts.join(";\n");
|
|
64079
|
+
return stmts.join(";\n") + ";";
|
|
63411
64080
|
},
|
|
63412
64081
|
...options
|
|
63413
64082
|
};
|
|
@@ -63418,7 +64087,6 @@ var GPUShaderTarget = class {
|
|
|
63418
64087
|
const constants = this.getConstants();
|
|
63419
64088
|
const v2 = this.languageId === "wgsl" ? "vec2f" : "vec2";
|
|
63420
64089
|
const target = this.createTarget({
|
|
63421
|
-
hints: options.hints,
|
|
63422
64090
|
functions: (id) => {
|
|
63423
64091
|
if (userFunctions && id in userFunctions) {
|
|
63424
64092
|
const fn = userFunctions[id];
|
|
@@ -63457,89 +64125,12 @@ var GPUShaderTarget = class {
|
|
|
63457
64125
|
if (code.includes("_gpu_besselJ"))
|
|
63458
64126
|
preamble += this.languageId === "wgsl" ? GPU_BESSELJ_PREAMBLE_WGSL : GPU_BESSELJ_PREAMBLE_GLSL;
|
|
63459
64127
|
if (code.includes("_fractal_")) {
|
|
63460
|
-
|
|
63461
|
-
preamble += this.languageId === "wgsl" ? GPU_DS_ARITHMETIC_PREAMBLE_WGSL : GPU_DS_ARITHMETIC_PREAMBLE_GLSL;
|
|
63462
|
-
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PT_PREAMBLE_WGSL : GPU_FRACTAL_PT_PREAMBLE_GLSL;
|
|
63463
|
-
} else if (code.includes("_fractal_mandelbrot_dp") || code.includes("_fractal_julia_dp")) {
|
|
63464
|
-
preamble += this.languageId === "wgsl" ? GPU_DS_ARITHMETIC_PREAMBLE_WGSL : GPU_DS_ARITHMETIC_PREAMBLE_GLSL;
|
|
63465
|
-
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_DP_PREAMBLE_WGSL : GPU_FRACTAL_DP_PREAMBLE_GLSL;
|
|
63466
|
-
} else {
|
|
63467
|
-
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PREAMBLE_WGSL : GPU_FRACTAL_PREAMBLE_GLSL;
|
|
63468
|
-
}
|
|
64128
|
+
preamble += this.languageId === "wgsl" ? GPU_FRACTAL_PREAMBLE_WGSL : GPU_FRACTAL_PREAMBLE_GLSL;
|
|
63469
64129
|
}
|
|
63470
64130
|
if (code.includes("_gpu_srgb_to") || code.includes("_gpu_oklab") || code.includes("_gpu_oklch") || code.includes("_gpu_color_mix") || code.includes("_gpu_apca")) {
|
|
63471
64131
|
preamble += this.languageId === "wgsl" ? GPU_COLOR_PREAMBLE_WGSL : GPU_COLOR_PREAMBLE_GLSL;
|
|
63472
64132
|
}
|
|
63473
64133
|
if (preamble) result.preamble = preamble;
|
|
63474
|
-
if (code.includes("_fractal_") && options.hints?.viewport) {
|
|
63475
|
-
const strategy = selectFractalStrategy(target);
|
|
63476
|
-
const radius = options.hints.viewport.radius;
|
|
63477
|
-
switch (strategy) {
|
|
63478
|
-
case "single":
|
|
63479
|
-
result.staleWhen = { radiusBelow: 1e-6 };
|
|
63480
|
-
break;
|
|
63481
|
-
case "double":
|
|
63482
|
-
result.staleWhen = { radiusBelow: 1e-14, radiusAbove: 1e-5 };
|
|
63483
|
-
break;
|
|
63484
|
-
case "perturbation":
|
|
63485
|
-
result.staleWhen = {
|
|
63486
|
-
radiusAbove: 1e-5,
|
|
63487
|
-
radiusBelow: radius * 0.01,
|
|
63488
|
-
centerDistance: radius * 2
|
|
63489
|
-
};
|
|
63490
|
-
break;
|
|
63491
|
-
}
|
|
63492
|
-
}
|
|
63493
|
-
if ((code.includes("_fractal_mandelbrot_dp") || code.includes("_fractal_julia_dp")) && options.hints?.viewport) {
|
|
63494
|
-
const cx = hpToNumber(options.hints.viewport.center[0]);
|
|
63495
|
-
const cy = hpToNumber(options.hints.viewport.center[1]);
|
|
63496
|
-
const size = options.hints.viewport.radius * 2;
|
|
63497
|
-
const cx_hi = Math.fround(cx);
|
|
63498
|
-
const cy_hi = Math.fround(cy);
|
|
63499
|
-
result.uniforms = {
|
|
63500
|
-
...result.uniforms,
|
|
63501
|
-
_dp_cx_hi: cx_hi,
|
|
63502
|
-
_dp_cx_lo: cx - cx_hi,
|
|
63503
|
-
_dp_cy_hi: cy_hi,
|
|
63504
|
-
_dp_cy_lo: cy - cy_hi,
|
|
63505
|
-
_dp_w: size,
|
|
63506
|
-
_dp_h: size
|
|
63507
|
-
};
|
|
63508
|
-
}
|
|
63509
|
-
if ((code.includes("_fractal_mandelbrot_pt") || code.includes("_fractal_julia_pt")) && options.hints?.viewport) {
|
|
63510
|
-
const viewport = options.hints.viewport;
|
|
63511
|
-
const size = viewport.radius * 2;
|
|
63512
|
-
result.uniforms = {
|
|
63513
|
-
...result.uniforms,
|
|
63514
|
-
_pt_offset_x: 0,
|
|
63515
|
-
_pt_offset_y: 0,
|
|
63516
|
-
_pt_w: size,
|
|
63517
|
-
_pt_h: size
|
|
63518
|
-
};
|
|
63519
|
-
const digits = Math.max(50, Math.ceil(-Math.log10(viewport.radius)) + 10);
|
|
63520
|
-
const maxIter = 1e3;
|
|
63521
|
-
const orbit = computeReferenceOrbit(
|
|
63522
|
-
viewport.center,
|
|
63523
|
-
maxIter,
|
|
63524
|
-
digits
|
|
63525
|
-
);
|
|
63526
|
-
const orbitLen = orbit.length / 2;
|
|
63527
|
-
const texWidth = Math.min(orbitLen, 4096);
|
|
63528
|
-
const texHeight = Math.ceil(orbitLen / texWidth);
|
|
63529
|
-
result.textures = {
|
|
63530
|
-
_refOrbit: {
|
|
63531
|
-
data: orbit,
|
|
63532
|
-
width: texWidth,
|
|
63533
|
-
height: texHeight,
|
|
63534
|
-
format: "rg32f"
|
|
63535
|
-
}
|
|
63536
|
-
};
|
|
63537
|
-
result.uniforms = {
|
|
63538
|
-
...result.uniforms,
|
|
63539
|
-
_refOrbitLen: orbitLen,
|
|
63540
|
-
_refOrbitTexWidth: texWidth
|
|
63541
|
-
};
|
|
63542
|
-
}
|
|
63543
64134
|
return result;
|
|
63544
64135
|
}
|
|
63545
64136
|
compileToSource(expr2, _options = {}) {
|
|
@@ -63584,7 +64175,7 @@ var GLSLTarget = class extends GPUShaderTarget {
|
|
|
63584
64175
|
if (body.includes("\n")) {
|
|
63585
64176
|
const indented = body.split("\n").map((l) => ` ${l}`).join("\n");
|
|
63586
64177
|
return `${returnType} ${functionName}(${params}) {
|
|
63587
|
-
${indented}
|
|
64178
|
+
${indented}
|
|
63588
64179
|
}`;
|
|
63589
64180
|
}
|
|
63590
64181
|
return `${returnType} ${functionName}(${params}) {
|
|
@@ -63695,7 +64286,7 @@ var WGSLTarget = class extends GPUShaderTarget {
|
|
|
63695
64286
|
return `fn ${functionName}(${params}) -> ${toWGSLType(
|
|
63696
64287
|
returnType
|
|
63697
64288
|
)} {
|
|
63698
|
-
${indented}
|
|
64289
|
+
${indented}
|
|
63699
64290
|
}`;
|
|
63700
64291
|
}
|
|
63701
64292
|
return `fn ${functionName}(${params}) -> ${toWGSLType(returnType)} {
|
|
@@ -68102,6 +68693,7 @@ var ComputeEngine = class _ComputeEngine {
|
|
|
68102
68693
|
this.pushScope(void 0, "global");
|
|
68103
68694
|
this._compilationTargets.registerDefaults();
|
|
68104
68695
|
if (options?.latexSyntax) this._latexSyntax = options.latexSyntax;
|
|
68696
|
+
if (options?.latexOptions) this._latexOptions = { ...options.latexOptions };
|
|
68105
68697
|
hidePrivateProperties(this);
|
|
68106
68698
|
}
|
|
68107
68699
|
toJSON() {
|
|
@@ -68762,6 +69354,29 @@ var ComputeEngine = class _ComputeEngine {
|
|
|
68762
69354
|
);
|
|
68763
69355
|
return this._latexSyntax;
|
|
68764
69356
|
}
|
|
69357
|
+
/** @internal Engine-wide LaTeX parse/serialize options (e.g. decimalSeparator).
|
|
69358
|
+
* Merged into every `parse()` and `toLatex()` call between the LatexSyntax
|
|
69359
|
+
* instance defaults and any per-call overrides. */
|
|
69360
|
+
_latexOptions = {};
|
|
69361
|
+
/** Engine-wide LaTeX parse/serialize options.
|
|
69362
|
+
*
|
|
69363
|
+
* These options are merged into every `parse()` and `toLatex()` call.
|
|
69364
|
+
* Precedence (most-specific wins):
|
|
69365
|
+
* 1. LatexSyntax instance defaults (set at its construction)
|
|
69366
|
+
* 2. `ce.latexOptions` (this property)
|
|
69367
|
+
* 3. Per-call options passed to `ce.parse()` / `expr.toLatex()`
|
|
69368
|
+
*
|
|
69369
|
+
* Assigning replaces the whole bag. Use spread to merge:
|
|
69370
|
+
* ```ts
|
|
69371
|
+
* ce.latexOptions = { ...ce.latexOptions, decimalSeparator: '{,}' };
|
|
69372
|
+
* ```
|
|
69373
|
+
*/
|
|
69374
|
+
get latexOptions() {
|
|
69375
|
+
return this._latexOptions;
|
|
69376
|
+
}
|
|
69377
|
+
set latexOptions(options) {
|
|
69378
|
+
this._latexOptions = { ...options };
|
|
69379
|
+
}
|
|
68765
69380
|
parse(latex, options) {
|
|
68766
69381
|
if (latex === null || latex === void 0) return null;
|
|
68767
69382
|
if (typeof latex !== "string")
|
|
@@ -68769,7 +69384,6 @@ var ComputeEngine = class _ComputeEngine {
|
|
|
68769
69384
|
const syntax = this._requireLatexSyntax();
|
|
68770
69385
|
const { form, ...parseOpts } = options ?? {};
|
|
68771
69386
|
const result = syntax.parse(latex, {
|
|
68772
|
-
decimalSeparator: ".",
|
|
68773
69387
|
getSymbolType: (id) => {
|
|
68774
69388
|
const def = this.lookupDefinition(id);
|
|
68775
69389
|
if (!def) return BoxedType.unknown;
|
|
@@ -68781,6 +69395,7 @@ var ComputeEngine = class _ComputeEngine {
|
|
|
68781
69395
|
const def = this.lookupDefinition(id);
|
|
68782
69396
|
return !!(isValueDef(def) && def.value.subscriptEvaluate);
|
|
68783
69397
|
},
|
|
69398
|
+
...this._latexOptions,
|
|
68784
69399
|
...parseOpts
|
|
68785
69400
|
});
|
|
68786
69401
|
if (result === null) return null;
|
|
@@ -68944,14 +69559,14 @@ var ComputeEngine = class _ComputeEngine {
|
|
|
68944
69559
|
_setDefaultEngineFactory(() => new ComputeEngine());
|
|
68945
69560
|
|
|
68946
69561
|
// src/compute-engine.ts
|
|
68947
|
-
var version = "0.
|
|
69562
|
+
var version = "0.56.0";
|
|
68948
69563
|
ComputeEngine._latexSyntaxFactory = () => new LatexSyntax();
|
|
68949
69564
|
_setDefaultEngineFactory(
|
|
68950
69565
|
() => new ComputeEngine({ latexSyntax: new LatexSyntax() })
|
|
68951
69566
|
);
|
|
68952
69567
|
globalThis[/* @__PURE__ */ Symbol.for("io.cortexjs.compute-engine")] = {
|
|
68953
69568
|
ComputeEngine: ComputeEngine.prototype.constructor,
|
|
68954
|
-
version: "0.
|
|
69569
|
+
version: "0.56.0"
|
|
68955
69570
|
};
|
|
68956
69571
|
export {
|
|
68957
69572
|
DEFINITIONS_ALGEBRA as ALGEBRA_DICTIONARY,
|