@pixodesk/svg-animator-react 1.0.21 → 1.0.22
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/index.umd.js +60 -9
- package/dist/index.umd.js.map +1 -1
- package/package.json +2 -2
package/dist/index.umd.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../node_modules/.pnpm/react@19.2.4/node_modules/react/cjs/react.production.js","../../../node_modules/.pnpm/react@19.2.4/node_modules/react/cjs/react.development.js","../../../node_modules/.pnpm/react@19.2.4/node_modules/react/index.js","../../../node_modules/.pnpm/react@19.2.4/node_modules/react/cjs/react-jsx-runtime.production.js","../../../node_modules/.pnpm/react@19.2.4/node_modules/react/cjs/react-jsx-runtime.development.js","../../../node_modules/.pnpm/react@19.2.4/node_modules/react/jsx-runtime.js","../src/index.ts","../../svg-animator-core/src/PxSchema.ts","../../svg-animator-core/src/PxAnimatorTypes.ts","../../svg-animator-core/src/PxAnimatorUtil.ts","../../svg-animator-core/src/PxIdUtil.ts","../../svg-animator-core/src/PxNodeProps.ts","../../svg-animator-core/src/PxMotionPath.ts","../../svg-animator-core/src/PxDefinitions.ts","../../svg-animator-core/src/PxNodeCloneUtil.ts","../../svg-animator-core/src/PxAnimatorUseMaterialiser.ts","../../svg-animator-core/src/effects/transformParts.ts","../../svg-animator-core/src/effects/transformationEffect.ts","../../svg-animator-core/src/effects/contentRefSplit.ts","../../svg-animator-core/src/effects/util.ts","../../svg-animator-core/src/effects/gradientEffect.ts","../../svg-animator-core/src/effects/clipPathEffect.ts","../../svg-animator-core/src/effects/maskedByEffect.ts","../../svg-animator-core/src/effects/refEffect.ts","../../svg-animator-core/src/effects/repeaterEffect.ts","../../svg-animator-core/src/effects/retimeEffect.ts","../../svg-animator-core/src/effects/pathSampler.ts","../../svg-animator-core/src/effects/textPathEffect.ts","../../svg-animator-core/src/effects/elementFactory.ts","../../svg-animator-core/src/effects/glyphPathBake.ts","../../svg-animator-core/src/effects/textGlyphsEffect.ts","../../svg-animator-core/src/effects/trimPathEffect.ts","../../svg-animator-core/src/effects/PlayerEffectsUtil.ts","../../svg-animator-core/src/PxAnimatorMaterialiseAll.ts","../../svg-animator-core/src/PxFrameLoop.ts","../../svg-animator-core/src/effects/PlayerEffectsUtil.visualModel.ts","../../svg-animator-web/src/PxAnimatorDOM.ts","../../svg-animator-web/src/PxAnimatorTriggers.ts","../../svg-animator-web/src/PxAnimatorFrameLoop.ts","../../svg-animator-web/src/PxAnimatorWebApi.ts","../../svg-animator-web/src/PxAnimator.ts","../src/PixodeskSvgAnimator.tsx","../src/Utils.ts","../src/PixodeskSvgCssAnimator.tsx"],"sourcesContent":["/**\n * @license React\n * react.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\"),\n REACT_STRICT_MODE_TYPE = Symbol.for(\"react.strict_mode\"),\n REACT_PROFILER_TYPE = Symbol.for(\"react.profiler\"),\n REACT_CONSUMER_TYPE = Symbol.for(\"react.consumer\"),\n REACT_CONTEXT_TYPE = Symbol.for(\"react.context\"),\n REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\"),\n REACT_SUSPENSE_TYPE = Symbol.for(\"react.suspense\"),\n REACT_MEMO_TYPE = Symbol.for(\"react.memo\"),\n REACT_LAZY_TYPE = Symbol.for(\"react.lazy\"),\n REACT_ACTIVITY_TYPE = Symbol.for(\"react.activity\"),\n MAYBE_ITERATOR_SYMBOL = Symbol.iterator;\nfunction getIteratorFn(maybeIterable) {\n if (null === maybeIterable || \"object\" !== typeof maybeIterable) return null;\n maybeIterable =\n (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) ||\n maybeIterable[\"@@iterator\"];\n return \"function\" === typeof maybeIterable ? maybeIterable : null;\n}\nvar ReactNoopUpdateQueue = {\n isMounted: function () {\n return !1;\n },\n enqueueForceUpdate: function () {},\n enqueueReplaceState: function () {},\n enqueueSetState: function () {}\n },\n assign = Object.assign,\n emptyObject = {};\nfunction Component(props, context, updater) {\n this.props = props;\n this.context = context;\n this.refs = emptyObject;\n this.updater = updater || ReactNoopUpdateQueue;\n}\nComponent.prototype.isReactComponent = {};\nComponent.prototype.setState = function (partialState, callback) {\n if (\n \"object\" !== typeof partialState &&\n \"function\" !== typeof partialState &&\n null != partialState\n )\n throw Error(\n \"takes an object of state variables to update or a function which returns an object of state variables.\"\n );\n this.updater.enqueueSetState(this, partialState, callback, \"setState\");\n};\nComponent.prototype.forceUpdate = function (callback) {\n this.updater.enqueueForceUpdate(this, callback, \"forceUpdate\");\n};\nfunction ComponentDummy() {}\nComponentDummy.prototype = Component.prototype;\nfunction PureComponent(props, context, updater) {\n this.props = props;\n this.context = context;\n this.refs = emptyObject;\n this.updater = updater || ReactNoopUpdateQueue;\n}\nvar pureComponentPrototype = (PureComponent.prototype = new ComponentDummy());\npureComponentPrototype.constructor = PureComponent;\nassign(pureComponentPrototype, Component.prototype);\npureComponentPrototype.isPureReactComponent = !0;\nvar isArrayImpl = Array.isArray;\nfunction noop() {}\nvar ReactSharedInternals = { H: null, A: null, T: null, S: null },\n hasOwnProperty = Object.prototype.hasOwnProperty;\nfunction ReactElement(type, key, props) {\n var refProp = props.ref;\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n ref: void 0 !== refProp ? refProp : null,\n props: props\n };\n}\nfunction cloneAndReplaceKey(oldElement, newKey) {\n return ReactElement(oldElement.type, newKey, oldElement.props);\n}\nfunction isValidElement(object) {\n return (\n \"object\" === typeof object &&\n null !== object &&\n object.$$typeof === REACT_ELEMENT_TYPE\n );\n}\nfunction escape(key) {\n var escaperLookup = { \"=\": \"=0\", \":\": \"=2\" };\n return (\n \"$\" +\n key.replace(/[=:]/g, function (match) {\n return escaperLookup[match];\n })\n );\n}\nvar userProvidedKeyEscapeRegex = /\\/+/g;\nfunction getElementKey(element, index) {\n return \"object\" === typeof element && null !== element && null != element.key\n ? escape(\"\" + element.key)\n : index.toString(36);\n}\nfunction resolveThenable(thenable) {\n switch (thenable.status) {\n case \"fulfilled\":\n return thenable.value;\n case \"rejected\":\n throw thenable.reason;\n default:\n switch (\n (\"string\" === typeof thenable.status\n ? thenable.then(noop, noop)\n : ((thenable.status = \"pending\"),\n thenable.then(\n function (fulfilledValue) {\n \"pending\" === thenable.status &&\n ((thenable.status = \"fulfilled\"),\n (thenable.value = fulfilledValue));\n },\n function (error) {\n \"pending\" === thenable.status &&\n ((thenable.status = \"rejected\"), (thenable.reason = error));\n }\n )),\n thenable.status)\n ) {\n case \"fulfilled\":\n return thenable.value;\n case \"rejected\":\n throw thenable.reason;\n }\n }\n throw thenable;\n}\nfunction mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) {\n var type = typeof children;\n if (\"undefined\" === type || \"boolean\" === type) children = null;\n var invokeCallback = !1;\n if (null === children) invokeCallback = !0;\n else\n switch (type) {\n case \"bigint\":\n case \"string\":\n case \"number\":\n invokeCallback = !0;\n break;\n case \"object\":\n switch (children.$$typeof) {\n case REACT_ELEMENT_TYPE:\n case REACT_PORTAL_TYPE:\n invokeCallback = !0;\n break;\n case REACT_LAZY_TYPE:\n return (\n (invokeCallback = children._init),\n mapIntoArray(\n invokeCallback(children._payload),\n array,\n escapedPrefix,\n nameSoFar,\n callback\n )\n );\n }\n }\n if (invokeCallback)\n return (\n (callback = callback(children)),\n (invokeCallback =\n \"\" === nameSoFar ? \".\" + getElementKey(children, 0) : nameSoFar),\n isArrayImpl(callback)\n ? ((escapedPrefix = \"\"),\n null != invokeCallback &&\n (escapedPrefix =\n invokeCallback.replace(userProvidedKeyEscapeRegex, \"$&/\") + \"/\"),\n mapIntoArray(callback, array, escapedPrefix, \"\", function (c) {\n return c;\n }))\n : null != callback &&\n (isValidElement(callback) &&\n (callback = cloneAndReplaceKey(\n callback,\n escapedPrefix +\n (null == callback.key ||\n (children && children.key === callback.key)\n ? \"\"\n : (\"\" + callback.key).replace(\n userProvidedKeyEscapeRegex,\n \"$&/\"\n ) + \"/\") +\n invokeCallback\n )),\n array.push(callback)),\n 1\n );\n invokeCallback = 0;\n var nextNamePrefix = \"\" === nameSoFar ? \".\" : nameSoFar + \":\";\n if (isArrayImpl(children))\n for (var i = 0; i < children.length; i++)\n (nameSoFar = children[i]),\n (type = nextNamePrefix + getElementKey(nameSoFar, i)),\n (invokeCallback += mapIntoArray(\n nameSoFar,\n array,\n escapedPrefix,\n type,\n callback\n ));\n else if (((i = getIteratorFn(children)), \"function\" === typeof i))\n for (\n children = i.call(children), i = 0;\n !(nameSoFar = children.next()).done;\n\n )\n (nameSoFar = nameSoFar.value),\n (type = nextNamePrefix + getElementKey(nameSoFar, i++)),\n (invokeCallback += mapIntoArray(\n nameSoFar,\n array,\n escapedPrefix,\n type,\n callback\n ));\n else if (\"object\" === type) {\n if (\"function\" === typeof children.then)\n return mapIntoArray(\n resolveThenable(children),\n array,\n escapedPrefix,\n nameSoFar,\n callback\n );\n array = String(children);\n throw Error(\n \"Objects are not valid as a React child (found: \" +\n (\"[object Object]\" === array\n ? \"object with keys {\" + Object.keys(children).join(\", \") + \"}\"\n : array) +\n \"). If you meant to render a collection of children, use an array instead.\"\n );\n }\n return invokeCallback;\n}\nfunction mapChildren(children, func, context) {\n if (null == children) return children;\n var result = [],\n count = 0;\n mapIntoArray(children, result, \"\", \"\", function (child) {\n return func.call(context, child, count++);\n });\n return result;\n}\nfunction lazyInitializer(payload) {\n if (-1 === payload._status) {\n var ctor = payload._result;\n ctor = ctor();\n ctor.then(\n function (moduleObject) {\n if (0 === payload._status || -1 === payload._status)\n (payload._status = 1), (payload._result = moduleObject);\n },\n function (error) {\n if (0 === payload._status || -1 === payload._status)\n (payload._status = 2), (payload._result = error);\n }\n );\n -1 === payload._status && ((payload._status = 0), (payload._result = ctor));\n }\n if (1 === payload._status) return payload._result.default;\n throw payload._result;\n}\nvar reportGlobalError =\n \"function\" === typeof reportError\n ? reportError\n : function (error) {\n if (\n \"object\" === typeof window &&\n \"function\" === typeof window.ErrorEvent\n ) {\n var event = new window.ErrorEvent(\"error\", {\n bubbles: !0,\n cancelable: !0,\n message:\n \"object\" === typeof error &&\n null !== error &&\n \"string\" === typeof error.message\n ? String(error.message)\n : String(error),\n error: error\n });\n if (!window.dispatchEvent(event)) return;\n } else if (\n \"object\" === typeof process &&\n \"function\" === typeof process.emit\n ) {\n process.emit(\"uncaughtException\", error);\n return;\n }\n console.error(error);\n },\n Children = {\n map: mapChildren,\n forEach: function (children, forEachFunc, forEachContext) {\n mapChildren(\n children,\n function () {\n forEachFunc.apply(this, arguments);\n },\n forEachContext\n );\n },\n count: function (children) {\n var n = 0;\n mapChildren(children, function () {\n n++;\n });\n return n;\n },\n toArray: function (children) {\n return (\n mapChildren(children, function (child) {\n return child;\n }) || []\n );\n },\n only: function (children) {\n if (!isValidElement(children))\n throw Error(\n \"React.Children.only expected to receive a single React element child.\"\n );\n return children;\n }\n };\nexports.Activity = REACT_ACTIVITY_TYPE;\nexports.Children = Children;\nexports.Component = Component;\nexports.Fragment = REACT_FRAGMENT_TYPE;\nexports.Profiler = REACT_PROFILER_TYPE;\nexports.PureComponent = PureComponent;\nexports.StrictMode = REACT_STRICT_MODE_TYPE;\nexports.Suspense = REACT_SUSPENSE_TYPE;\nexports.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE =\n ReactSharedInternals;\nexports.__COMPILER_RUNTIME = {\n __proto__: null,\n c: function (size) {\n return ReactSharedInternals.H.useMemoCache(size);\n }\n};\nexports.cache = function (fn) {\n return function () {\n return fn.apply(null, arguments);\n };\n};\nexports.cacheSignal = function () {\n return null;\n};\nexports.cloneElement = function (element, config, children) {\n if (null === element || void 0 === element)\n throw Error(\n \"The argument must be a React element, but you passed \" + element + \".\"\n );\n var props = assign({}, element.props),\n key = element.key;\n if (null != config)\n for (propName in (void 0 !== config.key && (key = \"\" + config.key), config))\n !hasOwnProperty.call(config, propName) ||\n \"key\" === propName ||\n \"__self\" === propName ||\n \"__source\" === propName ||\n (\"ref\" === propName && void 0 === config.ref) ||\n (props[propName] = config[propName]);\n var propName = arguments.length - 2;\n if (1 === propName) props.children = children;\n else if (1 < propName) {\n for (var childArray = Array(propName), i = 0; i < propName; i++)\n childArray[i] = arguments[i + 2];\n props.children = childArray;\n }\n return ReactElement(element.type, key, props);\n};\nexports.createContext = function (defaultValue) {\n defaultValue = {\n $$typeof: REACT_CONTEXT_TYPE,\n _currentValue: defaultValue,\n _currentValue2: defaultValue,\n _threadCount: 0,\n Provider: null,\n Consumer: null\n };\n defaultValue.Provider = defaultValue;\n defaultValue.Consumer = {\n $$typeof: REACT_CONSUMER_TYPE,\n _context: defaultValue\n };\n return defaultValue;\n};\nexports.createElement = function (type, config, children) {\n var propName,\n props = {},\n key = null;\n if (null != config)\n for (propName in (void 0 !== config.key && (key = \"\" + config.key), config))\n hasOwnProperty.call(config, propName) &&\n \"key\" !== propName &&\n \"__self\" !== propName &&\n \"__source\" !== propName &&\n (props[propName] = config[propName]);\n var childrenLength = arguments.length - 2;\n if (1 === childrenLength) props.children = children;\n else if (1 < childrenLength) {\n for (var childArray = Array(childrenLength), i = 0; i < childrenLength; i++)\n childArray[i] = arguments[i + 2];\n props.children = childArray;\n }\n if (type && type.defaultProps)\n for (propName in ((childrenLength = type.defaultProps), childrenLength))\n void 0 === props[propName] &&\n (props[propName] = childrenLength[propName]);\n return ReactElement(type, key, props);\n};\nexports.createRef = function () {\n return { current: null };\n};\nexports.forwardRef = function (render) {\n return { $$typeof: REACT_FORWARD_REF_TYPE, render: render };\n};\nexports.isValidElement = isValidElement;\nexports.lazy = function (ctor) {\n return {\n $$typeof: REACT_LAZY_TYPE,\n _payload: { _status: -1, _result: ctor },\n _init: lazyInitializer\n };\n};\nexports.memo = function (type, compare) {\n return {\n $$typeof: REACT_MEMO_TYPE,\n type: type,\n compare: void 0 === compare ? null : compare\n };\n};\nexports.startTransition = function (scope) {\n var prevTransition = ReactSharedInternals.T,\n currentTransition = {};\n ReactSharedInternals.T = currentTransition;\n try {\n var returnValue = scope(),\n onStartTransitionFinish = ReactSharedInternals.S;\n null !== onStartTransitionFinish &&\n onStartTransitionFinish(currentTransition, returnValue);\n \"object\" === typeof returnValue &&\n null !== returnValue &&\n \"function\" === typeof returnValue.then &&\n returnValue.then(noop, reportGlobalError);\n } catch (error) {\n reportGlobalError(error);\n } finally {\n null !== prevTransition &&\n null !== currentTransition.types &&\n (prevTransition.types = currentTransition.types),\n (ReactSharedInternals.T = prevTransition);\n }\n};\nexports.unstable_useCacheRefresh = function () {\n return ReactSharedInternals.H.useCacheRefresh();\n};\nexports.use = function (usable) {\n return ReactSharedInternals.H.use(usable);\n};\nexports.useActionState = function (action, initialState, permalink) {\n return ReactSharedInternals.H.useActionState(action, initialState, permalink);\n};\nexports.useCallback = function (callback, deps) {\n return ReactSharedInternals.H.useCallback(callback, deps);\n};\nexports.useContext = function (Context) {\n return ReactSharedInternals.H.useContext(Context);\n};\nexports.useDebugValue = function () {};\nexports.useDeferredValue = function (value, initialValue) {\n return ReactSharedInternals.H.useDeferredValue(value, initialValue);\n};\nexports.useEffect = function (create, deps) {\n return ReactSharedInternals.H.useEffect(create, deps);\n};\nexports.useEffectEvent = function (callback) {\n return ReactSharedInternals.H.useEffectEvent(callback);\n};\nexports.useId = function () {\n return ReactSharedInternals.H.useId();\n};\nexports.useImperativeHandle = function (ref, create, deps) {\n return ReactSharedInternals.H.useImperativeHandle(ref, create, deps);\n};\nexports.useInsertionEffect = function (create, deps) {\n return ReactSharedInternals.H.useInsertionEffect(create, deps);\n};\nexports.useLayoutEffect = function (create, deps) {\n return ReactSharedInternals.H.useLayoutEffect(create, deps);\n};\nexports.useMemo = function (create, deps) {\n return ReactSharedInternals.H.useMemo(create, deps);\n};\nexports.useOptimistic = function (passthrough, reducer) {\n return ReactSharedInternals.H.useOptimistic(passthrough, reducer);\n};\nexports.useReducer = function (reducer, initialArg, init) {\n return ReactSharedInternals.H.useReducer(reducer, initialArg, init);\n};\nexports.useRef = function (initialValue) {\n return ReactSharedInternals.H.useRef(initialValue);\n};\nexports.useState = function (initialState) {\n return ReactSharedInternals.H.useState(initialState);\n};\nexports.useSyncExternalStore = function (\n subscribe,\n getSnapshot,\n getServerSnapshot\n) {\n return ReactSharedInternals.H.useSyncExternalStore(\n subscribe,\n getSnapshot,\n getServerSnapshot\n );\n};\nexports.useTransition = function () {\n return ReactSharedInternals.H.useTransition();\n};\nexports.version = \"19.2.4\";\n","/**\n * @license React\n * react.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n (function () {\n function defineDeprecationWarning(methodName, info) {\n Object.defineProperty(Component.prototype, methodName, {\n get: function () {\n console.warn(\n \"%s(...) is deprecated in plain JavaScript React classes. %s\",\n info[0],\n info[1]\n );\n }\n });\n }\n function getIteratorFn(maybeIterable) {\n if (null === maybeIterable || \"object\" !== typeof maybeIterable)\n return null;\n maybeIterable =\n (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) ||\n maybeIterable[\"@@iterator\"];\n return \"function\" === typeof maybeIterable ? maybeIterable : null;\n }\n function warnNoop(publicInstance, callerName) {\n publicInstance =\n ((publicInstance = publicInstance.constructor) &&\n (publicInstance.displayName || publicInstance.name)) ||\n \"ReactClass\";\n var warningKey = publicInstance + \".\" + callerName;\n didWarnStateUpdateForUnmountedComponent[warningKey] ||\n (console.error(\n \"Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.\",\n callerName,\n publicInstance\n ),\n (didWarnStateUpdateForUnmountedComponent[warningKey] = !0));\n }\n function Component(props, context, updater) {\n this.props = props;\n this.context = context;\n this.refs = emptyObject;\n this.updater = updater || ReactNoopUpdateQueue;\n }\n function ComponentDummy() {}\n function PureComponent(props, context, updater) {\n this.props = props;\n this.context = context;\n this.refs = emptyObject;\n this.updater = updater || ReactNoopUpdateQueue;\n }\n function noop() {}\n function testStringCoercion(value) {\n return \"\" + value;\n }\n function checkKeyStringCoercion(value) {\n try {\n testStringCoercion(value);\n var JSCompiler_inline_result = !1;\n } catch (e) {\n JSCompiler_inline_result = !0;\n }\n if (JSCompiler_inline_result) {\n JSCompiler_inline_result = console;\n var JSCompiler_temp_const = JSCompiler_inline_result.error;\n var JSCompiler_inline_result$jscomp$0 =\n (\"function\" === typeof Symbol &&\n Symbol.toStringTag &&\n value[Symbol.toStringTag]) ||\n value.constructor.name ||\n \"Object\";\n JSCompiler_temp_const.call(\n JSCompiler_inline_result,\n \"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.\",\n JSCompiler_inline_result$jscomp$0\n );\n return testStringCoercion(value);\n }\n }\n function getComponentNameFromType(type) {\n if (null == type) return null;\n if (\"function\" === typeof type)\n return type.$$typeof === REACT_CLIENT_REFERENCE\n ? null\n : type.displayName || type.name || null;\n if (\"string\" === typeof type) return type;\n switch (type) {\n case REACT_FRAGMENT_TYPE:\n return \"Fragment\";\n case REACT_PROFILER_TYPE:\n return \"Profiler\";\n case REACT_STRICT_MODE_TYPE:\n return \"StrictMode\";\n case REACT_SUSPENSE_TYPE:\n return \"Suspense\";\n case REACT_SUSPENSE_LIST_TYPE:\n return \"SuspenseList\";\n case REACT_ACTIVITY_TYPE:\n return \"Activity\";\n }\n if (\"object\" === typeof type)\n switch (\n (\"number\" === typeof type.tag &&\n console.error(\n \"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.\"\n ),\n type.$$typeof)\n ) {\n case REACT_PORTAL_TYPE:\n return \"Portal\";\n case REACT_CONTEXT_TYPE:\n return type.displayName || \"Context\";\n case REACT_CONSUMER_TYPE:\n return (type._context.displayName || \"Context\") + \".Consumer\";\n case REACT_FORWARD_REF_TYPE:\n var innerType = type.render;\n type = type.displayName;\n type ||\n ((type = innerType.displayName || innerType.name || \"\"),\n (type = \"\" !== type ? \"ForwardRef(\" + type + \")\" : \"ForwardRef\"));\n return type;\n case REACT_MEMO_TYPE:\n return (\n (innerType = type.displayName || null),\n null !== innerType\n ? innerType\n : getComponentNameFromType(type.type) || \"Memo\"\n );\n case REACT_LAZY_TYPE:\n innerType = type._payload;\n type = type._init;\n try {\n return getComponentNameFromType(type(innerType));\n } catch (x) {}\n }\n return null;\n }\n function getTaskName(type) {\n if (type === REACT_FRAGMENT_TYPE) return \"<>\";\n if (\n \"object\" === typeof type &&\n null !== type &&\n type.$$typeof === REACT_LAZY_TYPE\n )\n return \"<...>\";\n try {\n var name = getComponentNameFromType(type);\n return name ? \"<\" + name + \">\" : \"<...>\";\n } catch (x) {\n return \"<...>\";\n }\n }\n function getOwner() {\n var dispatcher = ReactSharedInternals.A;\n return null === dispatcher ? null : dispatcher.getOwner();\n }\n function UnknownOwner() {\n return Error(\"react-stack-top-frame\");\n }\n function hasValidKey(config) {\n if (hasOwnProperty.call(config, \"key\")) {\n var getter = Object.getOwnPropertyDescriptor(config, \"key\").get;\n if (getter && getter.isReactWarning) return !1;\n }\n return void 0 !== config.key;\n }\n function defineKeyPropWarningGetter(props, displayName) {\n function warnAboutAccessingKey() {\n specialPropKeyWarningShown ||\n ((specialPropKeyWarningShown = !0),\n console.error(\n \"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)\",\n displayName\n ));\n }\n warnAboutAccessingKey.isReactWarning = !0;\n Object.defineProperty(props, \"key\", {\n get: warnAboutAccessingKey,\n configurable: !0\n });\n }\n function elementRefGetterWithDeprecationWarning() {\n var componentName = getComponentNameFromType(this.type);\n didWarnAboutElementRef[componentName] ||\n ((didWarnAboutElementRef[componentName] = !0),\n console.error(\n \"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.\"\n ));\n componentName = this.props.ref;\n return void 0 !== componentName ? componentName : null;\n }\n function ReactElement(type, key, props, owner, debugStack, debugTask) {\n var refProp = props.ref;\n type = {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n props: props,\n _owner: owner\n };\n null !== (void 0 !== refProp ? refProp : null)\n ? Object.defineProperty(type, \"ref\", {\n enumerable: !1,\n get: elementRefGetterWithDeprecationWarning\n })\n : Object.defineProperty(type, \"ref\", { enumerable: !1, value: null });\n type._store = {};\n Object.defineProperty(type._store, \"validated\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: 0\n });\n Object.defineProperty(type, \"_debugInfo\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: null\n });\n Object.defineProperty(type, \"_debugStack\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugStack\n });\n Object.defineProperty(type, \"_debugTask\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugTask\n });\n Object.freeze && (Object.freeze(type.props), Object.freeze(type));\n return type;\n }\n function cloneAndReplaceKey(oldElement, newKey) {\n newKey = ReactElement(\n oldElement.type,\n newKey,\n oldElement.props,\n oldElement._owner,\n oldElement._debugStack,\n oldElement._debugTask\n );\n oldElement._store &&\n (newKey._store.validated = oldElement._store.validated);\n return newKey;\n }\n function validateChildKeys(node) {\n isValidElement(node)\n ? node._store && (node._store.validated = 1)\n : \"object\" === typeof node &&\n null !== node &&\n node.$$typeof === REACT_LAZY_TYPE &&\n (\"fulfilled\" === node._payload.status\n ? isValidElement(node._payload.value) &&\n node._payload.value._store &&\n (node._payload.value._store.validated = 1)\n : node._store && (node._store.validated = 1));\n }\n function isValidElement(object) {\n return (\n \"object\" === typeof object &&\n null !== object &&\n object.$$typeof === REACT_ELEMENT_TYPE\n );\n }\n function escape(key) {\n var escaperLookup = { \"=\": \"=0\", \":\": \"=2\" };\n return (\n \"$\" +\n key.replace(/[=:]/g, function (match) {\n return escaperLookup[match];\n })\n );\n }\n function getElementKey(element, index) {\n return \"object\" === typeof element &&\n null !== element &&\n null != element.key\n ? (checkKeyStringCoercion(element.key), escape(\"\" + element.key))\n : index.toString(36);\n }\n function resolveThenable(thenable) {\n switch (thenable.status) {\n case \"fulfilled\":\n return thenable.value;\n case \"rejected\":\n throw thenable.reason;\n default:\n switch (\n (\"string\" === typeof thenable.status\n ? thenable.then(noop, noop)\n : ((thenable.status = \"pending\"),\n thenable.then(\n function (fulfilledValue) {\n \"pending\" === thenable.status &&\n ((thenable.status = \"fulfilled\"),\n (thenable.value = fulfilledValue));\n },\n function (error) {\n \"pending\" === thenable.status &&\n ((thenable.status = \"rejected\"),\n (thenable.reason = error));\n }\n )),\n thenable.status)\n ) {\n case \"fulfilled\":\n return thenable.value;\n case \"rejected\":\n throw thenable.reason;\n }\n }\n throw thenable;\n }\n function mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) {\n var type = typeof children;\n if (\"undefined\" === type || \"boolean\" === type) children = null;\n var invokeCallback = !1;\n if (null === children) invokeCallback = !0;\n else\n switch (type) {\n case \"bigint\":\n case \"string\":\n case \"number\":\n invokeCallback = !0;\n break;\n case \"object\":\n switch (children.$$typeof) {\n case REACT_ELEMENT_TYPE:\n case REACT_PORTAL_TYPE:\n invokeCallback = !0;\n break;\n case REACT_LAZY_TYPE:\n return (\n (invokeCallback = children._init),\n mapIntoArray(\n invokeCallback(children._payload),\n array,\n escapedPrefix,\n nameSoFar,\n callback\n )\n );\n }\n }\n if (invokeCallback) {\n invokeCallback = children;\n callback = callback(invokeCallback);\n var childKey =\n \"\" === nameSoFar ? \".\" + getElementKey(invokeCallback, 0) : nameSoFar;\n isArrayImpl(callback)\n ? ((escapedPrefix = \"\"),\n null != childKey &&\n (escapedPrefix =\n childKey.replace(userProvidedKeyEscapeRegex, \"$&/\") + \"/\"),\n mapIntoArray(callback, array, escapedPrefix, \"\", function (c) {\n return c;\n }))\n : null != callback &&\n (isValidElement(callback) &&\n (null != callback.key &&\n ((invokeCallback && invokeCallback.key === callback.key) ||\n checkKeyStringCoercion(callback.key)),\n (escapedPrefix = cloneAndReplaceKey(\n callback,\n escapedPrefix +\n (null == callback.key ||\n (invokeCallback && invokeCallback.key === callback.key)\n ? \"\"\n : (\"\" + callback.key).replace(\n userProvidedKeyEscapeRegex,\n \"$&/\"\n ) + \"/\") +\n childKey\n )),\n \"\" !== nameSoFar &&\n null != invokeCallback &&\n isValidElement(invokeCallback) &&\n null == invokeCallback.key &&\n invokeCallback._store &&\n !invokeCallback._store.validated &&\n (escapedPrefix._store.validated = 2),\n (callback = escapedPrefix)),\n array.push(callback));\n return 1;\n }\n invokeCallback = 0;\n childKey = \"\" === nameSoFar ? \".\" : nameSoFar + \":\";\n if (isArrayImpl(children))\n for (var i = 0; i < children.length; i++)\n (nameSoFar = children[i]),\n (type = childKey + getElementKey(nameSoFar, i)),\n (invokeCallback += mapIntoArray(\n nameSoFar,\n array,\n escapedPrefix,\n type,\n callback\n ));\n else if (((i = getIteratorFn(children)), \"function\" === typeof i))\n for (\n i === children.entries &&\n (didWarnAboutMaps ||\n console.warn(\n \"Using Maps as children is not supported. Use an array of keyed ReactElements instead.\"\n ),\n (didWarnAboutMaps = !0)),\n children = i.call(children),\n i = 0;\n !(nameSoFar = children.next()).done;\n\n )\n (nameSoFar = nameSoFar.value),\n (type = childKey + getElementKey(nameSoFar, i++)),\n (invokeCallback += mapIntoArray(\n nameSoFar,\n array,\n escapedPrefix,\n type,\n callback\n ));\n else if (\"object\" === type) {\n if (\"function\" === typeof children.then)\n return mapIntoArray(\n resolveThenable(children),\n array,\n escapedPrefix,\n nameSoFar,\n callback\n );\n array = String(children);\n throw Error(\n \"Objects are not valid as a React child (found: \" +\n (\"[object Object]\" === array\n ? \"object with keys {\" + Object.keys(children).join(\", \") + \"}\"\n : array) +\n \"). If you meant to render a collection of children, use an array instead.\"\n );\n }\n return invokeCallback;\n }\n function mapChildren(children, func, context) {\n if (null == children) return children;\n var result = [],\n count = 0;\n mapIntoArray(children, result, \"\", \"\", function (child) {\n return func.call(context, child, count++);\n });\n return result;\n }\n function lazyInitializer(payload) {\n if (-1 === payload._status) {\n var ioInfo = payload._ioInfo;\n null != ioInfo && (ioInfo.start = ioInfo.end = performance.now());\n ioInfo = payload._result;\n var thenable = ioInfo();\n thenable.then(\n function (moduleObject) {\n if (0 === payload._status || -1 === payload._status) {\n payload._status = 1;\n payload._result = moduleObject;\n var _ioInfo = payload._ioInfo;\n null != _ioInfo && (_ioInfo.end = performance.now());\n void 0 === thenable.status &&\n ((thenable.status = \"fulfilled\"),\n (thenable.value = moduleObject));\n }\n },\n function (error) {\n if (0 === payload._status || -1 === payload._status) {\n payload._status = 2;\n payload._result = error;\n var _ioInfo2 = payload._ioInfo;\n null != _ioInfo2 && (_ioInfo2.end = performance.now());\n void 0 === thenable.status &&\n ((thenable.status = \"rejected\"), (thenable.reason = error));\n }\n }\n );\n ioInfo = payload._ioInfo;\n if (null != ioInfo) {\n ioInfo.value = thenable;\n var displayName = thenable.displayName;\n \"string\" === typeof displayName && (ioInfo.name = displayName);\n }\n -1 === payload._status &&\n ((payload._status = 0), (payload._result = thenable));\n }\n if (1 === payload._status)\n return (\n (ioInfo = payload._result),\n void 0 === ioInfo &&\n console.error(\n \"lazy: Expected the result of a dynamic import() call. Instead received: %s\\n\\nYour code should look like: \\n const MyComponent = lazy(() => import('./MyComponent'))\\n\\nDid you accidentally put curly braces around the import?\",\n ioInfo\n ),\n \"default\" in ioInfo ||\n console.error(\n \"lazy: Expected the result of a dynamic import() call. Instead received: %s\\n\\nYour code should look like: \\n const MyComponent = lazy(() => import('./MyComponent'))\",\n ioInfo\n ),\n ioInfo.default\n );\n throw payload._result;\n }\n function resolveDispatcher() {\n var dispatcher = ReactSharedInternals.H;\n null === dispatcher &&\n console.error(\n \"Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\\n1. You might have mismatching versions of React and the renderer (such as React DOM)\\n2. You might be breaking the Rules of Hooks\\n3. You might have more than one copy of React in the same app\\nSee https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.\"\n );\n return dispatcher;\n }\n function releaseAsyncTransition() {\n ReactSharedInternals.asyncTransitions--;\n }\n function enqueueTask(task) {\n if (null === enqueueTaskImpl)\n try {\n var requireString = (\"require\" + Math.random()).slice(0, 7);\n enqueueTaskImpl = (module && module[requireString]).call(\n module,\n \"timers\"\n ).setImmediate;\n } catch (_err) {\n enqueueTaskImpl = function (callback) {\n !1 === didWarnAboutMessageChannel &&\n ((didWarnAboutMessageChannel = !0),\n \"undefined\" === typeof MessageChannel &&\n console.error(\n \"This browser does not have a MessageChannel implementation, so enqueuing tasks via await act(async () => ...) will fail. Please file an issue at https://github.com/facebook/react/issues if you encounter this warning.\"\n ));\n var channel = new MessageChannel();\n channel.port1.onmessage = callback;\n channel.port2.postMessage(void 0);\n };\n }\n return enqueueTaskImpl(task);\n }\n function aggregateErrors(errors) {\n return 1 < errors.length && \"function\" === typeof AggregateError\n ? new AggregateError(errors)\n : errors[0];\n }\n function popActScope(prevActQueue, prevActScopeDepth) {\n prevActScopeDepth !== actScopeDepth - 1 &&\n console.error(\n \"You seem to have overlapping act() calls, this is not supported. Be sure to await previous act() calls before making a new one. \"\n );\n actScopeDepth = prevActScopeDepth;\n }\n function recursivelyFlushAsyncActWork(returnValue, resolve, reject) {\n var queue = ReactSharedInternals.actQueue;\n if (null !== queue)\n if (0 !== queue.length)\n try {\n flushActQueue(queue);\n enqueueTask(function () {\n return recursivelyFlushAsyncActWork(returnValue, resolve, reject);\n });\n return;\n } catch (error) {\n ReactSharedInternals.thrownErrors.push(error);\n }\n else ReactSharedInternals.actQueue = null;\n 0 < ReactSharedInternals.thrownErrors.length\n ? ((queue = aggregateErrors(ReactSharedInternals.thrownErrors)),\n (ReactSharedInternals.thrownErrors.length = 0),\n reject(queue))\n : resolve(returnValue);\n }\n function flushActQueue(queue) {\n if (!isFlushing) {\n isFlushing = !0;\n var i = 0;\n try {\n for (; i < queue.length; i++) {\n var callback = queue[i];\n do {\n ReactSharedInternals.didUsePromise = !1;\n var continuation = callback(!1);\n if (null !== continuation) {\n if (ReactSharedInternals.didUsePromise) {\n queue[i] = callback;\n queue.splice(0, i);\n return;\n }\n callback = continuation;\n } else break;\n } while (1);\n }\n queue.length = 0;\n } catch (error) {\n queue.splice(0, i + 1), ReactSharedInternals.thrownErrors.push(error);\n } finally {\n isFlushing = !1;\n }\n }\n }\n \"undefined\" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&\n \"function\" ===\n typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart &&\n __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());\n var REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\"),\n REACT_STRICT_MODE_TYPE = Symbol.for(\"react.strict_mode\"),\n REACT_PROFILER_TYPE = Symbol.for(\"react.profiler\"),\n REACT_CONSUMER_TYPE = Symbol.for(\"react.consumer\"),\n REACT_CONTEXT_TYPE = Symbol.for(\"react.context\"),\n REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\"),\n REACT_SUSPENSE_TYPE = Symbol.for(\"react.suspense\"),\n REACT_SUSPENSE_LIST_TYPE = Symbol.for(\"react.suspense_list\"),\n REACT_MEMO_TYPE = Symbol.for(\"react.memo\"),\n REACT_LAZY_TYPE = Symbol.for(\"react.lazy\"),\n REACT_ACTIVITY_TYPE = Symbol.for(\"react.activity\"),\n MAYBE_ITERATOR_SYMBOL = Symbol.iterator,\n didWarnStateUpdateForUnmountedComponent = {},\n ReactNoopUpdateQueue = {\n isMounted: function () {\n return !1;\n },\n enqueueForceUpdate: function (publicInstance) {\n warnNoop(publicInstance, \"forceUpdate\");\n },\n enqueueReplaceState: function (publicInstance) {\n warnNoop(publicInstance, \"replaceState\");\n },\n enqueueSetState: function (publicInstance) {\n warnNoop(publicInstance, \"setState\");\n }\n },\n assign = Object.assign,\n emptyObject = {};\n Object.freeze(emptyObject);\n Component.prototype.isReactComponent = {};\n Component.prototype.setState = function (partialState, callback) {\n if (\n \"object\" !== typeof partialState &&\n \"function\" !== typeof partialState &&\n null != partialState\n )\n throw Error(\n \"takes an object of state variables to update or a function which returns an object of state variables.\"\n );\n this.updater.enqueueSetState(this, partialState, callback, \"setState\");\n };\n Component.prototype.forceUpdate = function (callback) {\n this.updater.enqueueForceUpdate(this, callback, \"forceUpdate\");\n };\n var deprecatedAPIs = {\n isMounted: [\n \"isMounted\",\n \"Instead, make sure to clean up subscriptions and pending requests in componentWillUnmount to prevent memory leaks.\"\n ],\n replaceState: [\n \"replaceState\",\n \"Refactor your code to use setState instead (see https://github.com/facebook/react/issues/3236).\"\n ]\n };\n for (fnName in deprecatedAPIs)\n deprecatedAPIs.hasOwnProperty(fnName) &&\n defineDeprecationWarning(fnName, deprecatedAPIs[fnName]);\n ComponentDummy.prototype = Component.prototype;\n deprecatedAPIs = PureComponent.prototype = new ComponentDummy();\n deprecatedAPIs.constructor = PureComponent;\n assign(deprecatedAPIs, Component.prototype);\n deprecatedAPIs.isPureReactComponent = !0;\n var isArrayImpl = Array.isArray,\n REACT_CLIENT_REFERENCE = Symbol.for(\"react.client.reference\"),\n ReactSharedInternals = {\n H: null,\n A: null,\n T: null,\n S: null,\n actQueue: null,\n asyncTransitions: 0,\n isBatchingLegacy: !1,\n didScheduleLegacyUpdate: !1,\n didUsePromise: !1,\n thrownErrors: [],\n getCurrentStack: null,\n recentlyCreatedOwnerStacks: 0\n },\n hasOwnProperty = Object.prototype.hasOwnProperty,\n createTask = console.createTask\n ? console.createTask\n : function () {\n return null;\n };\n deprecatedAPIs = {\n react_stack_bottom_frame: function (callStackForError) {\n return callStackForError();\n }\n };\n var specialPropKeyWarningShown, didWarnAboutOldJSXRuntime;\n var didWarnAboutElementRef = {};\n var unknownOwnerDebugStack = deprecatedAPIs.react_stack_bottom_frame.bind(\n deprecatedAPIs,\n UnknownOwner\n )();\n var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));\n var didWarnAboutMaps = !1,\n userProvidedKeyEscapeRegex = /\\/+/g,\n reportGlobalError =\n \"function\" === typeof reportError\n ? reportError\n : function (error) {\n if (\n \"object\" === typeof window &&\n \"function\" === typeof window.ErrorEvent\n ) {\n var event = new window.ErrorEvent(\"error\", {\n bubbles: !0,\n cancelable: !0,\n message:\n \"object\" === typeof error &&\n null !== error &&\n \"string\" === typeof error.message\n ? String(error.message)\n : String(error),\n error: error\n });\n if (!window.dispatchEvent(event)) return;\n } else if (\n \"object\" === typeof process &&\n \"function\" === typeof process.emit\n ) {\n process.emit(\"uncaughtException\", error);\n return;\n }\n console.error(error);\n },\n didWarnAboutMessageChannel = !1,\n enqueueTaskImpl = null,\n actScopeDepth = 0,\n didWarnNoAwaitAct = !1,\n isFlushing = !1,\n queueSeveralMicrotasks =\n \"function\" === typeof queueMicrotask\n ? function (callback) {\n queueMicrotask(function () {\n return queueMicrotask(callback);\n });\n }\n : enqueueTask;\n deprecatedAPIs = Object.freeze({\n __proto__: null,\n c: function (size) {\n return resolveDispatcher().useMemoCache(size);\n }\n });\n var fnName = {\n map: mapChildren,\n forEach: function (children, forEachFunc, forEachContext) {\n mapChildren(\n children,\n function () {\n forEachFunc.apply(this, arguments);\n },\n forEachContext\n );\n },\n count: function (children) {\n var n = 0;\n mapChildren(children, function () {\n n++;\n });\n return n;\n },\n toArray: function (children) {\n return (\n mapChildren(children, function (child) {\n return child;\n }) || []\n );\n },\n only: function (children) {\n if (!isValidElement(children))\n throw Error(\n \"React.Children.only expected to receive a single React element child.\"\n );\n return children;\n }\n };\n exports.Activity = REACT_ACTIVITY_TYPE;\n exports.Children = fnName;\n exports.Component = Component;\n exports.Fragment = REACT_FRAGMENT_TYPE;\n exports.Profiler = REACT_PROFILER_TYPE;\n exports.PureComponent = PureComponent;\n exports.StrictMode = REACT_STRICT_MODE_TYPE;\n exports.Suspense = REACT_SUSPENSE_TYPE;\n exports.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE =\n ReactSharedInternals;\n exports.__COMPILER_RUNTIME = deprecatedAPIs;\n exports.act = function (callback) {\n var prevActQueue = ReactSharedInternals.actQueue,\n prevActScopeDepth = actScopeDepth;\n actScopeDepth++;\n var queue = (ReactSharedInternals.actQueue =\n null !== prevActQueue ? prevActQueue : []),\n didAwaitActCall = !1;\n try {\n var result = callback();\n } catch (error) {\n ReactSharedInternals.thrownErrors.push(error);\n }\n if (0 < ReactSharedInternals.thrownErrors.length)\n throw (\n (popActScope(prevActQueue, prevActScopeDepth),\n (callback = aggregateErrors(ReactSharedInternals.thrownErrors)),\n (ReactSharedInternals.thrownErrors.length = 0),\n callback)\n );\n if (\n null !== result &&\n \"object\" === typeof result &&\n \"function\" === typeof result.then\n ) {\n var thenable = result;\n queueSeveralMicrotasks(function () {\n didAwaitActCall ||\n didWarnNoAwaitAct ||\n ((didWarnNoAwaitAct = !0),\n console.error(\n \"You called act(async () => ...) without await. This could lead to unexpected testing behaviour, interleaving multiple act calls and mixing their scopes. You should - await act(async () => ...);\"\n ));\n });\n return {\n then: function (resolve, reject) {\n didAwaitActCall = !0;\n thenable.then(\n function (returnValue) {\n popActScope(prevActQueue, prevActScopeDepth);\n if (0 === prevActScopeDepth) {\n try {\n flushActQueue(queue),\n enqueueTask(function () {\n return recursivelyFlushAsyncActWork(\n returnValue,\n resolve,\n reject\n );\n });\n } catch (error$0) {\n ReactSharedInternals.thrownErrors.push(error$0);\n }\n if (0 < ReactSharedInternals.thrownErrors.length) {\n var _thrownError = aggregateErrors(\n ReactSharedInternals.thrownErrors\n );\n ReactSharedInternals.thrownErrors.length = 0;\n reject(_thrownError);\n }\n } else resolve(returnValue);\n },\n function (error) {\n popActScope(prevActQueue, prevActScopeDepth);\n 0 < ReactSharedInternals.thrownErrors.length\n ? ((error = aggregateErrors(\n ReactSharedInternals.thrownErrors\n )),\n (ReactSharedInternals.thrownErrors.length = 0),\n reject(error))\n : reject(error);\n }\n );\n }\n };\n }\n var returnValue$jscomp$0 = result;\n popActScope(prevActQueue, prevActScopeDepth);\n 0 === prevActScopeDepth &&\n (flushActQueue(queue),\n 0 !== queue.length &&\n queueSeveralMicrotasks(function () {\n didAwaitActCall ||\n didWarnNoAwaitAct ||\n ((didWarnNoAwaitAct = !0),\n console.error(\n \"A component suspended inside an `act` scope, but the `act` call was not awaited. When testing React components that depend on asynchronous data, you must await the result:\\n\\nawait act(() => ...)\"\n ));\n }),\n (ReactSharedInternals.actQueue = null));\n if (0 < ReactSharedInternals.thrownErrors.length)\n throw (\n ((callback = aggregateErrors(ReactSharedInternals.thrownErrors)),\n (ReactSharedInternals.thrownErrors.length = 0),\n callback)\n );\n return {\n then: function (resolve, reject) {\n didAwaitActCall = !0;\n 0 === prevActScopeDepth\n ? ((ReactSharedInternals.actQueue = queue),\n enqueueTask(function () {\n return recursivelyFlushAsyncActWork(\n returnValue$jscomp$0,\n resolve,\n reject\n );\n }))\n : resolve(returnValue$jscomp$0);\n }\n };\n };\n exports.cache = function (fn) {\n return function () {\n return fn.apply(null, arguments);\n };\n };\n exports.cacheSignal = function () {\n return null;\n };\n exports.captureOwnerStack = function () {\n var getCurrentStack = ReactSharedInternals.getCurrentStack;\n return null === getCurrentStack ? null : getCurrentStack();\n };\n exports.cloneElement = function (element, config, children) {\n if (null === element || void 0 === element)\n throw Error(\n \"The argument must be a React element, but you passed \" +\n element +\n \".\"\n );\n var props = assign({}, element.props),\n key = element.key,\n owner = element._owner;\n if (null != config) {\n var JSCompiler_inline_result;\n a: {\n if (\n hasOwnProperty.call(config, \"ref\") &&\n (JSCompiler_inline_result = Object.getOwnPropertyDescriptor(\n config,\n \"ref\"\n ).get) &&\n JSCompiler_inline_result.isReactWarning\n ) {\n JSCompiler_inline_result = !1;\n break a;\n }\n JSCompiler_inline_result = void 0 !== config.ref;\n }\n JSCompiler_inline_result && (owner = getOwner());\n hasValidKey(config) &&\n (checkKeyStringCoercion(config.key), (key = \"\" + config.key));\n for (propName in config)\n !hasOwnProperty.call(config, propName) ||\n \"key\" === propName ||\n \"__self\" === propName ||\n \"__source\" === propName ||\n (\"ref\" === propName && void 0 === config.ref) ||\n (props[propName] = config[propName]);\n }\n var propName = arguments.length - 2;\n if (1 === propName) props.children = children;\n else if (1 < propName) {\n JSCompiler_inline_result = Array(propName);\n for (var i = 0; i < propName; i++)\n JSCompiler_inline_result[i] = arguments[i + 2];\n props.children = JSCompiler_inline_result;\n }\n props = ReactElement(\n element.type,\n key,\n props,\n owner,\n element._debugStack,\n element._debugTask\n );\n for (key = 2; key < arguments.length; key++)\n validateChildKeys(arguments[key]);\n return props;\n };\n exports.createContext = function (defaultValue) {\n defaultValue = {\n $$typeof: REACT_CONTEXT_TYPE,\n _currentValue: defaultValue,\n _currentValue2: defaultValue,\n _threadCount: 0,\n Provider: null,\n Consumer: null\n };\n defaultValue.Provider = defaultValue;\n defaultValue.Consumer = {\n $$typeof: REACT_CONSUMER_TYPE,\n _context: defaultValue\n };\n defaultValue._currentRenderer = null;\n defaultValue._currentRenderer2 = null;\n return defaultValue;\n };\n exports.createElement = function (type, config, children) {\n for (var i = 2; i < arguments.length; i++)\n validateChildKeys(arguments[i]);\n i = {};\n var key = null;\n if (null != config)\n for (propName in (didWarnAboutOldJSXRuntime ||\n !(\"__self\" in config) ||\n \"key\" in config ||\n ((didWarnAboutOldJSXRuntime = !0),\n console.warn(\n \"Your app (or one of its dependencies) is using an outdated JSX transform. Update to the modern JSX transform for faster performance: https://react.dev/link/new-jsx-transform\"\n )),\n hasValidKey(config) &&\n (checkKeyStringCoercion(config.key), (key = \"\" + config.key)),\n config))\n hasOwnProperty.call(config, propName) &&\n \"key\" !== propName &&\n \"__self\" !== propName &&\n \"__source\" !== propName &&\n (i[propName] = config[propName]);\n var childrenLength = arguments.length - 2;\n if (1 === childrenLength) i.children = children;\n else if (1 < childrenLength) {\n for (\n var childArray = Array(childrenLength), _i = 0;\n _i < childrenLength;\n _i++\n )\n childArray[_i] = arguments[_i + 2];\n Object.freeze && Object.freeze(childArray);\n i.children = childArray;\n }\n if (type && type.defaultProps)\n for (propName in ((childrenLength = type.defaultProps), childrenLength))\n void 0 === i[propName] && (i[propName] = childrenLength[propName]);\n key &&\n defineKeyPropWarningGetter(\n i,\n \"function\" === typeof type\n ? type.displayName || type.name || \"Unknown\"\n : type\n );\n var propName = 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return ReactElement(\n type,\n key,\n i,\n getOwner(),\n propName ? Error(\"react-stack-top-frame\") : unknownOwnerDebugStack,\n propName ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n exports.createRef = function () {\n var refObject = { current: null };\n Object.seal(refObject);\n return refObject;\n };\n exports.forwardRef = function (render) {\n null != render && render.$$typeof === REACT_MEMO_TYPE\n ? console.error(\n \"forwardRef requires a render function but received a `memo` component. Instead of forwardRef(memo(...)), use memo(forwardRef(...)).\"\n )\n : \"function\" !== typeof render\n ? console.error(\n \"forwardRef requires a render function but was given %s.\",\n null === render ? \"null\" : typeof render\n )\n : 0 !== render.length &&\n 2 !== render.length &&\n console.error(\n \"forwardRef render functions accept exactly two parameters: props and ref. %s\",\n 1 === render.length\n ? \"Did you forget to use the ref parameter?\"\n : \"Any additional parameter will be undefined.\"\n );\n null != render &&\n null != render.defaultProps &&\n console.error(\n \"forwardRef render functions do not support defaultProps. Did you accidentally pass a React component?\"\n );\n var elementType = { $$typeof: REACT_FORWARD_REF_TYPE, render: render },\n ownName;\n Object.defineProperty(elementType, \"displayName\", {\n enumerable: !1,\n configurable: !0,\n get: function () {\n return ownName;\n },\n set: function (name) {\n ownName = name;\n render.name ||\n render.displayName ||\n (Object.defineProperty(render, \"name\", { value: name }),\n (render.displayName = name));\n }\n });\n return elementType;\n };\n exports.isValidElement = isValidElement;\n exports.lazy = function (ctor) {\n ctor = { _status: -1, _result: ctor };\n var lazyType = {\n $$typeof: REACT_LAZY_TYPE,\n _payload: ctor,\n _init: lazyInitializer\n },\n ioInfo = {\n name: \"lazy\",\n start: -1,\n end: -1,\n value: null,\n owner: null,\n debugStack: Error(\"react-stack-top-frame\"),\n debugTask: console.createTask ? console.createTask(\"lazy()\") : null\n };\n ctor._ioInfo = ioInfo;\n lazyType._debugInfo = [{ awaited: ioInfo }];\n return lazyType;\n };\n exports.memo = function (type, compare) {\n null == type &&\n console.error(\n \"memo: The first argument must be a component. Instead received: %s\",\n null === type ? \"null\" : typeof type\n );\n compare = {\n $$typeof: REACT_MEMO_TYPE,\n type: type,\n compare: void 0 === compare ? null : compare\n };\n var ownName;\n Object.defineProperty(compare, \"displayName\", {\n enumerable: !1,\n configurable: !0,\n get: function () {\n return ownName;\n },\n set: function (name) {\n ownName = name;\n type.name ||\n type.displayName ||\n (Object.defineProperty(type, \"name\", { value: name }),\n (type.displayName = name));\n }\n });\n return compare;\n };\n exports.startTransition = function (scope) {\n var prevTransition = ReactSharedInternals.T,\n currentTransition = {};\n currentTransition._updatedFibers = new Set();\n ReactSharedInternals.T = currentTransition;\n try {\n var returnValue = scope(),\n onStartTransitionFinish = ReactSharedInternals.S;\n null !== onStartTransitionFinish &&\n onStartTransitionFinish(currentTransition, returnValue);\n \"object\" === typeof returnValue &&\n null !== returnValue &&\n \"function\" === typeof returnValue.then &&\n (ReactSharedInternals.asyncTransitions++,\n returnValue.then(releaseAsyncTransition, releaseAsyncTransition),\n returnValue.then(noop, reportGlobalError));\n } catch (error) {\n reportGlobalError(error);\n } finally {\n null === prevTransition &&\n currentTransition._updatedFibers &&\n ((scope = currentTransition._updatedFibers.size),\n currentTransition._updatedFibers.clear(),\n 10 < scope &&\n console.warn(\n \"Detected a large number of updates inside startTransition. If this is due to a subscription please re-write it to use React provided hooks. Otherwise concurrent mode guarantees are off the table.\"\n )),\n null !== prevTransition &&\n null !== currentTransition.types &&\n (null !== prevTransition.types &&\n prevTransition.types !== currentTransition.types &&\n console.error(\n \"We expected inner Transitions to have transferred the outer types set and that you cannot add to the outer Transition while inside the inner.This is a bug in React.\"\n ),\n (prevTransition.types = currentTransition.types)),\n (ReactSharedInternals.T = prevTransition);\n }\n };\n exports.unstable_useCacheRefresh = function () {\n return resolveDispatcher().useCacheRefresh();\n };\n exports.use = function (usable) {\n return resolveDispatcher().use(usable);\n };\n exports.useActionState = function (action, initialState, permalink) {\n return resolveDispatcher().useActionState(\n action,\n initialState,\n permalink\n );\n };\n exports.useCallback = function (callback, deps) {\n return resolveDispatcher().useCallback(callback, deps);\n };\n exports.useContext = function (Context) {\n var dispatcher = resolveDispatcher();\n Context.$$typeof === REACT_CONSUMER_TYPE &&\n console.error(\n \"Calling useContext(Context.Consumer) is not supported and will cause bugs. Did you mean to call useContext(Context) instead?\"\n );\n return dispatcher.useContext(Context);\n };\n exports.useDebugValue = function (value, formatterFn) {\n return resolveDispatcher().useDebugValue(value, formatterFn);\n };\n exports.useDeferredValue = function (value, initialValue) {\n return resolveDispatcher().useDeferredValue(value, initialValue);\n };\n exports.useEffect = function (create, deps) {\n null == create &&\n console.warn(\n \"React Hook useEffect requires an effect callback. Did you forget to pass a callback to the hook?\"\n );\n return resolveDispatcher().useEffect(create, deps);\n };\n exports.useEffectEvent = function (callback) {\n return resolveDispatcher().useEffectEvent(callback);\n };\n exports.useId = function () {\n return resolveDispatcher().useId();\n };\n exports.useImperativeHandle = function (ref, create, deps) {\n return resolveDispatcher().useImperativeHandle(ref, create, deps);\n };\n exports.useInsertionEffect = function (create, deps) {\n null == create &&\n console.warn(\n \"React Hook useInsertionEffect requires an effect callback. Did you forget to pass a callback to the hook?\"\n );\n return resolveDispatcher().useInsertionEffect(create, deps);\n };\n exports.useLayoutEffect = function (create, deps) {\n null == create &&\n console.warn(\n \"React Hook useLayoutEffect requires an effect callback. Did you forget to pass a callback to the hook?\"\n );\n return resolveDispatcher().useLayoutEffect(create, deps);\n };\n exports.useMemo = function (create, deps) {\n return resolveDispatcher().useMemo(create, deps);\n };\n exports.useOptimistic = function (passthrough, reducer) {\n return resolveDispatcher().useOptimistic(passthrough, reducer);\n };\n exports.useReducer = function (reducer, initialArg, init) {\n return resolveDispatcher().useReducer(reducer, initialArg, init);\n };\n exports.useRef = function (initialValue) {\n return resolveDispatcher().useRef(initialValue);\n };\n exports.useState = function (initialState) {\n return resolveDispatcher().useState(initialState);\n };\n exports.useSyncExternalStore = function (\n subscribe,\n getSnapshot,\n getServerSnapshot\n ) {\n return resolveDispatcher().useSyncExternalStore(\n subscribe,\n getSnapshot,\n getServerSnapshot\n );\n };\n exports.useTransition = function () {\n return resolveDispatcher().useTransition();\n };\n exports.version = \"19.2.4\";\n \"undefined\" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&\n \"function\" ===\n typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&\n __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());\n })();\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react.production.js');\n} else {\n module.exports = require('./cjs/react.development.js');\n}\n","/**\n * @license React\n * react-jsx-runtime.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\");\nfunction jsxProd(type, config, maybeKey) {\n var key = null;\n void 0 !== maybeKey && (key = \"\" + maybeKey);\n void 0 !== config.key && (key = \"\" + config.key);\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n config = maybeKey.ref;\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n ref: void 0 !== config ? config : null,\n props: maybeKey\n };\n}\nexports.Fragment = REACT_FRAGMENT_TYPE;\nexports.jsx = jsxProd;\nexports.jsxs = jsxProd;\n","/**\n * @license React\n * react-jsx-runtime.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n (function () {\n function getComponentNameFromType(type) {\n if (null == type) return null;\n if (\"function\" === typeof type)\n return type.$$typeof === REACT_CLIENT_REFERENCE\n ? null\n : type.displayName || type.name || null;\n if (\"string\" === typeof type) return type;\n switch (type) {\n case REACT_FRAGMENT_TYPE:\n return \"Fragment\";\n case REACT_PROFILER_TYPE:\n return \"Profiler\";\n case REACT_STRICT_MODE_TYPE:\n return \"StrictMode\";\n case REACT_SUSPENSE_TYPE:\n return \"Suspense\";\n case REACT_SUSPENSE_LIST_TYPE:\n return \"SuspenseList\";\n case REACT_ACTIVITY_TYPE:\n return \"Activity\";\n }\n if (\"object\" === typeof type)\n switch (\n (\"number\" === typeof type.tag &&\n console.error(\n \"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.\"\n ),\n type.$$typeof)\n ) {\n case REACT_PORTAL_TYPE:\n return \"Portal\";\n case REACT_CONTEXT_TYPE:\n return type.displayName || \"Context\";\n case REACT_CONSUMER_TYPE:\n return (type._context.displayName || \"Context\") + \".Consumer\";\n case REACT_FORWARD_REF_TYPE:\n var innerType = type.render;\n type = type.displayName;\n type ||\n ((type = innerType.displayName || innerType.name || \"\"),\n (type = \"\" !== type ? \"ForwardRef(\" + type + \")\" : \"ForwardRef\"));\n return type;\n case REACT_MEMO_TYPE:\n return (\n (innerType = type.displayName || null),\n null !== innerType\n ? innerType\n : getComponentNameFromType(type.type) || \"Memo\"\n );\n case REACT_LAZY_TYPE:\n innerType = type._payload;\n type = type._init;\n try {\n return getComponentNameFromType(type(innerType));\n } catch (x) {}\n }\n return null;\n }\n function testStringCoercion(value) {\n return \"\" + value;\n }\n function checkKeyStringCoercion(value) {\n try {\n testStringCoercion(value);\n var JSCompiler_inline_result = !1;\n } catch (e) {\n JSCompiler_inline_result = !0;\n }\n if (JSCompiler_inline_result) {\n JSCompiler_inline_result = console;\n var JSCompiler_temp_const = JSCompiler_inline_result.error;\n var JSCompiler_inline_result$jscomp$0 =\n (\"function\" === typeof Symbol &&\n Symbol.toStringTag &&\n value[Symbol.toStringTag]) ||\n value.constructor.name ||\n \"Object\";\n JSCompiler_temp_const.call(\n JSCompiler_inline_result,\n \"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.\",\n JSCompiler_inline_result$jscomp$0\n );\n return testStringCoercion(value);\n }\n }\n function getTaskName(type) {\n if (type === REACT_FRAGMENT_TYPE) return \"<>\";\n if (\n \"object\" === typeof type &&\n null !== type &&\n type.$$typeof === REACT_LAZY_TYPE\n )\n return \"<...>\";\n try {\n var name = getComponentNameFromType(type);\n return name ? \"<\" + name + \">\" : \"<...>\";\n } catch (x) {\n return \"<...>\";\n }\n }\n function getOwner() {\n var dispatcher = ReactSharedInternals.A;\n return null === dispatcher ? null : dispatcher.getOwner();\n }\n function UnknownOwner() {\n return Error(\"react-stack-top-frame\");\n }\n function hasValidKey(config) {\n if (hasOwnProperty.call(config, \"key\")) {\n var getter = Object.getOwnPropertyDescriptor(config, \"key\").get;\n if (getter && getter.isReactWarning) return !1;\n }\n return void 0 !== config.key;\n }\n function defineKeyPropWarningGetter(props, displayName) {\n function warnAboutAccessingKey() {\n specialPropKeyWarningShown ||\n ((specialPropKeyWarningShown = !0),\n console.error(\n \"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)\",\n displayName\n ));\n }\n warnAboutAccessingKey.isReactWarning = !0;\n Object.defineProperty(props, \"key\", {\n get: warnAboutAccessingKey,\n configurable: !0\n });\n }\n function elementRefGetterWithDeprecationWarning() {\n var componentName = getComponentNameFromType(this.type);\n didWarnAboutElementRef[componentName] ||\n ((didWarnAboutElementRef[componentName] = !0),\n console.error(\n \"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.\"\n ));\n componentName = this.props.ref;\n return void 0 !== componentName ? componentName : null;\n }\n function ReactElement(type, key, props, owner, debugStack, debugTask) {\n var refProp = props.ref;\n type = {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n props: props,\n _owner: owner\n };\n null !== (void 0 !== refProp ? refProp : null)\n ? Object.defineProperty(type, \"ref\", {\n enumerable: !1,\n get: elementRefGetterWithDeprecationWarning\n })\n : Object.defineProperty(type, \"ref\", { enumerable: !1, value: null });\n type._store = {};\n Object.defineProperty(type._store, \"validated\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: 0\n });\n Object.defineProperty(type, \"_debugInfo\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: null\n });\n Object.defineProperty(type, \"_debugStack\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugStack\n });\n Object.defineProperty(type, \"_debugTask\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugTask\n });\n Object.freeze && (Object.freeze(type.props), Object.freeze(type));\n return type;\n }\n function jsxDEVImpl(\n type,\n config,\n maybeKey,\n isStaticChildren,\n debugStack,\n debugTask\n ) {\n var children = config.children;\n if (void 0 !== children)\n if (isStaticChildren)\n if (isArrayImpl(children)) {\n for (\n isStaticChildren = 0;\n isStaticChildren < children.length;\n isStaticChildren++\n )\n validateChildKeys(children[isStaticChildren]);\n Object.freeze && Object.freeze(children);\n } else\n console.error(\n \"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.\"\n );\n else validateChildKeys(children);\n if (hasOwnProperty.call(config, \"key\")) {\n children = getComponentNameFromType(type);\n var keys = Object.keys(config).filter(function (k) {\n return \"key\" !== k;\n });\n isStaticChildren =\n 0 < keys.length\n ? \"{key: someKey, \" + keys.join(\": ..., \") + \": ...}\"\n : \"{key: someKey}\";\n didWarnAboutKeySpread[children + isStaticChildren] ||\n ((keys =\n 0 < keys.length ? \"{\" + keys.join(\": ..., \") + \": ...}\" : \"{}\"),\n console.error(\n 'A props object containing a \"key\" prop is being spread into JSX:\\n let props = %s;\\n <%s {...props} />\\nReact keys must be passed directly to JSX without using spread:\\n let props = %s;\\n <%s key={someKey} {...props} />',\n isStaticChildren,\n children,\n keys,\n children\n ),\n (didWarnAboutKeySpread[children + isStaticChildren] = !0));\n }\n children = null;\n void 0 !== maybeKey &&\n (checkKeyStringCoercion(maybeKey), (children = \"\" + maybeKey));\n hasValidKey(config) &&\n (checkKeyStringCoercion(config.key), (children = \"\" + config.key));\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n children &&\n defineKeyPropWarningGetter(\n maybeKey,\n \"function\" === typeof type\n ? type.displayName || type.name || \"Unknown\"\n : type\n );\n return ReactElement(\n type,\n children,\n maybeKey,\n getOwner(),\n debugStack,\n debugTask\n );\n }\n function validateChildKeys(node) {\n isValidElement(node)\n ? node._store && (node._store.validated = 1)\n : \"object\" === typeof node &&\n null !== node &&\n node.$$typeof === REACT_LAZY_TYPE &&\n (\"fulfilled\" === node._payload.status\n ? isValidElement(node._payload.value) &&\n node._payload.value._store &&\n (node._payload.value._store.validated = 1)\n : node._store && (node._store.validated = 1));\n }\n function isValidElement(object) {\n return (\n \"object\" === typeof object &&\n null !== object &&\n object.$$typeof === REACT_ELEMENT_TYPE\n );\n }\n var React = require(\"react\"),\n REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\"),\n REACT_STRICT_MODE_TYPE = Symbol.for(\"react.strict_mode\"),\n REACT_PROFILER_TYPE = Symbol.for(\"react.profiler\"),\n REACT_CONSUMER_TYPE = Symbol.for(\"react.consumer\"),\n REACT_CONTEXT_TYPE = Symbol.for(\"react.context\"),\n REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\"),\n REACT_SUSPENSE_TYPE = Symbol.for(\"react.suspense\"),\n REACT_SUSPENSE_LIST_TYPE = Symbol.for(\"react.suspense_list\"),\n REACT_MEMO_TYPE = Symbol.for(\"react.memo\"),\n REACT_LAZY_TYPE = Symbol.for(\"react.lazy\"),\n REACT_ACTIVITY_TYPE = Symbol.for(\"react.activity\"),\n REACT_CLIENT_REFERENCE = Symbol.for(\"react.client.reference\"),\n ReactSharedInternals =\n React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,\n hasOwnProperty = Object.prototype.hasOwnProperty,\n isArrayImpl = Array.isArray,\n createTask = console.createTask\n ? console.createTask\n : function () {\n return null;\n };\n React = {\n react_stack_bottom_frame: function (callStackForError) {\n return callStackForError();\n }\n };\n var specialPropKeyWarningShown;\n var didWarnAboutElementRef = {};\n var unknownOwnerDebugStack = React.react_stack_bottom_frame.bind(\n React,\n UnknownOwner\n )();\n var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));\n var didWarnAboutKeySpread = {};\n exports.Fragment = REACT_FRAGMENT_TYPE;\n exports.jsx = function (type, config, maybeKey) {\n var trackActualOwner =\n 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return jsxDEVImpl(\n type,\n config,\n maybeKey,\n !1,\n trackActualOwner\n ? Error(\"react-stack-top-frame\")\n : unknownOwnerDebugStack,\n trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n exports.jsxs = function (type, config, maybeKey) {\n var trackActualOwner =\n 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return jsxDEVImpl(\n type,\n config,\n maybeKey,\n !0,\n trackActualOwner\n ? Error(\"react-stack-top-frame\")\n : unknownOwnerDebugStack,\n trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n })();\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-jsx-runtime.production.js');\n} else {\n module.exports = require('./cjs/react-jsx-runtime.development.js');\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport PixodeskSvgAnimator from './PixodeskSvgAnimator';\nexport type { PixodeskSvgAnimatorCallbacks, PixodeskSvgAnimatorProps, ReactAnimatorApi } from './PixodeskSvgAnimator';\nexport { PixodeskSvgAnimator };\n\nimport PixodeskSvgCssAnimator from './PixodeskSvgCssAnimator';\nexport { PixodeskSvgCssAnimator };\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n/**\n * Lightweight Zod-like schema system — type declaration + runtime sanitization.\n *\n * Two operations per schema:\n * isValid(raw) — true only when raw already conforms; no repair needed.\n * sanitize(raw) — always returns T; fixes or replaces invalid input with defaults.\n *\n * Field rules inside px.object():\n * required field → if absent/invalid, field's declared default is used.\n * optional field → if absent/invalid (or wrong JS type), field becomes undefined.\n *\n * Array: items that cannot even be attempted are filtered out.\n * Record: values that cannot even be attempted are dropped.\n *\n * The distinction between isValid and _canSanitize:\n * isValid — strict; ALL fields must be correct, no repairs accepted.\n * _canSanitize — permissive; \"is the JS type right enough to attempt repair?\"\n * For containers (object/array/record) this is a structural check\n * so that partially-valid nested objects are sanitized rather than dropped.\n * For primitives it equals isValid (a wrong primitive type is unrecoverable).\n *\n * Validation context (optional):\n * Pass a PxValidationContext as the second arg to isValid() to collect per-field\n * error and warning messages with their dot-paths.\n * e.g. schema.isValid(raw, ctx, []) where ctx = { errors: [], warnings: [] }\n * Path segments are pushed/popped during recursion; join with '.' only when reporting.\n */\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Public interfaces\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Collects structured validation feedback. Pass to isValid() as the second argument. */\nexport interface PxValidationContext {\n /** Per-field errors — each entry is \"<dot.path>: <reason>\". */\n errors: Array<string>;\n /** Per-field warnings — same format as errors but non-fatal. */\n warnings: Array<string>;\n /**\n * When true, closed objects (`px.object` / `px.extendedObject`) report any\n * extra (undeclared) keys as errors. Default `false` (or omitted) — extras\n * are ignored, matching `sanitize`'s strip-extras behaviour, which is what\n * production app code wants (forward-compat with unknown future fields).\n * Tests that want to lock the wire shape down to its declared schema\n * should pass `strict: true`.\n *\n * Open objects (`px.openObject`) are unaffected by `strict` — they accept\n * extras by design (used for SVG element nodes that carry arbitrary attrs).\n */\n strict?: boolean;\n}\n\nexport interface PxSchema<T, IsOptional extends boolean = false> {\n /** Phantom discriminator — `false` for required schemas, `true` for optional. Used by InferShape. */\n readonly _optional: IsOptional;\n sanitize(raw: unknown): T;\n /**\n * Returns true when raw already conforms to this schema.\n * Pass an optional PxValidationContext to collect per-field error messages.\n * Pass a mutable Array<string> as `path` — segments are pushed/popped during\n * recursion so only a single array allocation is needed per validation call.\n */\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean;\n /** True if raw has the right structure to attempt sanitization (may still need repair). */\n _canSanitize(raw: unknown): boolean;\n readonly _default: T;\n /** Returns a new schema that marks this field as optional (?: in object shapes). */\n optional(): PxSchema<T | undefined, true>;\n}\n\n/** Extract the TypeScript type from a schema. */\nexport type PxInfer<S> = S extends PxSchema<infer T, any> ? T : never;\n\n/**\n * Removes string/number index signatures from T, leaving only explicitly named properties.\n * Useful for strict property-access checking on types that have an open `[key: string]: any`.\n *\n * @example\n * type Strict = RemoveIndex<PxAnimatedSvgDocument>;\n * Strict['animator'] // PxAnimatorConfig | undefined ✓\n * Strict['anything'] // compile error ✓\n */\nexport type RemoveIndex<T> = {\n [K in keyof T as string extends K ? never : number extends K ? never : K]: T[K]\n};\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Internal path helper\n// ─────────────────────────────────────────────────────────────────────────────\n\n// Joins path segments into a dot-path string for error messages.\n// Segments starting with '[' are appended without a leading dot.\n// e.g. ['obj', 'key'] -> 'obj.key' ['arr', '[0]'] -> 'arr[0]' [] -> '.'\nfunction pathStr(path: Array<string>): string {\n if (!path.length) return '.';\n let result = '';\n for (const seg of path) {\n if (seg.startsWith('[')) result += seg;\n else result += (result ? '.' : '') + seg;\n }\n return result;\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Base — default _canSanitize = isValid (correct for primitives)\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Shared base; overrides _canSanitize only when the structural check must differ from isValid. */\nabstract class Base<T, IsOptional extends boolean = false> implements PxSchema<T, IsOptional> {\n // `declare` emits no runtime code; purely satisfies the interface's phantom _optional property.\n declare readonly _optional: IsOptional;\n abstract sanitize(raw: unknown): T;\n abstract isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean;\n abstract readonly _default: T;\n\n _canSanitize(raw: unknown): boolean { return this.isValid(raw); }\n\n optional(): PxSchema<T | undefined, true> { return new Optional(this); }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Optional wrapper\n// Uses _canSanitize (not isValid) so that partially-valid nested objects are\n// repaired rather than dropped entirely.\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Wraps any schema to make its value optional.\n * sanitize uses _canSanitize (not isValid) so partially-valid objects are repaired, not dropped.\n */\nclass Optional<T> extends Base<T | undefined, true> {\n readonly _default = undefined as T | undefined;\n constructor(private readonly inner: PxSchema<T, any>) { super(); }\n\n sanitize(raw: unknown): T | undefined {\n if (raw === undefined || raw === null) return undefined;\n return this.inner._canSanitize(raw) ? this.inner.sanitize(raw) : undefined;\n }\n\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n if (raw === undefined || raw === null) return true;\n return this.inner.isValid(raw, ctx, path);\n }\n\n override _canSanitize(raw: unknown): boolean {\n return raw === undefined || raw === null || this.inner._canSanitize(raw);\n }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Primitives — _canSanitize = isValid (a wrong primitive type is unrecoverable)\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** String schema; wrong type is unrecoverable so _canSanitize = isValid (inherited default). */\nclass Str extends Base<string> {\n constructor(readonly _default: string = '') { super(); }\n sanitize(raw: unknown): string { return typeof raw === 'string' ? raw : this._default; }\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n if (typeof raw === 'string') return true;\n ctx?.errors.push(pathStr(path ?? []) + ': expected string, got ' + typeof raw);\n return false;\n }\n}\n\n/** Finite-number schema; rejects NaN and ±Infinity as unrecoverable. */\nclass Num extends Base<number> {\n constructor(readonly _default: number = 0) { super(); }\n sanitize(raw: unknown): number {\n return typeof raw === 'number' && isFinite(raw) ? raw : this._default;\n }\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n if (typeof raw === 'number' && isFinite(raw)) return true;\n ctx?.errors.push(pathStr(path ?? []) + ': expected finite number, got ' + JSON.stringify(raw));\n return false;\n }\n}\n\n/** Boolean schema. */\nclass Bool extends Base<boolean> {\n constructor(readonly _default: boolean = false) { super(); }\n sanitize(raw: unknown): boolean { return typeof raw === 'boolean' ? raw : this._default; }\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n if (typeof raw === 'boolean') return true;\n ctx?.errors.push(pathStr(path ?? []) + ': expected boolean, got ' + typeof raw);\n return false;\n }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Literal — exact value match; default is the literal itself\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Matches one exact primitive value; its _default is the value itself. */\nclass Literal<T extends string | number | boolean> extends Base<T> {\n readonly _default: T;\n constructor(private readonly value: T) { super(); this._default = value; }\n sanitize(raw: unknown): T { return raw === this.value ? this.value : this._default; }\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n if (raw === this.value) return true;\n ctx?.errors.push(pathStr(path ?? []) + ': expected ' + JSON.stringify(this.value) + ', got ' + JSON.stringify(raw));\n return false;\n }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Enum — union of string/number literals; default is first value\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Union of string/number literals; _default is the first value unless overridden. */\nclass Enum<T extends string | number> extends Base<T> {\n readonly _default: T;\n constructor(private readonly values: readonly T[], defaultVal?: T) {\n super();\n this._default = defaultVal ?? values[0];\n }\n sanitize(raw: unknown): T { return this.values.includes(raw as T) ? (raw as T) : this._default; }\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n if (this.values.includes(raw as T)) return true;\n ctx?.errors.push(pathStr(path ?? []) + ': expected one of ' + this.values.map(v => JSON.stringify(v)).join(' | ') + ', got ' + JSON.stringify(raw));\n return false;\n }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Union — first matching schema wins\n// _canSanitize: true if any member can attempt sanitization\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Tries member schemas in order; first whose isValid passes wins. sanitize returns _default when none match. */\nclass Union<T> extends Base<T> {\n readonly _default: T;\n constructor(private readonly schemas: ReadonlyArray<PxSchema<T>>, defaultVal?: T) {\n super();\n this._default = defaultVal ?? schemas[0]._default;\n }\n sanitize(raw: unknown): T {\n for (const s of this.schemas) {\n if (s.isValid(raw)) return s.sanitize(raw);\n }\n return this._default;\n }\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n // Test members without ctx — avoids spurious errors from non-matching branches.\n if (this.schemas.some(s => s.isValid(raw))) return true;\n ctx?.errors.push(pathStr(path ?? []) + ': no union member matched for value ' + (JSON.stringify(raw) ?? '').slice(0, 60));\n return false;\n }\n override _canSanitize(raw: unknown): boolean { return this.schemas.some(s => s._canSanitize(raw)); }\n}\n\n// Infers the union of all member types from a tuple of schemas\ntype UnionMembers<T extends ReadonlyArray<PxSchema<any, any>>> =\n T extends ReadonlyArray<PxSchema<infer U, any>> ? U : never;\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// DiscriminatedUnion — routes by a literal key field, not first-match order\n// ─────────────────────────────────────────────────────────────────────────────\n\ntype AnyDiscriminantShape<K extends string> = Record<K, PxSchema<string | number | boolean, any>>;\n\n/**\n * Reads `raw[key]`, finds the member schema whose literal matches that value,\n * then delegates sanitize/isValid to that member. Falls back to the first\n * member for sanitize when no match is found.\n */\nclass DiscriminatedUnion<T> extends Base<T> {\n readonly _default: T;\n private readonly _map: Map<string | number | boolean, PxSchema<T>>;\n\n constructor(\n private readonly _key: string,\n private readonly _schemas: ReadonlyArray<PxSchema<T> & { readonly _shape: AnyDiscriminantShape<string> }>,\n defaultVal?: T\n ) {\n super();\n this._default = defaultVal ?? _schemas[0]._default;\n this._map = new Map();\n for (const s of _schemas) {\n const keySchema = s._shape[_key];\n if (keySchema) this._map.set(keySchema._default, s);\n }\n }\n\n private _findSchema(raw: unknown): PxSchema<T> | undefined {\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) return undefined;\n const val = (raw as Record<string, unknown>)[this._key];\n if (val === undefined || val === null) return undefined;\n return this._map.get(val as string | number | boolean);\n }\n\n sanitize(raw: unknown): T {\n return (this._findSchema(raw) ?? this._schemas[0]).sanitize(raw);\n }\n\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n const schema = this._findSchema(raw);\n if (!schema) {\n const val = (raw !== null && typeof raw === 'object' && !Array.isArray(raw))\n ? (raw as Record<string, unknown>)[this._key] : undefined;\n ctx?.errors.push(pathStr(path ?? []) + ': no discriminated union member matched '\n + this._key + '=' + JSON.stringify(val));\n return false;\n }\n return schema.isValid(raw, ctx, path);\n }\n\n override _canSanitize(raw: unknown): boolean {\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) return false;\n const schema = this._findSchema(raw);\n return schema ? schema._canSanitize(raw) : this._schemas[0]._canSanitize(raw);\n }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Object — strips unknown keys; required fields use default, optional → undefined\n// _canSanitize: true when raw is a plain (non-array) object\n// ─────────────────────────────────────────────────────────────────────────────\n\ntype AnyShape = Record<string, PxSchema<any, any>>;\n\n// Required keys: IsOptional=false → plain property.\n// Optional keys: IsOptional=true → ?:, with Exclude<T,undefined> (?: already adds undefined).\ntype InferShape<S extends AnyShape> =\n { [K in keyof S as S[K] extends PxSchema<any, true> ? never : K]: PxInfer<S[K]> } &\n { [K in keyof S as S[K] extends PxSchema<any, true> ? K : never]?: Exclude<PxInfer<S[K]>, undefined> };\n\n/**\n * Typed object schema; strips unknown keys, repairs required fields via their defaults.\n * _canSanitize checks structure only (non-array object) so partially-valid objects are repaired.\n */\nclass Obj<S extends AnyShape> extends Base<InferShape<S>> {\n readonly _default: InferShape<S>;\n\n constructor(readonly _shape: S) {\n super();\n const d: any = {};\n for (const key of Object.keys(_shape)) d[key] = _shape[key]._default;\n this._default = d;\n }\n\n sanitize(raw: unknown): InferShape<S> {\n const src = (raw && typeof raw === 'object' && !Array.isArray(raw)) ? raw as any : {};\n const out: any = {};\n for (const key of Object.keys(this._shape)) {\n out[key] = this._shape[key].sanitize(src[key]);\n }\n return out;\n }\n\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n ctx?.errors.push(pathStr(path ?? []) + ': expected object, got ' + (Array.isArray(raw) ? 'array' : typeof raw));\n return false;\n }\n const obj = raw as any;\n const p = path ?? [];\n let ok = true;\n for (const key of Object.keys(this._shape)) {\n p.push(key);\n if (!this._shape[key].isValid(obj[key], ctx, p)) ok = false;\n p.pop();\n }\n // Strict mode: closed objects reject extra (undeclared) keys.\n // Default mode silently ignores them (matching `sanitize`'s strip-extras).\n if (ctx?.strict) {\n for (const key of Object.keys(obj)) {\n if (key in this._shape) continue;\n p.push(key);\n ctx.errors.push(pathStr(p) + ': unexpected extra key');\n p.pop();\n ok = false;\n }\n }\n return ok;\n }\n\n override _canSanitize(raw: unknown): boolean {\n return !!raw && typeof raw === 'object' && !Array.isArray(raw);\n }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// OpenObj — like Obj but passes unknown keys through unchanged (or validates/sanitizes\n// them against an optional open-value schema).\n// Known keys are validated/sanitized; unknown keys are passed through as-is when no\n// open schema is given, or validated/sanitized against the open schema when one is provided.\n// Inferred type: InferShape<S> & { [key: string]: V } where V defaults to any.\n// Note: TypeScript intersection semantics mean named-property access on the\n// derived type yields `any` rather than the specific declared type. For\n// type-precise access keep a hand-written interface alongside the schema.\n// ─────────────────────────────────────────────────────────────────────────────\n\ntype InferOpenShape<S extends AnyShape, _V = any> = InferShape<S> & { [key: string]: any };\n\n/**\n * Open object schema; validates/repairs known keys, passes unknown keys through unchanged.\n * Use when the object may carry arbitrary extra properties (e.g. SVG element attributes).\n *\n * @param shape Known key schemas (validated and type-inferred).\n * @param openSchema Optional schema applied to every unknown key's value.\n * When omitted, unknown values are passed through as-is (`any`).\n */\nclass OpenObj<S extends AnyShape, V = any> extends Base<InferOpenShape<S, V>> {\n readonly _default: InferOpenShape<S, V>;\n\n constructor(readonly _shape: S, private readonly _openSchema?: PxSchema<V>) {\n super();\n const d: any = {};\n for (const key of Object.keys(_shape)) d[key] = _shape[key]._default;\n this._default = d;\n }\n\n sanitize(raw: unknown): InferOpenShape<S, V> {\n const src: Record<string, unknown> = (raw && typeof raw === 'object' && !Array.isArray(raw))\n ? raw as Record<string, unknown>\n : {};\n const out: Record<string, unknown> = { ...src };\n for (const key of Object.keys(this._shape)) {\n out[key] = this._shape[key].sanitize(src[key]);\n }\n if (this._openSchema) {\n for (const key of Object.keys(src)) {\n if (!(key in this._shape)) out[key] = this._openSchema.sanitize(src[key]);\n }\n }\n return out as InferOpenShape<S, V>;\n }\n\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n ctx?.errors.push(pathStr(path ?? []) + ': expected object, got ' + (Array.isArray(raw) ? 'array' : typeof raw));\n return false;\n }\n const obj = raw as any;\n const p = path ?? [];\n let ok = true;\n for (const key of Object.keys(this._shape)) {\n p.push(key);\n if (!this._shape[key].isValid(obj[key], ctx, p)) ok = false;\n p.pop();\n }\n if (this._openSchema) {\n for (const key of Object.keys(obj)) {\n if (key in this._shape) continue;\n p.push(key);\n if (!this._openSchema.isValid(obj[key], ctx, p)) ok = false;\n p.pop();\n }\n }\n return ok;\n }\n\n override _canSanitize(raw: unknown): boolean {\n return !!raw && typeof raw === 'object' && !Array.isArray(raw);\n }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Array — items that cannot be attempted are filtered out; default is []\n// Uses _canSanitize for filtering so partially-valid objects are repaired, not dropped.\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Array schema; items failing _canSanitize are filtered out rather than blocking the whole array. */\nclass Arr<T> extends Base<Array<T>> {\n readonly _default: Array<T> = [];\n constructor(private readonly item: PxSchema<T>) { super(); }\n\n sanitize(raw: unknown): Array<T> {\n if (!Array.isArray(raw)) return [];\n const out: Array<T> = [];\n for (const el of raw) {\n if (this.item._canSanitize(el)) out.push(this.item.sanitize(el));\n }\n return out;\n }\n\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n if (!Array.isArray(raw)) {\n ctx?.errors.push(pathStr(path ?? []) + ': expected array, got ' + typeof raw);\n return false;\n }\n const p = path ?? [];\n let ok = true;\n for (let i = 0; i < raw.length; i++) {\n p.push('[' + i + ']');\n if (!this.item.isValid(raw[i], ctx, p)) ok = false;\n p.pop();\n }\n return ok;\n }\n\n override _canSanitize(raw: unknown): boolean { return Array.isArray(raw); }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Record — invalid values are dropped; default is {}\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** String-keyed record; values failing _canSanitize are dropped rather than blocking the whole record. */\nclass Rec<T> extends Base<Record<string, T>> {\n readonly _default: Record<string, T> = {};\n constructor(private readonly value: PxSchema<T>) { super(); }\n\n sanitize(raw: unknown): Record<string, T> {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return {};\n const out: Record<string, T> = {};\n for (const [k, v] of Object.entries(raw)) {\n if (this.value._canSanitize(v)) out[k] = this.value.sanitize(v);\n }\n return out;\n }\n\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n ctx?.errors.push(pathStr(path ?? []) + ': expected object/record, got ' + (Array.isArray(raw) ? 'array' : typeof raw));\n return false;\n }\n const p = path ?? [];\n let ok = true;\n for (const [k, v] of Object.entries(raw as object)) {\n p.push(k);\n if (!this.value.isValid(v, ctx, p)) ok = false;\n p.pop();\n }\n return ok;\n }\n\n override _canSanitize(raw: unknown): boolean {\n return !!raw && typeof raw === 'object' && !Array.isArray(raw);\n }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Any — passes raw through unchanged, always valid\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Passes any value through unchanged; always valid. Useful for opaque blobs with no schema. */\nclass Any extends Base<any> {\n readonly _default: any = undefined;\n sanitize(raw: unknown): any { return raw; }\n isValid(_raw: unknown, _ctx?: PxValidationContext, _path?: Array<string>): boolean { return true; }\n override _canSanitize(_raw: unknown): boolean { return true; }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Lazy — resolves schema on first use, required for recursive types\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Defers schema resolution to first use; required to break circular references in recursive types. */\nclass Lazy<T> extends Base<T> {\n private resolved: PxSchema<T> | null = null;\n constructor(private readonly fn: () => PxSchema<T>, readonly _default: T) { super(); }\n\n private get schema(): PxSchema<T> {\n return this.resolved ?? (this.resolved = this.fn());\n }\n\n sanitize(raw: unknown): T { return this.schema.sanitize(raw); }\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean { return this.schema.isValid(raw, ctx, path); }\n override _canSanitize(raw: unknown): boolean { return this.schema._canSanitize(raw); }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Tuple — fixed-length array with per-position schemas; default is defaults of each position\n// _canSanitize: true only when raw is an array of the exact expected length\n// ─────────────────────────────────────────────────────────────────────────────\n\n// Maps a tuple of schemas to a tuple of their inferred types.\ntype TupleItems<T extends ReadonlyArray<PxSchema<any, any>>> =\n { -readonly [K in keyof T]: T[K] extends PxSchema<infer U, any> ? U : never };\n\n/** Fixed-length array schema; validates element count and each position individually. */\nclass Tuple<T extends ReadonlyArray<PxSchema<any, any>>> extends Base<TupleItems<T>> {\n readonly _default: TupleItems<T>;\n\n constructor(private readonly schemas: T) {\n super();\n this._default = schemas.map(s => s._default) as unknown as TupleItems<T>;\n }\n\n sanitize(raw: unknown): TupleItems<T> {\n if (!Array.isArray(raw) || raw.length !== this.schemas.length) return this._default;\n return this.schemas.map((s, i) => s.sanitize((raw as unknown[])[i])) as unknown as TupleItems<T>;\n }\n\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n if (!Array.isArray(raw) || raw.length !== this.schemas.length) {\n ctx?.errors.push(pathStr(path ?? []) + ': expected tuple of length ' + this.schemas.length + ', got ' + (Array.isArray(raw) ? 'array[' + (raw as unknown[]).length + ']' : typeof raw));\n return false;\n }\n const p = path ?? [];\n let ok = true;\n for (let i = 0; i < this.schemas.length; i++) {\n p.push('[' + i + ']');\n if (!(this.schemas as ReadonlyArray<PxSchema<any, any>>)[i].isValid((raw as unknown[])[i], ctx, p)) ok = false;\n p.pop();\n }\n return ok;\n }\n\n // Require exact length so wrong-length arrays are dropped rather than repaired to default.\n override _canSanitize(raw: unknown): boolean {\n return Array.isArray(raw) && raw.length === this.schemas.length;\n }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// implementsInterface — compile-time lock between a schema and an interface\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Returns a pass-through wrapper that enforces at compile time that the schema's\n * inferred type is structurally assignable to `T`. Catches type mismatches on\n * required fields and value-type mismatches on optional fields.\n *\n * For key-level equality (catching optional field renames), pair with a\n * `KeysMatch` assertion after the inferred type alias:\n * ```ts\n * const _ck: KeysMatch<PxFoo, _PxFoo> = true;\n * ```\n *\n * @example\n * export const PxLoopSchema = implementsInterface<_PxLoop>()(px.object({ ... }));\n */\nexport function implementsInterface<T>() {\n return <S extends PxSchema<T>>(schema: S): S => schema;\n}\n\n/**\n * Evaluates to `true` when A and B have exactly the same set of keys; `false` otherwise.\n * Use with a `const` assertion to get a compile-time error on key renames:\n * ```ts\n * const _ck: KeysMatch<PxFoo, _PxFoo> = true;\n * ```\n */\nexport type KeysMatch<A, B> =\n [Exclude<keyof A, keyof B>] extends [never]\n ? [Exclude<keyof B, keyof A>] extends [never] ? true : false\n : false;\n\n/**\n * Builds a `{ key: 'key', ... }` object from a schema's shape.\n * Each value is typed as the literal key name, so `schemaKeys(PxFooSchema).bar`\n * is typed as `'bar'` — use in @serializable calls to get a compile-time error\n * if the field is renamed in the schema.\n */\nexport function schemaKeys<S extends { readonly _shape: Record<string, any> }>(schema: S) {\n return Object.fromEntries(\n Object.keys(schema['_shape']).map(k => [k, k])\n ) as { [K in keyof S['_shape']]: K };\n}\n\n/**\n * Describes the structural kind of a schema for traversal purposes.\n * Use with `getMissingCoveragePaths` or similar tree-walking utilities.\n *\n * - `shape` — object schema (Obj/OpenObj); `shape` maps key → sub-schema\n * - `array` — array schema; `item` is the element schema\n * - `optional` — optional wrapper; `inner` is the wrapped schema\n * - `lazy` — lazy/recursive schema; `resolved` is the resolved schema (cached)\n * - `leaf` — primitive, union, record, any, tuple — no traversable children\n */\nexport type PxSchemaDesc =\n | { kind: 'shape'; shape: Record<string, PxSchema<any, any>> }\n | { kind: 'array'; item: PxSchema<any, any> }\n | { kind: 'optional'; inner: PxSchema<any, any> }\n | { kind: 'lazy'; resolved: PxSchema<any, any> }\n | { kind: 'leaf' };\n\nexport function describeSchema(schema: PxSchema<any, any>): PxSchemaDesc {\n const s = schema as any;\n if ('_shape' in s) return { kind: 'shape', shape: s._shape };\n if ('item' in s) return { kind: 'array', item: s.item };\n if ('inner' in s) return { kind: 'optional', inner: s.inner };\n if ('fn' in s) return { kind: 'lazy', resolved: s.resolved ?? s.fn() };\n return { kind: 'leaf' };\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Public factory\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const px = {\n /** Matches a string. Default: '' or provided value. */\n string: (defaultVal = ''): PxSchema<string> => new Str(defaultVal),\n\n /** Matches a finite number. Default: 0 or provided value. */\n number: (defaultVal = 0): PxSchema<number> => new Num(defaultVal),\n\n /** Matches a boolean. Default: false or provided value. */\n boolean: (defaultVal = false): PxSchema<boolean> => new Bool(defaultVal),\n\n /** Matches one exact primitive value; its default is the value itself. */\n literal: <T extends string | number | boolean>(value: T): PxSchema<T> =>\n new Literal(value),\n\n /** Matches one of a fixed set of string/number values. Default: first value. */\n enum: <T extends string | number>(values: readonly T[], defaultVal?: T): PxSchema<T> =>\n new Enum(values, defaultVal),\n\n /**\n * Returns the first schema whose isValid passes.\n * TypeScript infers the union of all member types automatically.\n */\n union: <T extends ReadonlyArray<PxSchema<any, any>>>(\n schemas: T,\n defaultVal?: UnionMembers<T>\n ): PxSchema<UnionMembers<T>> =>\n new Union(schemas as any, defaultVal) as any,\n\n /**\n * Discriminated union — reads `raw[key]`, finds the member schema whose\n * literal at `key` matches, then delegates sanitize/isValid to that member.\n * Each member must be an object schema with a `px.literal(...)` at `key`.\n * TypeScript infers the union of all member types automatically.\n */\n discriminatedUnion: <\n K extends string,\n T extends ReadonlyArray<PxSchema<any, any> & { readonly _shape: Record<K, PxSchema<string | number | boolean, any>> }>\n >(key: K, schemas: T): PxSchema<UnionMembers<T>> =>\n new DiscriminatedUnion(key, schemas as any) as any,\n\n /** Typed object — unknown keys are stripped. Required fields fall back to their default. */\n object: <S extends AnyShape>(shape: S): PxSchema<InferShape<S>> & { readonly _shape: S } =>\n new Obj(shape),\n\n /**\n * Open object — validates known keys; passes unknown keys through as-is,\n * or validates/sanitizes them against `openSchema` when provided.\n */\n openObject: <S extends AnyShape, V = any>(\n shape: S,\n openSchema?: PxSchema<V>\n ): PxSchema<InferOpenShape<S, V>> & { readonly _shape: S } =>\n new OpenObj(shape, openSchema) as any,\n\n /**\n * Creates a new closed object schema by merging a base schema's shape with additional fields.\n * The base can be the result of px.object() or px.openObject() — anything with a _shape property.\n *\n * @example\n * const PxSvgNodeSchema = px.extendedObject(PxNodeBase, { width: px.number().optional() });\n */\n extendedObject: <B extends AnyShape, E extends AnyShape>(\n base: { readonly _shape: B },\n extra: E\n ): PxSchema<InferShape<B & E>> & { readonly _shape: B & E } =>\n new Obj({ ...base._shape, ...extra } as B & E),\n\n /** Array whose unrecoverable items are filtered out. Default: []. */\n array: <T>(item: PxSchema<T>): PxSchema<Array<T>> =>\n new Arr(item),\n\n /** String-keyed record whose unrecoverable values are dropped. Default: {}. */\n record: <T>(value: PxSchema<T>): PxSchema<Record<string, T>> =>\n new Rec(value),\n\n /** Passes anything through unchanged — always valid. */\n any: (): PxSchema<any> => new Any(),\n\n /** Fixed-length tuple — validates element count and each position individually. */\n tuple: <T extends ReadonlyArray<PxSchema<any, any>>>(schemas: T): PxSchema<TupleItems<T>> =>\n new Tuple(schemas),\n\n /** Defers schema creation — required for recursive types. Must supply a default value. */\n lazy: <T>(fn: () => PxSchema<T>, defaultVal: T): PxSchema<T> =>\n new Lazy(fn, defaultVal),\n} as const;\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport type { KeysMatch, PxInfer, PxSchema, PxValidationContext, RemoveIndex } from './PxSchema';\nimport { implementsInterface, px } from './PxSchema';\n\nexport type FillMode = 'forwards' | 'backwards' | 'both' | 'none';\n\nexport type PlaybackDirection = 'normal' | 'reverse' | 'alternate' | 'alternate-reverse';\n\nexport const PX_ANIM_SRC_ATTR_NAME = 'data-px-animation-src';\n\nexport const PX_ANIM_ATTR_NAME = '_px_animator';\n\nexport type StartOn = 'load' | 'mouseOver' | 'click' | 'scrollIntoView';\n\nexport type OutAction = 'continue' | 'pause' | 'reset' | 'reverse';\n\n/** Animation engine selection (config level). `auto` means \"try `webapi`, fall\n * back to `frames`\"; the runtime resolves it to a concrete {@link PxAnimatorEngine}\n * via `createAnimatorFromConfig`. Wire as a const-namespace + matching string\n * type so call sites can use named members (`PxAnimatorMode.frames`) instead of\n * bare string literals. */\nexport const PxAnimatorMode = {\n auto: 'auto',\n webapi: 'webapi',\n frames: 'frames',\n} as const;\nexport type PxAnimatorMode = typeof PxAnimatorMode[keyof typeof PxAnimatorMode];\n\n/** Resolved engine after `auto` dispatch — used downstream by code that always\n * knows exactly which engine is running (e.g. `getNormalisedBindings`'s\n * `engine` arg gates motion-along-path materialisation). Strictly a subset of\n * {@link PxAnimatorMode} (no `auto`). */\nexport const PxAnimatorEngine = {\n webapi: PxAnimatorMode.webapi,\n frames: PxAnimatorMode.frames,\n} as const;\nexport type PxAnimatorEngine = typeof PxAnimatorEngine[keyof typeof PxAnimatorEngine];\n\n/** @deprecated Backwards-compatibility alias — use {@link PxAnimatorMode} for the type. */\nexport type JsMode = PxAnimatorMode;\n\n\nexport const TEXT_ATTR = 'text';\nexport const TEXT_CONTENT_ATTR = 'textContent';\n\n// Attributes that should not be set on DOM elements (internal use only)\nexport const INTERNAL_ATTRS = new Set([\n 'type', 'children', 'animator', 'meta', 'animate', TEXT_ATTR, TEXT_CONTENT_ATTR\n]);\n\n\n// ============================================================================\n// EASING\n// ============================================================================\n\n/**\n * Easing function definition.\n * Can be a named reference to a predefined easing or a cubic-bezier array [x1, y1, x2, y2].\n *\n * @example \"ease-in\" | [0.68, -0.55, 0.265, 1.55]\n *\n * `string | [x1, y1, x2, y2]`\n */\nexport const PxEasingOrRefSchema = px.union([\n px.string(),\n px.tuple([px.number(), px.number(), px.number(), px.number()] as const),\n]);\n\n/**\n * Easing function definition.\n * Can be a named reference to a predefined easing or a cubic-bezier array [x1, y1, x2, y2].\n *\n * @example \"ease-in\" | \"easeOut\" | [0.68, -0.55, 0.265, 1.55]\n */\nexport type PxEasingOrRef = PxInfer<typeof PxEasingOrRefSchema>;\n\n\n// ============================================================================\n// KEYFRAME\n// ============================================================================\n\n/**\n * A single animation keyframe defining the state at a specific point in time.\n * Supports both full property names and short aliases for compact notation.\n */\nexport interface _PxKeyframe {\n\n /** Timestamp in milliseconds from animation start */\n time?: number;\n\n /** Short alias for \"time\" */\n t?: number;\n\n /** The value of the animated property at this keyframe */\n value?: any;\n\n /** Short alias for \"value\" */\n v?: any;\n\n /** Easing function applied to the interval from this keyframe to the next */\n easing?: PxEasingOrRef;\n\n /** Short alias for \"easing\" */\n e?: PxEasingOrRef;\n\n /**\n * Outgoing spatial tangent `[dx, dy]` for motion-along-path interpolation\n * (translate animations only).\n *\n * Stored as a *delta relative to* this keyframe's translate position —\n * the cubic Bezier segment between this kf and the next is built from\n * `(P0=value, P1=value+tangentOut, P2=next.value+next.tangentIn, P3=next.value)`.\n *\n * Defined when the segment leaving this keyframe is curved.\n */\n tangentOut?: [number, number];\n\n /** Short alias for \"tangentOut\" */\n to?: [number, number];\n\n /**\n * Incoming spatial tangent `[dx, dy]` for motion-along-path interpolation\n * (translate animations only). Delta relative to this keyframe's translate\n * position. See `tangentOut` for the segment construction.\n *\n * Defined when the segment arriving at this keyframe is curved.\n */\n tangentIn?: [number, number];\n\n /** Short alias for \"tangentIn\" */\n ti?: [number, number];\n\n /**\n * Editor-side UI state (whether the keyframe is selected in the timeline).\n * Declared here so strict-mode schema validation accepts it on the wire —\n * the Player ignores it.\n */\n selected?: boolean;\n}\n\n/**\n * Allowed shapes for a single keyframe `value` across the wire schema:\n * - `number` — scalar properties (rotate-degree, opacity, offset-distance, …)\n * - `Array<number>` — vector properties (translate `[x,y]`, scale `[sx,sy]`, stroke-dasharray, RGBA …)\n * - `string` — color (hex / `url(#…)` / named) and other string-valued props\n * - `PxTransformParts` — unified body `transform` parts record\n * `{translate, rotate, scale, origin}`\n * - `{ paths: Array<PxBezierPath> }` — animated SVG path `d` value\n *\n * Used as documentation / explicit-validation entry point; `PxKeyframeSchema`\n * itself stores `value` as `any` to keep downstream interpolator code in\n * `PxDefinitions.ts` working with duck-typed access (`prevV?.paths`,\n * `Array.isArray(prevV)`, …) without per-shape narrowing.\n */\nexport type _PxKeyframeValue =\n | string\n | number\n | Array<number>\n | PxTransformParts\n | { path: string }\n | { paths: Array<PxBezierPath> };\n\n// `string | number | Array<number> | PxTransformParts | { path: string } | { paths: BezierPath[] }`\n//\n// `{ path: \"M…\" }` is the unified single-`d`-string form for animated paths\n// (compound shapes are one string with multiple `M…` sub-paths); `{ paths: […] }`\n// is the legacy bezier-array form, both accepted.\n//\n// `PxTransformPartsSchema` / `PxBezierPathSchema` are declared later in this\n// file — `px.lazy` defers the lookup until validation time so the declarations\n// stay in narrative order without a TDZ at module load.\nexport const PxKeyframeValueSchema = implementsInterface<_PxKeyframeValue>()(px.union([\n px.string(), // e.g. for colors\n px.number(),\n px.array(px.number()),\n px.lazy<PxTransformParts>(() => PxTransformPartsSchema, {}),\n px.object({ path: px.string() }),\n px.lazy<{ paths: Array<PxBezierPath> }>(() => px.object({ paths: px.array(PxBezierPathSchema) }), { paths: [] }),\n]));\n\n/** A single keyframe `value` — union of all wire-allowed shapes. */\nexport type PxKeyframeValue = PxInfer<typeof PxKeyframeValueSchema>;\n\n// `{ time?:number, t?:number, value?:any, v?:any, easing?:Easing, e?:Easing,\n// tangentOut?:[dx,dy], tangentIn?:[dx,dy] }`\n//\n// `value` / `v` are stored as `px.any()` to match the `_PxKeyframe` interface\n// (`value?: any`) and to keep the inferred `PxKeyframe.value` type permissive\n// for the duck-typed access in `PxDefinitions.ts`. The structured value-shape\n// union is still available via {@link PxKeyframeValueSchema} for callers that\n// want to validate or document the allowed shapes.\nexport const PxKeyframeSchema = implementsInterface<_PxKeyframe>()(px.object({\n time: px.number().optional(),\n t: px.number().optional(),\n value: px.any().optional(),\n v: px.any().optional(),\n easing: PxEasingOrRefSchema.optional(),\n e: PxEasingOrRefSchema.optional(),\n tangentOut: px.tuple([px.number(), px.number()] as const).optional(),\n to: px.tuple([px.number(), px.number()] as const).optional(), // short alias\n tangentIn: px.tuple([px.number(), px.number()] as const).optional(),\n ti: px.tuple([px.number(), px.number()] as const).optional(), // short alias\n selected: px.boolean().optional(), // editor-side UI state (Player ignores it)\n}));\n\n/**\n * A single animation keyframe defining the state at a specific point in time.\n *\n * Generic over the keyframe `value` type for callers that know the per-property\n * value shape (e.g. `PxKeyframe<Vec2>` in the effect appliers). Defaults to\n * `any`, matching the schema (`value` is stored as `px.any()` on the wire).\n */\nexport type PxKeyframe<T = any> = Omit<PxInfer<typeof PxKeyframeSchema>, 'value' | 'v'> & { value?: T; v?: T };\nconst _ck_PxKeyframe: KeysMatch<PxKeyframe, _PxKeyframe> = true; // the key sets are identical\n\n\n// ============================================================================\n// LOOP\n// ============================================================================\n\n/**\n * Defines how a property's keyframe animation is extended beyond its defined keyframe range\n * by continuously repeating a chosen segment of the sequence.\n *\n * The repeated segment is a contiguous run of keyframe *intervals* (gaps between consecutive\n * keyframes). Which end of the sequence is repeated is controlled by `before`, and whether\n * each repetition plays in the same direction or alternates is controlled by `alternate`.\n *\n * **Relationship to `animator.iterations`**\n *\n * `PxLoop` and `animator.iterations` are independent mechanisms operating at different levels:\n *\n * - `PxLoop` is a **pre-processing step**: it expands the property's keyframe list to fill the\n * full `animator.duration` before any playback begins. The runtime sees a single, fully\n * expanded keyframe sequence — it has no knowledge of the loop.\n *\n * - `animator.iterations` repeats the **entire document timeline** (all properties, all\n * elements) as a unit, after the expanded keyframes are already in place.\n *\n * The two compose independently: a property with `loop: true` inside a document with\n * `iterations: \"infinite\"` will cycle its own segment within each document iteration, and\n * that iteration will itself repeat forever — loop-within-loop.\n */\nexport interface _PxLoop {\n\n /**\n * Number of keyframe intervals (gaps between consecutive keyframes) that form the repeating\n * segment.\n *\n * - `undefined` → the entire keyframe sequence is used as the loop segment.\n * - `N` → only the first `N` intervals (when `before: true`) or the last `N` intervals\n * (when `before: false`) are looped. Clamped to `[1, keyframes.length - 1]`.\n */\n segmentCount?: number;\n\n /**\n * Selects which end of the keyframe sequence is looped.\n *\n * - `true` → the source segment is taken from the *start* of the keyframe sequence.\n * The animation is extended *before* the first keyframe — useful for intro loops\n * that run before the main timeline begins.\n *\n * - `false` (default) → the source segment is taken from the *end* of the keyframe sequence.\n * The animation is extended *after* the last keyframe — useful for idle or outro\n * loops that continue once the main timeline has finished.\n */\n before?: boolean;\n\n /**\n * Controls playback direction on each successive loop iteration.\n *\n * - `false` (default) → **cycle**: every iteration replays the segment in the same direction.\n *\n * - `true` → **pingpong**: iterations alternate between forward and backward playback\n * (even iterations play forward, odd iterations play in reverse).\n */\n alternate?: boolean;\n}\n\n// `{ segmentCount?:number, before?:boolean, alternate?:boolean }`\nexport const PxLoopSchema = implementsInterface<_PxLoop>()(px.object({\n segmentCount: px.number().optional(),\n before: px.boolean().optional(),\n alternate: px.boolean().optional(),\n}));\n\n/**\n * Defines how a property's keyframe animation is extended beyond its defined keyframe range\n * by continuously repeating a chosen segment of the sequence.\n */\nexport type PxLoop = PxInfer<typeof PxLoopSchema>;\nconst _ck_PxLoop: KeysMatch<PxLoop, _PxLoop> = true; // the key sets are identical\n\n\n// ============================================================================\n// PROPERTY ANIMATION\n// ============================================================================\n\n/**\n * Animation definition for a single CSS/SVG property.\n * Contains an array of keyframes that define how the property changes over time.\n */\nexport interface _PxPropertyAnimation {\n\n /** Array of keyframes defining the animation timeline */\n keyframes?: PxKeyframe[];\n\n /** Short alias for \"keyframes\" */\n kfs?: PxKeyframe[];\n\n /**\n * Optional loop configuration. When set, the keyframe sequence is expanded at pre-processing\n * time to fill the gap between the keyframe range and `animator.duration` by repeating a\n * chosen segment. `true` is shorthand for the default {@link PxLoop} (loop the last segment\n * after the final keyframe, cycling forward). See {@link PxLoop} for details.\n *\n * Note: this operates independently of `animator.iterations` — see {@link _PxLoop} for the\n * interaction between the two.\n */\n loop?: PxLoop | boolean;\n\n /**\n * Motion-along-path \"auto-orient\" flag. Only meaningful for translate\n * animations whose keyframes carry spatial tangents (`tangentIn` /\n * `tangentOut`): when true, the element rotates so its local X axis aligns\n * with the path tangent at the current position. The rotation is computed\n * from the cubic-Bezier derivative at the eased progress along the\n * arc-length-parametrised segment.\n */\n autoOrient?: boolean;\n}\n\n// `{ keyframes?:Keyframe[], kfs?:Keyframe[], loop?:Loop|boolean, autoOrient?:bool }`\nexport const PxPropertyAnimationSchema = implementsInterface<_PxPropertyAnimation>()(px.object({\n keyframes: px.array(PxKeyframeSchema).optional(),\n kfs: px.array(PxKeyframeSchema).optional(),\n loop: px.union([PxLoopSchema, px.boolean()]).optional(),\n autoOrient: px.boolean().optional(),\n}));\n\n/** Animation definition for a single CSS/SVG property. */\nexport type PxPropertyAnimation = PxInfer<typeof PxPropertyAnimationSchema>;\nconst _ck_PxPropertyAnimation: KeysMatch<PxPropertyAnimation, _PxPropertyAnimation> = true; // the key sets are identical\n\n\n// ============================================================================\n// TRANSFORM\n// ============================================================================\n\n/**\n * Names of the transform parts that can appear inside a transform value record.\n * The unified `transform` slot replaces the earlier per-part top-level keys\n * (`translate`, `rotate`, `scale`, `origin`) — those names now live as keys\n * inside a `PxTransformParts` record.\n */\nexport const PX_TRANSFORM_PART_KEYS = ['translate', 'rotate', 'scale', 'origin'] as const;\n\n/** One of the transform-part key strings. */\nexport type PxTransformPartKey = typeof PX_TRANSFORM_PART_KEYS[number];\n\n/**\n * Record of transform parts forming a single transform `value`. Each present\n * key contributes one segment of the composed CSS transform string at render /\n * interpolation time, in the canonical order\n * `translate, translate(+origin), rotate, scale, translate(-origin)`.\n *\n * `origin` is meaningful only when `rotate` or `scale` is also present in the\n * same record — see \"When does origin belong inside a keyframe value?\" in\n * `file-format-remaining-design-issues2.md`.\n */\nexport interface _PxTransformParts {\n\n /** Translation offset `[x, y]` in user units. */\n translate?: [number, number];\n\n /** Rotation in degrees. */\n rotate?: number;\n\n /** Skew (skewX) in degrees, pivoting at `origin` — composed between `rotate`\n * and `scale` (matches Lottie's transform order). */\n skew?: number;\n\n /** Scale factor `[sx, sy]`. */\n scale?: [number, number];\n\n /**\n * Pivot for rotate / scale `[x, y]`. Only meaningful alongside `rotate` or\n * `scale` in the same record.\n */\n origin?: [number, number];\n}\n\n// `{ translate?:[x,y], rotate?:deg, skew?:deg, scale?:[sx,sy], origin?:[x,y] }`\nexport const PxTransformPartsSchema = implementsInterface<_PxTransformParts>()(px.object({\n translate: px.tuple([px.number(), px.number()] as const).optional(),\n rotate: px.number().optional(),\n skew: px.number().optional(),\n scale: px.tuple([px.number(), px.number()] as const).optional(),\n origin: px.tuple([px.number(), px.number()] as const).optional(),\n}));\n\n/** Record of transform parts forming a single transform `value`. */\nexport type PxTransformParts = PxInfer<typeof PxTransformPartsSchema>;\nconst _ck_PxTransformParts: KeysMatch<PxTransformParts, _PxTransformParts> = true; // the key sets are identical\n\n/**\n * Unified `transform` slot value. Three valid shapes:\n *\n * - **SVG transform string** — `\"translate(10,10)rotate(45)scale(2,2)\"`. What\n * plain renderers consume directly.\n * - **Structured static** — `{value: PxTransformParts}`. Parametric record;\n * parts stay independently addressable.\n * - **Animated** — `{keyframes: [{time, value: PxTransformParts, …}, …]}`.\n * Each keyframe's `value` is a parts record. The interpolator composes the\n * parts into a single transform string per frame.\n *\n * Replaces the earlier convention of putting each animated transform part\n * under its own top-level attribute name (`translate`, `rotate`, `scale`,\n * `origin`).\n */\nexport const PxTransformValueSchema = px.union([\n px.string(),\n px.object({ value: PxTransformPartsSchema }),\n PxPropertyAnimationSchema,\n]);\n\n/** Unified `transform` slot value: string | structured static | animated. */\nexport type PxTransformValue = PxInfer<typeof PxTransformValueSchema>;\n\n\n// ============================================================================\n// ANIMATION DEFINITION\n// ============================================================================\n\n/**\n * Complete animation definition containing one or more property animations.\n * Each key is a CSS/SVG property name (e.g., \"opacity\", \"translate\", \"fill\").\n *\n * @example\n * { \"opacity\": { keyframes: [...] }, \"translate\": { keyframes: [...] } }\n */\nexport interface _PxAnimationDefinition {\n [property: string]: PxPropertyAnimation;\n}\n\n// `Record<propName, PropertyAnimation>`\nexport const PxAnimationDefinitionSchema = implementsInterface<_PxAnimationDefinition>()(\n px.record(PxPropertyAnimationSchema)\n);\n\n/**\n * Complete animation definition containing one or more property animations.\n * Each key is a CSS/SVG property name (e.g., \"opacity\", \"scale\", \"rotate\").\n */\nexport type PxAnimationDefinition = PxInfer<typeof PxAnimationDefinitionSchema>;\n\n\n// ============================================================================\n// ELEMENT ANIMATION\n// ============================================================================\n\n/**\n * Element animation specification. Can be:\n * - A string referencing a named animation from `definitions.animations`\n * - An array of named references\n * - An inline `AnimationDefinition` object\n * - A mixed array of references and inline definitions\n *\n * @example\n * \"fadeIn\"\n * [\"fadeIn\", \"spin\"]\n * { opacity: { keyframes: [...] } }\n * [\"fadeIn\", { scale: { keyframes: [...] } }]\n */\nexport type _PxElementAnimation =\n | string\n | string[]\n | PxAnimationDefinition\n | (string | PxAnimationDefinition)[];\n\n// `string | Array<string|AnimationDefinition> | AnimationDefinition`\nexport const PxElementAnimationSchema = implementsInterface<_PxElementAnimation>()(px.union([\n px.string(),\n px.array(px.union([px.string(), PxAnimationDefinitionSchema])),\n PxAnimationDefinitionSchema,\n]));\n\n/**\n * Element animation specification.\n * Can be a string reference, array of references, inline definition, or a mixed array.\n */\nexport type PxElementAnimation = PxInfer<typeof PxElementAnimationSchema>;\n\n\n// ============================================================================\n// TRIGGER\n// ============================================================================\n\ntype StartOnExtra = StartOn | 'programmatic';\n\n/**\n * Defines when and how an animation should be triggered.\n */\nexport interface _PxTrigger {\n\n /** Event that starts the animation */\n startOn?: StartOnExtra;\n\n /** Action to take when the trigger condition is no longer met (e.g., mouse leaves) */\n outAction?: 'continue' | 'pause' | 'reset' | 'reverse';\n\n /** Percentage of element visibility required to trigger (0–1, default 0 = any pixel).\n * Only applies to scrollIntoView. */\n scrollIntoViewThreshold?: number;\n}\n\n// `{ startOn?:'load'|'mouseOver'|'click'|'scrollIntoView'|'programmatic', outAction?:..., scrollIntoViewThreshold?:number }`\nexport const PxTriggerSchema = implementsInterface<_PxTrigger>()(px.object({\n startOn: px.enum(['load', 'mouseOver', 'click', 'scrollIntoView', 'programmatic'] as const).optional(),\n outAction: px.enum(['continue', 'pause', 'reset', 'reverse'] as const).optional(),\n scrollIntoViewThreshold: px.number().optional(),\n}));\n\n/** Defines when and how an animation should be triggered. */\nexport type PxTrigger = PxInfer<typeof PxTriggerSchema>;\nconst _ck_PxTrigger: KeysMatch<PxTrigger, _PxTrigger> = true; // the key sets are identical\n\n\n// ============================================================================\n// DEFS\n// ============================================================================\n\n/**\n * A single character's embedded outline (glyph-mode text). Coordinates and\n * advance are in the owning {@link _PxGlyphFont}'s `unitsPerEm` units, so the\n * player can render text without the original font. See svga.text.design.md.\n */\nexport interface _PxGlyph {\n /** Advance width, in the font's `unitsPerEm`. */\n width: number;\n /** Outline path `d`, in the font's `unitsPerEm` (empty for whitespace). */\n d: string;\n}\n\nexport const PxGlyphSchema = implementsInterface<_PxGlyph>()(px.object({\n width: px.number(),\n d: px.string(),\n}));\n\nexport type PxGlyph = PxInfer<typeof PxGlyphSchema>;\nconst _ck_PxGlyph: KeysMatch<PxGlyph, _PxGlyph> = true; // the key sets are identical\n\n/**\n * The used glyphs of one font, keyed by character. Referenced by a text's\n * `font-family` (the key in {@link _PxDefs.glyphs}).\n */\nexport interface _PxGlyphFont {\n /** CSS family name, e.g. \"Roboto\". */\n fFamily: string;\n /** Style notation, e.g. \"\" | \"italic\". */\n style: string;\n /** Ascent, in `unitsPerEm` units (baseline placement). */\n ascent: number;\n /** Units per em the glyph `width`/`d` are expressed in, e.g. 1000. */\n unitsPerEm: number;\n /** Outlines of the used characters, keyed by the character itself. */\n glyphs: { [char: string]: PxGlyph; };\n}\n\nexport const PxGlyphFontSchema = implementsInterface<_PxGlyphFont>()(px.object({\n fFamily: px.string(),\n style: px.string(),\n ascent: px.number(),\n unitsPerEm: px.number(),\n glyphs: px.record(PxGlyphSchema),\n}));\n\nexport type PxGlyphFont = PxInfer<typeof PxGlyphFontSchema>;\nconst _ck_PxGlyphFont: KeysMatch<PxGlyphFont, _PxGlyphFont> = true; // the key sets are identical\n\n/**\n * Reusable definitions library for easings, animations, and styles.\n * Defined once here, referenced by name on elements.\n */\nexport interface _PxDefs {\n\n /** Named cubic-bezier easing functions */\n easings?: { [name: string]: [number, number, number, number]; };\n\n /** Named animation definitions that can be referenced by elements */\n animations?: { [name: string]: PxAnimationDefinition; };\n\n /** Named style presets. A node's `style` may reference one by name;\n * resolved and applied at render time (see `resolveStyle` in PxAnimatorDOM). */\n styles?: { [name: string]: Record<string, string | number>; };\n\n /** Embedded per-font glyph outlines, keyed by the text's `font-family`.\n * Lets glyph-mode `<text>` render without an external font. */\n glyphs?: { [fontName: string]: PxGlyphFont; };\n}\n\n// `{ easings?:Record<name,[x1,y1,x2,y2]>, animations?:Record<name,AnimationDefinition>, styles?:Record<string,any>, glyphs?:Record<fontName,PxGlyphFont> }`\nexport const PxDefsSchema = implementsInterface<_PxDefs>()(px.object({\n easings: px.record(px.tuple([px.number(), px.number(), px.number(), px.number()] as const)).optional(),\n animations: px.record(PxAnimationDefinitionSchema).optional(),\n styles: px.record(px.any()).optional(),\n glyphs: px.record(PxGlyphFontSchema).optional(),\n}));\n\n/** Reusable definitions library for easings, animations, and styles. */\nexport type PxDefs = PxInfer<typeof PxDefsSchema>;\nconst _ck_PxDefs: KeysMatch<PxDefs, _PxDefs> = true; // the key sets are identical\n\n\n// ============================================================================\n// ANIMATOR CONFIG\n// ============================================================================\n\n/**\n * Global animation configuration that applies to all animations in the document.\n * Defines timing, playback behaviour, and rendering strategy.\n */\nexport interface _PxAnimatorConfig {\n\n /** JavaScript animation implementation strategy */\n mode?: PxAnimatorMode;\n\n /** Total animation duration in milliseconds */\n duration?: number;\n\n /** Delay before animation starts in milliseconds */\n delay?: number;\n\n /**\n * Number of times to repeat the entire document timeline. Use `\"infinite\"` for endless loop.\n *\n * This repeats **all properties across all elements** as a unit. It is independent of\n * per-property `loop` configuration: if a property uses `loop`, its keyframes are already\n * expanded to fill `duration` before `iterations` takes effect — the two do not interfere,\n * but they do compose (a looping property inside an infinitely iterating document loops\n * within each iteration).\n */\n iterations?: number | \"infinite\";\n\n /** After a natural finish, snap the document back to its start state (same\n * mechanics as the trigger `reset` out-action). Off by default — the animation\n * holds its end state per `fill`. */\n resetOnFinish?: boolean;\n\n /**\n * Defines which values are applied before/after the active animation period\n * (maps directly to the Web Animations API `fill` option).\n * Defaults to `'forwards'` when not set so that elements hold their final\n * state after the animation ends — consistent with Lottie and other animation\n * runtimes. Without this default, seeking to the last frame would cause\n * elements to revert to their pre-animation state.\n */\n fill?: FillMode;\n\n /** Direction of animation playback */\n direction?: PlaybackDirection;\n\n /** Target frame rate for frame-based animations (only applicable when mode=\"frames\") */\n frameRate?: number;\n\n /** Trigger configuration for when animation should start */\n trigger?: PxTrigger;\n\n /** Named easings, animations, and styles — referenced by elements */\n definitions?: PxDefs;\n\n /**\n * Animation map for pre-rendered SVG elements (Mode B).\n * Maps element IDs to their animation specs. Used when the SVG DOM already exists\n * and the player only needs to animate existing elements.\n *\n * @example { \"_px_abc\": { opacity: { keyframes: [...] } }, \"_px_def\": [\"fadeIn\"] }\n */\n animate?: Record<string, PxElementAnimation>;\n\n /** Reserved for future use — accepted on the wire but currently has no effect. */\n debug?: boolean;\n\n /** Debug helper: exposes the animator instance as `window[debugInstName]`. */\n debugInstName?: string;\n}\n\n// `{ mode?, duration?, delay?, iterations?, fill?, direction?, frameRate?, trigger?, definitions?, animate?, debug?, debugInstName? }`\nexport const PxAnimatorConfigSchema = implementsInterface<_PxAnimatorConfig>()(px.object({\n mode: px.enum([PxAnimatorMode.auto, PxAnimatorMode.webapi, PxAnimatorMode.frames] as const).optional(),\n duration: px.number().optional(),\n delay: px.number().optional(),\n iterations: px.union([px.number(), px.literal('infinite')]).optional(),\n fill: px.enum(['forwards', 'backwards', 'both', 'none'] as const).optional(),\n direction: px.enum(['normal', 'reverse', 'alternate', 'alternate-reverse'] as const).optional(),\n frameRate: px.number().optional(),\n trigger: PxTriggerSchema.optional(),\n resetOnFinish: px.boolean().optional(),\n definitions: PxDefsSchema.optional(),\n animate: px.record(PxElementAnimationSchema).optional(),\n debug: px.boolean().optional(),\n debugInstName: px.string().optional(),\n}));\n\n/**\n * Global animation configuration that applies to all animations in the document.\n * Defines timing, playback behavior, and rendering strategy.\n */\nexport type PxAnimatorConfig = PxInfer<typeof PxAnimatorConfigSchema>;\nconst _ck_PxAnimatorConfig: KeysMatch<PxAnimatorConfig, _PxAnimatorConfig> = true; // the key sets are identical\n\n\n// ============================================================================\n// BINDING\n// ============================================================================\n\n/**\n * Binds animations to existing DOM elements by ID.\n * Used when the SVG tree is pre-rendered and animations are applied separately.\n */\nexport interface _PxBinding {\n\n /** ID targeting elements in the DOM (data-px-id=\"...\") */\n id: string;\n\n /** Animation to apply to matched elements */\n animate: PxElementAnimation;\n}\n\n// `{ id:string, animate:ElementAnimation }`\nexport const PxBindingSchema = implementsInterface<_PxBinding>()(px.object({\n id: px.string(),\n animate: PxElementAnimationSchema,\n}));\n\n/**\n * Binds animations to existing DOM elements via CSS selectors.\n * Used when the SVG tree is pre-rendered and animations are applied separately.\n */\nexport type PxBinding = PxInfer<typeof PxBindingSchema>;\nconst _ck_PxBinding: KeysMatch<PxBinding, _PxBinding> = true; // the key sets are identical\n\n\n// ============================================================================\n// NODE\n// ============================================================================\n\n/**\n * Per-attribute value shape on the element body. A property key carries either:\n * - a primitive (string/number) — static SVG attribute\n * - a `{value: …}` object — structured static parametric source (record-shaped\n * static value, used by attributes whose static representation is itself a\n * record — notably `transform: {value: PxTransformParts}`)\n * - a `{keyframes}` / `{kfs}` object — inline property animation\n *\n * The unified rule (primitive | `{value}` | `{keyframes}`) applies across the\n * format. For most attributes the `{value}` form is rarely used on the body\n * (a primitive suffices for static); for `transform` it is the canonical\n * structured-static shape. See `PxTransformValueSchema`.\n */\nexport const PxAttrValueSchema = px.union([\n px.string(),\n px.number(),\n px.object({ value: px.any() }),\n PxPropertyAnimationSchema,\n]);\n\n/** Per-attribute value: primitive for static, `{value}` for structured static, `PxPropertyAnimation` for animated. */\nexport type PxAttrValue = string | number | { value: any } | PxPropertyAnimation;\n\n\n/**\n * Base interface for all SVG elements.\n * Named properties take precedence over the index signature when accessed.\n */\nexport interface _PxNode {\n\n /** SVG element type (e.g., \"circle\", \"rect\", \"path\", \"g\") */\n type: string;\n\n /** Child elements (for container elements like <g>) */\n children?: PxNode[];\n\n /** Meta informaion about this element */\n meta?: any;\n\n /**\n * Player-effects bucket (transformation/repeater/maskedBy/trimPath/retime/ref)\n * emitted by the Editor's lightweight design format. `applyPlayerEffects`\n * materialises and removes these before any other normalisation, so the\n * Player never observes a non-empty `effects` after entry-point processing.\n *\n * Typed against `PxEffectsSchema` (closed object — strict-mode validation\n * flags unknown effect keys). Adding a new effect requires extending the\n * `_PxEffects` interface AND the schema in lockstep.\n */\n effects?: PxEffects;\n\n /**\n * In-place property animations for this element. Same shape as the\n * `animator.animate` map values: string ref, array of refs, inline\n * definition (`{propName: PxPropertyAnimation}`), or mixed array.\n * The static initial value of an animated property is still carried as a\n * plain attribute on the body.\n */\n animate?: PxElementAnimation;\n\n /**\n * FIXME - do we need it?\n * Style applied to this element (named reference or inline object)\n */\n style?: string | Record<string, string | number>;\n\n /**\n * All other SVG attributes (cx, cy, r, fill, stroke, etc.).\n * A value is either a primitive (static) or a PxPropertyAnimation (in-place\n * animation `{keyframes: [...]}` / `{kfs: [...]}`).\n */\n [key: string]: any;\n}\n\n// ============================================================================\n// PLAYER-EFFECTS BUCKET — INTERFACES + SCHEMAS (linked via `implementsInterface`)\n// ============================================================================\n//\n// Schemas for the `node.effects` payload emitted by the Editor's lightweight\n// design format. `applyPlayerEffects` (in `effects/PlayerEffectsUtil.ts`)\n// materialises and removes these before any other normalisation, so the Player\n// never observes a non-empty `effects` after entry-point processing.\n//\n// Each effect is declared as a `_Px*` interface, paired with a `Px*Schema`\n// wrapped in `implementsInterface<_Px*>()(…)`. The runtime schema and the\n// compile-time interface drift together: a new field added to either without\n// matching the other is a TS error. `KeysMatch` asserts key-set equality so\n// renames are caught too. This is the same pattern used by `PxKeyframe`,\n// `PxLoop`, etc. earlier in this file.\n//\n// `effects/types.ts` re-exports these types so the applier internals\n// (`effects/*.ts`) can still `import from './types'` unchanged.\n\n/** Fixed-length 2-number tuple. `[x, y]` for positions, `[sx, sy]` for scale, …. */\nexport type Vec2 = [number, number];\n\n/**\n * Animatable wire value: a raw static value, a `{value}` structured-static, or\n * a `{keyframes}` animation. Used by the effect schemas; the runtime schema\n * variants live below as `PxAnimatableNumberSchema` / `PxAnimatableVec2Schema`.\n *\n * Generic over the per-kf value type `T` for compile-time narrowing of the\n * static / `{value}` forms. The `{keyframes}` form uses the lib's non-generic\n * `PxKeyframe` (whose `value` is `any`) — kf values are read with care in the\n * applier (the visualModel walker / `interpParts` know per-property shapes).\n */\nexport type PxAnimatable<T> = T | { value: T } | { keyframes: Array<PxKeyframe>; autoOrient?: boolean };\n\n// PxAnimatable<number> — static number OR `{value}` static OR `{keyframes}` animated.\nconst PxAnimatableNumberSchema = px.union([\n px.number(),\n px.object({ value: px.number() }),\n px.object({\n keyframes: px.array(PxKeyframeSchema),\n autoOrient: px.boolean().optional(),\n }),\n]);\n\n// PxAnimatable<Vec2> — static `[x,y]` OR `{value:[x,y]}` OR `{keyframes}` animated.\n// `as const` on the tuples is REQUIRED for TS to infer `[number, number]` (a\n// fixed-length tuple = `Vec2`) instead of the looser `number[]`.\nconst PxAnimatableVec2Schema = px.union([\n px.tuple([px.number(), px.number()] as const),\n px.object({ value: px.tuple([px.number(), px.number()] as const) }),\n px.object({\n keyframes: px.array(PxKeyframeSchema),\n autoOrient: px.boolean().optional(),\n }),\n]);\n\n\n/** Per-part editor transform (`transformation` effect). All parts optional and animatable. */\nexport interface _PxTransformationEffect {\n translate?: PxAnimatable<Vec2>;\n rotate?: PxAnimatable<number>;\n scale?: PxAnimatable<Vec2>;\n /** Skew (skewX) in degrees — a NUMBER (matches the editor's scalar skew part). */\n skew?: PxAnimatable<number>;\n origin?: PxAnimatable<Vec2>;\n}\nexport const PxTransformationEffectSchema = implementsInterface<_PxTransformationEffect>()(px.object({\n translate: PxAnimatableVec2Schema.optional(),\n rotate: PxAnimatableNumberSchema.optional(),\n scale: PxAnimatableVec2Schema.optional(),\n skew: PxAnimatableNumberSchema.optional(),\n origin: PxAnimatableVec2Schema.optional(),\n}));\nexport type PxTransformationEffect = PxInfer<typeof PxTransformationEffectSchema>;\nconst _ck_PxTransformationEffect: KeysMatch<PxTransformationEffect, _PxTransformationEffect> = true;\n\n\n/** Per-copy repeater offsets. Each part is animatable; per-copy values scale\n * with the copy index `i` (translate/rotate/origin × i; scale per-axis `(v/100)^i`).\n * Static repeater values pass through as a structured `transform: {value:…}` on\n * the per-copy wrapper; animated values are emitted as `animate.transform.keyframes`\n * with each kf value scaled by `i`. See `effects/repeaterEffect.ts`. */\nexport interface _PxRepeaterEffect {\n copies?: number;\n translate?: PxAnimatable<Vec2>;\n rotate?: PxAnimatable<number>;\n scale?: PxAnimatable<Vec2>; // per-copy scale, stored as PERCENT (85 → 0.85)\n origin?: PxAnimatable<Vec2>;\n}\nexport const PxRepeaterEffectSchema = implementsInterface<_PxRepeaterEffect>()(px.object({\n copies: px.number().optional(),\n translate: PxAnimatableVec2Schema.optional(),\n rotate: PxAnimatableNumberSchema.optional(),\n scale: PxAnimatableVec2Schema.optional(),\n origin: PxAnimatableVec2Schema.optional(),\n}));\nexport type PxRepeaterEffect = PxInfer<typeof PxRepeaterEffectSchema>;\nconst _ck_PxRepeaterEffect: KeysMatch<PxRepeaterEffect, _PxRepeaterEffect> = true;\n\n\n/** Mask source ref + standard `<mask>` attributes. */\nexport interface _PxMaskedByEffect {\n href?: string;\n maskType?: string;\n maskUnits?: string;\n maskContentUnits?: string;\n}\nexport const PxMaskedByEffectSchema = implementsInterface<_PxMaskedByEffect>()(px.object({\n href: px.string().optional(),\n maskType: px.string().optional(),\n maskUnits: px.string().optional(),\n maskContentUnits: px.string().optional(),\n}));\nexport type PxMaskedByEffect = PxInfer<typeof PxMaskedByEffectSchema>;\nconst _ck_PxMaskedByEffect: KeysMatch<PxMaskedByEffect, _PxMaskedByEffect> = true;\n\n\n/**\n * Clip-path effect — clips the host element to a vector path. `d` is a plain SVG\n * path-data string (one or more subpaths) — the static / frame-0 geometry. `animate`\n * (optional) carries `d` keyframes (`value:{path:\"M…\"}`) for an ANIMATED clip: at apply\n * time it lands on the minted `<path>`'s `animate.d`, so the player's frame loop rewrites\n * the clip path's `d` attribute per frame. `clip-path` is a live reference, so the browser\n * re-clips each frame (unlike `<marker>` — verified across SMIL/CSS/JS/WAAPI).\n *\n * At apply time the effect mints a `<clipPath><path d/></clipPath>` def and sets\n * `clip-path=\"url(#auto-id)\"` on the host (materialiser pattern, like `maskedBy` /\n * gradient). See `effects/clipPathEffect.ts`.\n */\nexport interface _PxClipPathEffect {\n d?: string;\n animate?: PxPropertyAnimation;\n}\nexport const PxClipPathEffectSchema = implementsInterface<_PxClipPathEffect>()(px.object({\n d: px.string().optional(),\n animate: PxPropertyAnimationSchema.optional(),\n}));\nexport type PxClipPathEffect = PxInfer<typeof PxClipPathEffectSchema>;\nconst _ck_PxClipPathEffect: KeysMatch<PxClipPathEffect, _PxClipPathEffect> = true;\n\n\n/**\n * Trim-path effect. `range[0..1]` is the visible fraction of the stroke; `offset`\n * shifts the visible window along the path (also a fraction). Both are animatable.\n * `trimAllAsOne=true` chains all descendant subpath lengths into one virtual path\n * (\"Trim All As One\"): the trim window slides across siblings instead of being\n * applied to each subpath independently — see `effects/trimPathEffect.ts`.\n */\nexport interface _PxTrimPathEffect {\n offset?: PxAnimatable<number>;\n range?: PxAnimatable<Vec2>;\n trimAllAsOne?: boolean;\n}\nexport const PxTrimPathEffectSchema = implementsInterface<_PxTrimPathEffect>()(px.object({\n offset: PxAnimatableNumberSchema.optional(),\n range: PxAnimatableVec2Schema.optional(),\n trimAllAsOne: px.boolean().optional(),\n}));\nexport type PxTrimPathEffect = PxInfer<typeof PxTrimPathEffectSchema>;\nconst _ck_PxTrimPathEffect: KeysMatch<PxTrimPathEffect, _PxTrimPathEffect> = true;\n\n\n/** `<use>` retime: `baseId` = source; `start`/`timeCrop` in ms.\n * NOTE: `timeCrop` is accepted on the wire but not implemented yet — the\n * applier warns and ignores it (see `effects/retimeEffect.ts`). */\nexport interface _PxRetimeEffect {\n baseId?: string;\n start?: number;\n stretch?: number;\n timeCrop?: [number, number];\n}\nexport const PxRetimeEffectSchema = implementsInterface<_PxRetimeEffect>()(px.object({\n baseId: px.string().optional(),\n start: px.number().optional(),\n stretch: px.number().optional(),\n timeCrop: px.tuple([px.number(), px.number()] as const).optional(),\n}));\nexport type PxRetimeEffect = PxInfer<typeof PxRetimeEffectSchema>;\nconst _ck_PxRetimeEffect: KeysMatch<PxRetimeEffect, _PxRetimeEffect> = true;\n\n\n/**\n * `<use>` CLONE — merges the former `ref` + `retime` effects. A `<use>` is a clone\n * of something: `type`/`baseId` say WHAT it clones, `retime` says WHEN.\n * - `type: 'content'` → content-ref (excludes the target's own translate);\n * `type` absent → direct / whole-element link (keeps translate).\n * - `baseId` = the source element id (lives once here; the player follows `href`).\n * - `retime` = optional time-shift (nested).\n * Omitted entirely when all-default (a bare `<use href>` carries no `clone` bucket).\n */\nexport interface _PxCloneEffect {\n type?: string;\n baseId?: string;\n retime?: _PxRetimeEffect;\n}\nexport const PxCloneEffectSchema = implementsInterface<_PxCloneEffect>()(px.object({\n type: px.string().optional(),\n baseId: px.string().optional(),\n retime: PxRetimeEffectSchema.optional(),\n}));\nexport type PxCloneEffect = PxInfer<typeof PxCloneEffectSchema>;\nconst _ck_PxCloneEffect: KeysMatch<PxCloneEffect, _PxCloneEffect> = true;\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Gradient paint effect — `fillGradient` / `strokeGradient`.\n//\n// Materialiser pattern mirrors `maskedByEffect`: at apply time the gradient\n// effect mints a `<linearGradient>` / `<radialGradient>` def into `ctx.defs`,\n// then sets the host element's `fill` / `stroke` to `url(#auto-id)`. The wire\n// gradient is geometry as static parts + a stop sequence that is either static\n// (bare array) or animated (a single `{keyframes}` block whose each kf's `value`\n// is the FULL `Array<{offset, color}>` snapshot at that time). Per-stop\n// independent timelines are intentionally NOT modelled — the source is a single\n// stop-colour keyframe group.\n//\n// Stop count is constant across kfs. `gradientTransform` is captured as static\n// only (animated transform is vanishingly rare).\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Loose enums for `gradientUnits` / `spreadMethod` — kept on the wire as\n * plain strings (matches the rest of the schema's loose-enum stance) but\n * collected here so call sites use named constants instead of bare literals. */\nexport const PxGradientUnits = {\n userSpaceOnUse: 'userSpaceOnUse',\n objectBoundingBox: 'objectBoundingBox',\n} as const;\nexport type PxGradientUnits = typeof PxGradientUnits[keyof typeof PxGradientUnits];\n\nexport const PxGradientSpreadMethod = {\n pad: 'pad',\n reflect: 'reflect',\n repeat: 'repeat',\n} as const;\nexport type PxGradientSpreadMethod = typeof PxGradientSpreadMethod[keyof typeof PxGradientSpreadMethod];\n\nexport const PxGradientType = {\n linear: 'linear',\n radial: 'radial',\n} as const;\nexport type PxGradientType = typeof PxGradientType[keyof typeof PxGradientType];\n\n/** A single colour stop. `offset` is in `[0, 1]`; `color` is a CSS colour\n * string (`#rrggbb`, `rgb(…)`, `rgba(…)`, or named). */\nexport interface _PxGradientStop {\n offset: number;\n color: string;\n}\nexport const PxGradientStopSchema = implementsInterface<_PxGradientStop>()(px.object({\n offset: px.number(),\n color: px.string(),\n}));\nexport type PxGradientStop = PxInfer<typeof PxGradientStopSchema>;\nconst _ck_PxGradientStop: KeysMatch<PxGradientStop, _PxGradientStop> = true;\n\n/** `PxAnimatable<Array<PxGradientStop>>` schema. Static is the bare array;\n * `{value: […]}` wraps the same; `{keyframes}` is a single timeline whose\n * each kf's `value` is the FULL stops array at that time. */\nconst PxAnimatableGradientStopsSchema = px.union([\n px.array(PxGradientStopSchema),\n px.object({ value: px.array(PxGradientStopSchema) }),\n px.object({ keyframes: px.array(PxKeyframeSchema) }),\n]);\n\n/** Gradient paint effect — used by both `fillGradient` and `strokeGradient`\n * (same shape, different host attribute). Linear: `p1`/`p2`. Radial:\n * `c`/`r`/`fp`. Stops animate as one timeline; geometry stays static. */\nexport interface _PxFillGradientEffect {\n type: PxGradientType; // 'linear' | 'radial'\n p1?: Vec2; // linear start\n p2?: Vec2; // linear end\n c?: Vec2; // radial centre\n r?: number; // radial radius\n fp?: Vec2; // radial focal point\n stops?: PxAnimatable<Array<_PxGradientStop>>; // single animation timeline\n gradientUnits?: string; // PxGradientUnits values\n spreadMethod?: string; // PxGradientSpreadMethod values\n gradientTransform?: string; // static only in v1\n}\nexport const PxFillGradientEffectSchema = implementsInterface<_PxFillGradientEffect>()(px.object({\n type: px.enum([PxGradientType.linear, PxGradientType.radial] as const),\n p1: px.tuple([px.number(), px.number()] as const).optional(),\n p2: px.tuple([px.number(), px.number()] as const).optional(),\n c: px.tuple([px.number(), px.number()] as const).optional(),\n r: px.number().optional(),\n fp: px.tuple([px.number(), px.number()] as const).optional(),\n stops: PxAnimatableGradientStopsSchema.optional(),\n gradientUnits: px.string().optional(),\n spreadMethod: px.string().optional(),\n gradientTransform: px.string().optional(),\n}));\nexport type PxFillGradientEffect = PxInfer<typeof PxFillGradientEffectSchema>;\nconst _ck_PxFillGradientEffect: KeysMatch<PxFillGradientEffect, _PxFillGradientEffect> = true;\n\n/** Stroke gradient is the same shape as fill gradient; the difference is\n * only which host attribute (`fill` vs `stroke`) the applier rewrites. */\nexport type _PxStrokeGradientEffect = _PxFillGradientEffect;\nexport const PxStrokeGradientEffectSchema = PxFillGradientEffectSchema;\nexport type PxStrokeGradientEffect = PxFillGradientEffect;\n\n/** Text-path effect on a `<text>` host. The path geometry is carried INLINE as\n * `path` (an SVG `d`; static for now, keyframed animation is a later step) — the\n * applier mints a `<path>` def from it and wraps the text's children in a native\n * `<textPath href=\"#…\">` at apply time. All SVG-native textPath attrs\n * (`lengthAdjust`, `method`, `spacing`, `startOffset`, `textLength`) ride on this\n * effect; `startOffset`/`textLength` accept the full `PxAnimatable<number>` shape.\n *\n * `pathOverflow` controls what happens to glyphs past the end of an OPEN path:\n * - `'extend'` (default): glyphs continue straight along the endpoint tangent\n * (Lottie / native-glyph behavior).\n * - `'clip'`: glyphs past the end disappear (native `<textPath>` behavior). */\nexport interface _PxTextPathEffect {\n path: string; // inline SVG `d`\n pathOverflow?: string; // 'clip' | 'extend' (default 'extend')\n lengthAdjust?: string; // 'spacing' | 'spacingAndGlyphs'\n method?: string; // 'align' | 'stretch'\n spacing?: string; // 'auto' | 'exact'\n startOffset?: PxAnimatable<number>;\n textLength?: PxAnimatable<number>;\n}\nexport const PxTextPathEffectSchema = implementsInterface<_PxTextPathEffect>()(px.object({\n path: px.string(),\n pathOverflow: px.string().optional(),\n lengthAdjust: px.string().optional(),\n method: px.string().optional(),\n spacing: px.string().optional(),\n startOffset: PxAnimatableNumberSchema.optional(),\n textLength: PxAnimatableNumberSchema.optional(),\n}));\nexport type PxTextPathEffect = PxInfer<typeof PxTextPathEffectSchema>;\nconst _ck_PxTextPathEffect: KeysMatch<PxTextPathEffect, _PxTextPathEffect> = true;\n\n\n/**\n * `effects.text` — text-rendering options for a `<text>` node.\n *\n * `useGlyphs: true` tells the player to render this text from the embedded\n * per-glyph outlines in `definitions.glyphs` (self-contained, no external\n * font) instead of a native `<text>`. See svga.text.design.md.\n */\nexport interface _PxTextEffect {\n useGlyphs?: boolean;\n}\nexport const PxTextEffectSchema = implementsInterface<_PxTextEffect>()(px.object({\n useGlyphs: px.boolean().optional(),\n}));\nexport type PxTextEffect = PxInfer<typeof PxTextEffectSchema>;\nconst _ck_PxTextEffect: KeysMatch<PxTextEffect, _PxTextEffect> = true;\n\n\n/** The full `node.effects` bucket. Closed — each known effect is declared\n * (strict-mode validation flags an unknown effect key as a wire-format drift). */\nexport interface _PxEffects {\n transformation?: _PxTransformationEffect;\n repeater?: _PxRepeaterEffect;\n maskedBy?: _PxMaskedByEffect;\n clipPath?: _PxClipPathEffect;\n trimPath?: _PxTrimPathEffect;\n clone?: _PxCloneEffect;\n isCombinedShape?: boolean;\n fillGradient?: _PxFillGradientEffect;\n strokeGradient?: _PxStrokeGradientEffect;\n textPath?: _PxTextPathEffect;\n text?: _PxTextEffect;\n}\nexport const PxEffectsSchema = implementsInterface<_PxEffects>()(px.object({\n transformation: PxTransformationEffectSchema.optional(),\n repeater: PxRepeaterEffectSchema.optional(),\n maskedBy: PxMaskedByEffectSchema.optional(),\n clipPath: PxClipPathEffectSchema.optional(),\n trimPath: PxTrimPathEffectSchema.optional(),\n clone: PxCloneEffectSchema.optional(),\n isCombinedShape: px.boolean().optional(),\n fillGradient: PxFillGradientEffectSchema.optional(),\n strokeGradient: PxStrokeGradientEffectSchema.optional(),\n textPath: PxTextPathEffectSchema.optional(),\n text: PxTextEffectSchema.optional(),\n}));\nexport type PxEffects = PxInfer<typeof PxEffectsSchema>;\nconst _ck_PxEffects: KeysMatch<PxEffects, _PxEffects> = true;\n\n/**\n * Walks `root` and validates every `node.effects` bucket against `PxEffectsSchema`.\n * Returns an array of human-readable warning strings (empty when all good).\n * Doesn't mutate the tree. Called by `createAnimatorImpl` before applying effects.\n *\n * Pass `strict: true` to also flag undeclared keys (useful in dev / tests).\n */\nexport function validateNodeEffects(root: PxNode, opts?: { strict?: boolean }): Array<string> {\n const warnings: Array<string> = [];\n // `path` is a human-readable breadcrumb prepended to each warning so the\n // reader can locate the offending node in the tree (e.g.\n // `root.children[0].children[2].effects.transformation.translate: …`).\n const walk = (node: PxNode, path: string): void => {\n if (node && node.effects) {\n const ctx: PxValidationContext = { errors: [], warnings: [], strict: !!opts?.strict };\n const ok = PxEffectsSchema.isValid(node.effects, ctx, [path + '.effects']);\n if (!ok) {\n for (const err of ctx.errors) warnings.push(err);\n }\n }\n if (node && Array.isArray(node.children)) {\n node.children.forEach((c, i) => walk(c, path + '.children[' + i + ']'));\n }\n };\n walk(root, 'root');\n return warnings;\n}\n\n\n// ============================================================================\n// NODE\n// ============================================================================\n\n/**\n * Base shape for all SVG element nodes.\n * Open object: validated known keys + arbitrary SVG attributes whose values are\n * either primitives (static) or PxPropertyAnimation objects (in-place animation).\n * Non-recursive — excludes `children` (circular reference). Used for type extraction via PxInfer.\n *\n * `{ type:string, style?:…, [key:string]: string|number|PxPropertyAnimation }`\n */\nexport const PxNodeBase = px.openObject({\n type: px.string(),\n id: px.string().optional(),\n meta: px.any().optional(),\n // Player-effects bucket emitted by the Editor's lightweight design format.\n // Consumed and removed by `applyPlayerEffects` before any other normalisation\n // (see `createAnimatorImpl`), so downstream code never sees it.\n effects: PxEffectsSchema.optional(),\n // `PxElementAnimation` (not just `PxAnimationDefinition`) — accepts\n // string ref / array of refs / inline definition / mixed array; mirrors\n // `animator.animate` map values and what `processNode` resolves at runtime.\n animate: PxElementAnimationSchema.optional(),\n style: px.union([px.string(), px.record(px.union([px.string(), px.number()]))]).optional(),\n}, PxAttrValueSchema);\n\n// `let` so the lazy closure can capture the variable reference after assignment.\n// By the time the lazy resolves (first isValid/sanitize call), PxNodeSchema is assigned.\n// `PxNodeBase & { children?:PxNode[] }`\nlet PxNodeSchema: PxSchema<any> = px.openObject({\n ...PxNodeBase._shape,\n children: px.lazy(() => px.array(PxNodeSchema), []).optional(),\n}, PxAttrValueSchema);\nexport { PxNodeSchema };\n\n/**\n * Base interface for all SVG elements.\n * Extends schema-derived typed fields; adds recursive children and the open\n * index signature for arbitrary SVG attributes (cx, cy, r, fill, etc.).\n * Named properties take precedence over the index signature when accessed.\n */\nexport interface PxNode extends PxInfer<typeof PxNodeBase> {\n children?: PxNode[];\n [key: string]: any;\n}\n\n\n// ============================================================================\n// SVG NODE (ROOT)\n// ============================================================================\n\n/**\n * Root SVG element containing the entire animated graphic.\n * Extends PxNode with SVG-specific properties and global configuration.\n */\nexport interface _PxSvgNode extends PxNode {\n\n /** FIXME - do we need it? SVG viewport width */\n width?: number;\n\n /** FIXME - do we need it? SVG viewport height */\n height?: number;\n\n /** FIXME - do we need it? SVG viewBox attribute defining coordinate system */\n viewBox?: string;\n\n /** Global animation configuration */\n animator?: PxAnimatorConfig;\n}\n\n/**\n * Extra fields present on the root SVG node, on top of PxNode.\n * Used for type extraction via PxInfer.\n *\n * `{ width?:number, height?:number, viewBox?:string, animator?:AnimatorConfig }`\n */\nexport const PxSvgNodeExtra = px.object({\n width: px.number().optional(),\n height: px.number().optional(),\n viewBox: px.string().optional(),\n animator: PxAnimatorConfigSchema.optional(),\n});\n\n/**\n * Root SVG element containing the entire animated graphic.\n * Extends PxNode (inheriting the open index signature) plus schema-derived\n * SVG-root fields.\n */\nexport interface PxSvgNode extends PxNode, PxInfer<typeof PxSvgNodeExtra> {\n}\n\n\n// ============================================================================\n// DOCUMENT\n// ============================================================================\n\n/**\n * Root SVG document schema. Enforces `type === 'svg'` to distinguish from child nodes.\n * This is the root type for the entire file format.\n *\n * `{ type:'svg', style?:…, width?:number, height?:number,\n * viewBox?:string, animator?:AnimatorConfig, children?:PxNode[],\n * [svgAttr]: string|number|PxPropertyAnimation }`\n */\nexport const PxAnimatedSvgDocumentSchema = px.openObject({\n ...PxNodeBase._shape,\n ...PxSvgNodeExtra._shape,\n type: px.literal('svg'), // override string → literal to require 'svg'\n children: px.array(PxNodeSchema).optional()\n}, PxAttrValueSchema);\n\n/**\n * The complete animated SVG document.\n * This is the root type for the entire file format.\n */\nexport interface PxAnimatedSvgDocument extends PxSvgNode {\n}\n\n\n// ============================================================================\n// API INTERFACES\n// ============================================================================\n\n/** A configuration object for animation lifecycle callbacks. */\nexport interface PxAnimatorCallbacksConfig {\n\n /** Callback executed when the animation starts or resumes. */\n onPlay?: () => void;\n\n /** Callback executed when the animation is paused. */\n onPause?: () => void;\n\n /** Callback executed when the animation is cancelled. */\n onCancel?: () => void;\n\n /** Callback executed when the animation finishes naturally. */\n onFinish?: () => void;\n\n /** Callback executed when the animation is removed. */\n onRemove?: () => void;\n}\n\n\nexport type PxPoint2D = Array<number>;\n\n\n// ============================================================================\n// BEZIER PATH\n// ============================================================================\n\n/** Represents a vector path for SVG shape animations. */\nexport interface _PxBezierPath {\n\n /** An array of vertex points [[x, y], ...]. */\n v: Array<PxPoint2D>;\n\n /** An array of 'in' tangent handles for each vertex [[x, y], ...]. */\n i?: Array<PxPoint2D>;\n\n /** An array of 'out' tangent handles for each vertex [[x, y], ...]. */\n o?: Array<PxPoint2D>;\n\n /** A boolean indicating if the path is closed. */\n c?: boolean;\n}\n\n// `{ v:number[][], i?:number[][], o?:number[][], c?:boolean }`\nexport const PxBezierPathSchema = implementsInterface<_PxBezierPath>()(px.object({\n v: px.array(px.array(px.number())),\n i: px.array(px.array(px.number())).optional(),\n o: px.array(px.array(px.number())).optional(),\n c: px.boolean().optional(),\n}));\n\n/** Represents a vector path for SVG shape animations. */\nexport type PxBezierPath = PxInfer<typeof PxBezierPathSchema>;\nconst _ck_PxBezierPath: KeysMatch<PxBezierPath, _PxBezierPath> = true; // the key sets are identical\n\n\n// ============================================================================\n// ANIMATOR API\n// ============================================================================\n\n/**\n * Basic animation controls common to all animator types.\n *\n * Generic over the platform's root-element type (`TRoot`) so this package stays\n * platform-neutral: the web player specialises it to the DOM `Element`, a\n * React Native player to its own view handle. Defaults to `unknown`.\n */\nexport interface PxBasicAnimatorAPI<TRoot = unknown> {\n\n isReady(): boolean;\n\n /** Returns the root element for the animation (platform-specific type). */\n getRootElement(): TRoot | null;\n\n /** Returns true if the animation is currently running. */\n isPlaying(): boolean;\n\n /** Starts or resumes the animation. */\n play(): void;\n\n /** Pauses the animation at its current state. */\n pause(): void;\n\n /** Stops the animation and resets it to its initial state. */\n cancel(): void;\n\n}\n\n/** The full programmatic control interface for an animation. */\nexport interface PxAnimatorAPI<TRoot = unknown> extends PxBasicAnimatorAPI<TRoot> {\n\n /** Jumps to the end of the animation and holds the final state. */\n finish(): void;\n\n /** Changes the speed of the animation. 1 is normal, 2 is double, -1 is reverse. */\n setPlaybackRate(rate: number): void;\n\n /** Returns the current playback time in milliseconds. */\n getCurrentTime(): number | null;\n\n /** Jumps to a specific time (in milliseconds) in the animation. */\n setCurrentTime(time: number): void;\n\n /** Stops the animation and cleans up all associated resources. */\n destroy(): void;\n}\n\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\nexport function isPxElementFileFormat(fileJson: any): fileJson is PxAnimatedSvgDocument {\n if (!(\n fileJson &&\n typeof fileJson === 'object' &&\n !Array.isArray(fileJson)\n )) {\n return false;\n }\n\n return fileJson['type'] === 'svg' || fileJson['tagName'] === 'svg';\n}\n\n\n// ============================================================================\n// DEEP VALIDATION\n// ============================================================================\n\nexport interface PxValidationResult {\n valid: boolean;\n errors: string[];\n}\n\n/**\n * Deep validation of PxAnimatedSvgDocument using the PxAnimatedSvgDocumentSchema.\n * @returns PxValidationResult with valid flag and array of error messages\n */\nexport function isPxElementFileFormatDeep(fileJson: any): PxValidationResult {\n const valid: boolean = PxAnimatedSvgDocumentSchema.isValid(fileJson);\n return { valid, errors: valid ? [] : ['Document failed schema validation'] };\n}\n\nexport function getAnimatorConfig(doc: PxAnimatedSvgDocument): PxAnimatorConfig | undefined {\n return (\n doc?.animator || doc?.meta?.animator ||\n doc?.animation || doc?.meta?.animation // FIXME - decide on the name\n );\n}\n\nexport function getDefs(doc: PxAnimatedSvgDocument): PxDefs | undefined {\n if (!doc) return undefined;\n return getAnimatorConfig(doc)?.definitions;\n}\n\nexport function getBindings(doc: PxAnimatedSvgDocument): PxBinding[] | undefined {\n if (!doc) return undefined;\n const animate = getAnimatorConfig(doc)?.animate;\n if (!animate) return undefined;\n return Object.entries(animate).map(([id, anim]) => ({ id, animate: anim }));\n}\n\n// FIXME - do we need it?\nexport function getChildren(doc: PxAnimatedSvgDocument): PxNode[] | undefined {\n return doc?.children;\n}","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport type { PxBezierPath, PxTransformParts } from './PxAnimatorTypes';\n\n\n/**\n * Converts a PxBezierPath to an SVG path string.\n * Control points (i, o) are treated as ABSOLUTE coordinates.\n * @param {PxBezierPath} path\n * @returns {string}\n */\n/**\n * @param forceCurves Emit EVERY segment (incl. the closing one) as a cubic `C`, even when\n * its control points are degenerate (a straight line). Needed for keyframe values the\n * BROWSER interpolates (WAAPI / CSS `path()`): CSS only interpolates paths with\n * IDENTICAL command sequences, so an opportunistic `L` in one keyframe vs a `C` in the\n * next (e.g. a round-corner radius animating from 0) turns the whole animation\n * DISCRETE — it flips at 50% instead of morphing.\n */\nexport function bezierToSvgPath(path: PxBezierPath, forceCurves = false): string {\n const v = path.v;\n const i = path.i;\n const o = path.o;\n const c = path.c;\n\n if (!v.length) return \"\";\n\n const d: Array<string> = [];\n const len = v.length;\n d.push(\"M\" + v[0][0] + \",\" + v[0][1]);\n\n for (let idx = 1; idx < len; idx++) {\n const prevV = v[idx - 1];\n const prevO = o?.[idx - 1] ?? prevV;\n const currI = i?.[idx] ?? v[idx];\n const currV = v[idx];\n\n // Check if it's a straight line (control points coincide with vertices)\n const isLine = !forceCurves && (prevO[0] === prevV[0] && prevO[1] === prevV[1]) &&\n (currI[0] === currV[0] && currI[1] === currV[1]);\n\n if (isLine) {\n d.push(\"L\" + currV[0] + \",\" + currV[1]);\n } else {\n // Control points are absolute coordinates\n d.push(\"C\" + prevO[0] + \",\" + prevO[1] + \",\" + currI[0] + \",\" + currI[1] + \",\" + currV[0] + \",\" + currV[1]);\n }\n }\n\n if (c && len > 0) {\n const lastV = v[len - 1];\n const lastO = o?.[len - 1] ?? lastV;\n const firstI = i?.[0] ?? v[0];\n const firstV = v[0];\n\n // Check if closing segment is a straight line\n const isLine = !forceCurves && (lastO[0] === lastV[0] && lastO[1] === lastV[1]) &&\n (firstI[0] === firstV[0] && firstI[1] === firstV[1]);\n\n if (!isLine) {\n d.push(\"C\" + lastO[0] + \",\" + lastO[1] + \",\" + firstI[0] + \",\" + firstI[1] + \",\" + firstV[0] + \",\" + firstV[1]);\n }\n\n d.push(\"z\");\n }\n\n return d.join(\"\");\n}\n\n/**\n * @param {number} a \n * @param {number} b \n * @param {number} t \n * @returns {number}\n */\nexport function interpolateNum(a: number, b: number, t: number): number {\n return a + (b - a) * t;\n}\n\n\n/**\n * @param {Array<number>} a \n * @param {Array<number>} b \n * @param {number} t \n * @returns {Array<number>}\n */\nexport function interpolateVec(a: Array<number>, b: Array<number>, t: number): Array<number> {\n const res: Array<number> = [];\n const count = Math.max(a.length, b.length);\n for (let i = 0; i < count; i++) {\n res[i] = interpolateNum(a[i] || 0, b[i] || 0, t);\n }\n return res;\n}\n\n/**\n * Interpolates between two color arrays [r, g, b] or [r, g, b, a].\n * Normalizes both colors to 4 elements, defaulting alpha to 1 if missing.\n */\nexport function interpolateColor(a: Array<number>, b: Array<number>, t: number): Array<number> {\n return [\n interpolateNum(a[0] || 0, b[0] || 0, t),\n interpolateNum(a[1] || 0, b[1] || 0, t),\n interpolateNum(a[2] || 0, b[2] || 0, t),\n interpolateNum(a[3] === undefined ? 1 : a[3], b[3] === undefined ? 1 : b[3], t)\n ];\n}\n\n/**\n * Interpolates between two arrays of bezier paths.\n * @param paths1 The starting array of paths.\n * @param paths2 The ending array of paths.\n * @param progress The interpolation progress from 0.0 to 1.0.\n */\nexport function interpolateBeziers(\n paths1: Array<PxBezierPath>,\n paths2: Array<PxBezierPath>,\n progress: number\n): Array<PxBezierPath> {\n const count = Math.max(paths1.length, paths2.length);\n const res: Array<PxBezierPath> = [];\n for (let i = 0; i < count; i++) {\n res.push(interpolateBezier(paths1[i], paths2[i], progress));\n }\n return res;\n}\n\n/**\n * Interpolates between two bezier paths.\n * Control points (i, o) are treated as ABSOLUTE coordinates.\n * When control points are missing, they default to the vertex position.\n * @param {PxBezierPath} path1\n * @param {PxBezierPath} path2\n * @param {number} progress\n * @returns {PxBezierPath}\n */\nexport function interpolateBezier(\n path1: PxBezierPath | undefined,\n path2: PxBezierPath | undefined,\n progress: number\n): PxBezierPath {\n if (!path1 || !path2) return path1 || path2 || { v: [] };\n\n const t = Math.min(Math.max(progress, 0), 1);\n const len = Math.min(path1.v.length, path2.v.length);\n\n const v: Array<Array<number>> = [];\n const i: Array<Array<number>> = [];\n const o: Array<Array<number>> = [];\n\n for (let idx = 0; idx < len; idx++) {\n const v1 = path1.v[idx];\n const v2 = path2.v[idx];\n v.push(interpolateVec(v1, v2, t));\n\n // For absolute control points, default to vertex position (straight line)\n const i1 = path1.i?.[idx] ?? v1;\n const i2 = path2.i?.[idx] ?? v2;\n i.push(interpolateVec(i1, i2, t));\n\n const o1 = path1.o?.[idx] ?? v1;\n const o2 = path2.o?.[idx] ?? v2;\n o.push(interpolateVec(o1, o2, t));\n }\n\n return { v, i: i.length ? i : undefined, o: o.length ? o : undefined, c: path1.c ?? path2.c };\n}\n\n\n/**\n * Remap a number from one range to another.\n *\n * @param {number} value - The input value.\n * @param {number} inMin - Lower bound of the input range.\n * @param {number} inMax - Upper bound of the input range.\n * @param {number} outMin - Lower bound of the output range.\n * @param {number} outMax - Upper bound of the output range.\n * @returns The remapped value.\n */\nexport function remap(\n value: number,\n inMin: number,\n inMax: number,\n outMin: number,\n outMax: number\n): number {\n if (inMax === inMin) return outMin; // avoid divide-by-zero\n const t = (value - inMin) / (inMax - inMin);\n return outMin + t * (outMax - outMin);\n}\n\n/**\n * Solves for the parameter t such that the cubic bezier X(t) = x,\n * where the bezier has control point x-coordinates p1x and p2x\n * (endpoints are fixed at x=0 and x=1).\n * Uses Newton-Raphson with bisection fallback.\n */\nexport function solveCubicBezierX(p1x: number, p2x: number, x: number): number {\n if (x <= 0) return 0;\n if (x >= 1) return 1;\n\n const cx = 3 * p1x;\n const bx = 3 * (p2x - p1x) - cx;\n const ax = 1 - cx - bx;\n\n function sampleX(t: number) { return ((ax * t + bx) * t + cx) * t; }\n function sampleDX(t: number) { return (3 * ax * t + 2 * bx) * t + cx; }\n\n let t2 = x;\n let t0 = 0;\n let t1 = 1;\n\n for (let i = 0; i < 8; i++) {\n const x2 = sampleX(t2) - x;\n if (Math.abs(x2) < 1e-6) return t2;\n const d2 = sampleDX(t2);\n if (Math.abs(d2) < 1e-6) break;\n t2 -= x2 / d2;\n }\n\n t2 = x;\n while (t0 < t1) {\n const x2 = sampleX(t2);\n if (Math.abs(x2 - x) < 1e-6) return t2;\n if (x > x2) t0 = t2;\n else t1 = t2;\n t2 = (t1 + t0) / 2;\n }\n\n return t2;\n}\n\n/**\n * Creates a cubic-bezier easing function.\n * @param easing An array of four numbers [x1, y1, x2, y2] defining the bezier curve.\n * @returns A function that takes a progress value (0-1) and returns an eased value.\n */\nexport function cubicBezier(easing: [number, number, number, number]) {\n const [p1x, p1y, p2x, p2y] = easing;\n\n const cy = 3 * p1y;\n const by = 3 * (p2y - p1y) - cy;\n const ay = 1 - cy - by;\n\n function sampleCurveY(t: number) { return ((ay * t + by) * t + cy) * t; }\n\n return function (x: number) {\n return sampleCurveY(solveCubicBezierX(p1x, p2x, x));\n };\n}\n\ntype Point2 = [number, number];\n\nfunction lerp2(a: Point2, b: Point2, t: number): Point2 {\n return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t];\n}\n\n/**\n * Splits a cubic bezier curve at parameter t using De Casteljau's algorithm.\n * Returns the left and right sub-curves as 4-point tuples.\n */\nexport function subdivideCubicBezier(\n p0: Point2, p1: Point2, p2: Point2, p3: Point2, t: number\n): { left: [Point2, Point2, Point2, Point2], right: [Point2, Point2, Point2, Point2] } {\n const q0 = lerp2(p0, p1, t);\n const q1 = lerp2(p1, p2, t);\n const q2 = lerp2(p2, p3, t);\n const r0 = lerp2(q0, q1, t);\n const r1 = lerp2(q1, q2, t);\n const s = lerp2(r0, r1, t);\n return {\n left: [p0, q0, r0, s],\n right: [s, r1, q2, p3]\n };\n}\n\ntype Easing = [number, number, number, number];\n\n/**\n * Splits a CSS cubic-bezier easing [x1,y1,x2,y2] at a given x-axis fraction.\n * Each half is re-normalized to map [0,0]→[1,1].\n * Returns undefined for either half if the input is undefined (linear) or the split is degenerate.\n */\nexport function splitEasing(\n easing: Easing | undefined,\n xFraction: number\n): { left: Easing | undefined, right: Easing | undefined } {\n if (!easing) return { left: undefined, right: undefined };\n if (xFraction <= 0) return { left: undefined, right: easing };\n if (xFraction >= 1) return { left: easing, right: undefined };\n\n const [x1, y1, x2, y2] = easing;\n const t = solveCubicBezierX(x1, x2, xFraction);\n\n const p0: Point2 = [0, 0];\n const p1: Point2 = [x1, y1];\n const p2: Point2 = [x2, y2];\n const p3: Point2 = [1, 1];\n\n const { left, right } = subdivideCubicBezier(p0, p1, p2, p3, t);\n\n // Split point coordinates\n const sx = left[3][0];\n const sy = left[3][1];\n\n let leftEasing: Easing | undefined;\n if (sx > 1e-9 && Math.abs(sy) > 1e-9) {\n leftEasing = [\n left[1][0] / sx, left[1][1] / sy,\n left[2][0] / sx, left[2][1] / sy\n ];\n }\n\n let rightEasing: Easing | undefined;\n const rx = 1 - sx;\n const ry = 1 - sy;\n if (rx > 1e-9 && Math.abs(ry) > 1e-9) {\n rightEasing = [\n (right[1][0] - sx) / rx, (right[1][1] - sy) / ry,\n (right[2][0] - sx) / rx, (right[2][1] - sy) / ry\n ];\n }\n\n return { left: leftEasing, right: rightEasing };\n}\n\n/**\n * Reverses a cubic-bezier easing for backward playback.\n * [x1,y1,x2,y2] → [1-x2, 1-y2, 1-x1, 1-y1].\n */\nexport function reverseEasing(easing: Easing | undefined): Easing | undefined {\n if (!easing) return undefined;\n return [1 - easing[2], 1 - easing[3], 1 - easing[0], 1 - easing[1]];\n}\n\n/**\n * Converts a color from a [r, g, b, a] array (where values are 0-1) to an rgba() or rgb() CSS string.\n * @param color The color array.\n */\nexport function toRGBA(color: Array<number>): string {\n const r = Math.round(color[0] * 255);\n const g = Math.round(color[1] * 255);\n const b = Math.round(color[2] * 255);\n return color.length === 4 ?\n 'rgba(' + r + ',' + g + ',' + b + ',' + color[3] + ')' :\n 'rgb(' + r + ',' + g + ',' + b + ')';\n}\n\n/** Parse rgb/rgba string to normalized array */\nexport function parseRgba(s: string): number[] {\n const inner = s.match(/rgba?\\((.*)\\)/)?.[1];\n if (!inner) throw new Error('Invalid rgb/rgba format');\n const parts = inner.split(',').map(v => +v.trim());\n return [parts[0] / 255, parts[1] / 255, parts[2] / 255, ...(parts[3] !== undefined ? [parts[3]] : [])];\n}\n\n/** Parse hex string to normalized array (#RGB, #RGBA, #RRGGBB, #RRGGBBAA) */\nfunction parseHex(s: string): number[] {\n const hex = s.slice(1); // Remove '#'\n const isShort = hex.length <= 4; // #RGB or #RGBA vs #RRGGBB or #RRGGBBAA\n\n const r = isShort ? hex[0] + hex[0] : hex.slice(0, 2);\n const g = isShort ? hex[1] + hex[1] : hex.slice(2, 4);\n const b = isShort ? hex[2] + hex[2] : hex.slice(4, 6);\n const a = hex.length === 4 ? hex[3] + hex[3] : hex.length === 8 ? hex.slice(6, 8) : null;\n\n const result = [\n parseInt(r, 16) / 255,\n parseInt(g, 16) / 255,\n parseInt(b, 16) / 255\n ];\n\n if (a !== null) {\n result.push(parseInt(a, 16) / 255);\n }\n\n return result;\n}\n\n//// FIXME - support normalisation of config from different formats\n/** Parse color string (hex or rgb/rgba) to normalized [r, g, b] or [r, g, b, a] array (0-1 range) */\nexport function parseColor(s: any): number[] | undefined {\n if (!s) return undefined;\n if (Array.isArray(s)) return s;\n if (typeof s !== 'string') return undefined;\n if (s.startsWith('#')) {\n return parseHex(s);\n } else if (s.startsWith('rgb')) {\n return parseRgba(s);\n } else {\n // FIXME - come up with some solution how to report errors...\n console.warn('Unsupported color format: ' + s);\n }\n return undefined;\n}\n\nexport const COLOUR_ATTR_NAMES = new Set([\"color\", \"fill\", \"flood-color\", \"lighting-color\", \"stop-color\", \"stroke\"]);\nexport const TRANSFORM_FN_NAMES = new Set([\"translate\", \"rotate\", \"scale\", \"skew\"]);\nexport const PCT_BASED_ATTR_NAMES = new Set([\"offset-distance\", \"offsetDistance\"]);\n\n/**\n * Compose a `PxTransformParts` record into a single SVG/CSS transform string in\n * the canonical order:\n *\n * translate, translate(+origin), rotate, scale, translate(-origin)\n *\n * Each part is omitted when not present. `origin` becomes a `translate(+o)` /\n * `translate(-o)` pair surrounding the rotate/scale segment — the SVG-native\n * way to render a transform-origin pivot.\n *\n * @param parts the parts record (translate / rotate / scale / origin)\n * @param opts.withUnits when true (default), translates use `px` and rotate\n * uses `deg` — required for CSS / WebAnimations keyframes. When false, no\n * units are emitted — required for the SVG `transform` attribute.\n */\nexport function composeTransformParts(\n parts: PxTransformParts | null | undefined,\n opts?: { withUnits?: boolean }\n): string {\n if (!parts) return '';\n const withUnits = opts?.withUnits ?? true;\n const segs: Array<string> = [];\n const t = parts.translate;\n const o = parts.origin;\n const r = parts.rotate;\n const k = parts.skew;\n const s = parts.scale;\n const tu = withUnits ? 'px' : '';\n const ru = withUnits ? 'deg' : '';\n if (t) segs.push('translate(' + t[0] + tu + ',' + t[1] + tu + ')');\n if (o) segs.push('translate(' + o[0] + tu + ',' + o[1] + tu + ')');\n if (r !== undefined && r !== null) segs.push('rotate(' + r + ru + ')');\n // Canonical slot: between rotate and scale (Lottie-compatible; pivots at origin).\n if (k !== undefined && k !== null) segs.push('skewX(' + k + ru + ')');\n if (s) segs.push('scale(' + s[0] + ',' + s[1] + ')');\n if (o) segs.push('translate(' + (-o[0]) + tu + ',' + (-o[1]) + tu + ')');\n return segs.join('');\n}\nexport const STYLE_ATTR_NAMES = new Set([\"offset-distance\", \"offsetDistance\"]); // Props that need to go to style\nexport const DEFAULT_DURATION_MS = 1000;\n\n/**\n * Converts a kebab-case string to camelCase.\n * @param kebab The kebab-case string.\n */\nexport function kebabToCamelCaseWord(kebab: string): string {\n return kebab.includes('-') ? kebab.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()) : kebab;\n}\n\n/**\n * Checks if a string is in camelCase.\n * @param word The string to check.\n */\nexport function isCamelCaseWord(word: string): boolean {\n return !word.includes('-') && /[a-z][A-Z]/.test(word);\n}\n\n// FIXME - docs, rename?\nconst SVG_CAMEL_CASE_ATTRS = new Set([\n // Transform/positioning\n 'viewBox',\n 'preserveAspectRatio',\n\n // Gradient\n 'gradientUnits',\n 'gradientTransform',\n 'spreadMethod',\n\n // Pattern\n 'patternUnits',\n 'patternContentUnits',\n 'patternTransform',\n\n // Clipping/masking\n 'clipPathUnits',\n 'maskUnits',\n 'maskContentUnits',\n\n // Marker (SVG spec keeps these camelCase, like viewBox)\n 'markerUnits',\n 'markerWidth',\n 'markerHeight',\n 'refX',\n 'refY',\n\n // Text\n 'textLength',\n 'lengthAdjust',\n 'startOffset',\n\n // Filter\n 'filterUnits',\n 'primitiveUnits',\n 'tableValues', // feFuncR/G/B/A transfer table (type=\"table\")\n 'stdDeviation',\n 'baseFrequency',\n 'numOctaves',\n 'surfaceScale',\n 'diffuseConstant',\n 'specularConstant',\n 'specularExponent',\n 'kernelMatrix',\n 'kernelUnitLength',\n 'edgeMode',\n 'preserveAlpha',\n 'targetX',\n 'targetY',\n\n // // Animation\n // 'attributeName',\n // 'attributeType',\n // 'calcMode',\n // 'keyTimes',\n // 'keySplines',\n // 'repeatCount',\n // 'repeatDur' \n]);\n\n/**\n * Converts a camelCase string to kebab-case.\n * @param camel The camelCase string.\n */\nexport function camelCaseToKebabWordIfNeeded(camel: string): string { // FIXME - docs, rename function?\n return SVG_CAMEL_CASE_ATTRS.has(camel) ?\n camel :\n camel.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();\n}\n\n/**\n * Checks if a CSS property is set inline on an element's style.\n *\n * Typed structurally (not as the DOM `CSSStyleDeclaration`) so this package\n * stays platform-neutral; a real `element.style` satisfies the shape.\n *\n * @param style - element.style (CSSStyleDeclaration-shaped)\n * @param propName - property name (camelCase or kebab-case)\n */\nexport function hasStyleProp(\n style: { getPropertyValue(propName: string): string },\n propName: string\n): boolean {\n return style.getPropertyValue(propName) !== '';\n}\n\n/**\n * Clamps a number between a minimum and maximum value.\n * @param value The number to clamp.\n * @param min The minimum value.\n * @param max The maximum value.\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(value, max));\n}\n\n\n// ============================================================================\n// 2D CUBIC BÉZIER PRIMITIVES — motion-along-path support\n// ============================================================================\n//\n// Hand-written, dependency-free 2D Bézier maths used by the motion-along-path\n// playback paths (both WAAPI normalisation and frames-mode direct compute).\n// See `fix-motion-along-path--fix-plan.md` for the wider plan.\n//\n// Conventions:\n// - Points are `[x, y]` tuples (`Point2`) — matches the wire format.\n// - A cubic segment is `(P0, P1, P2, P3)` where `P0` and `P3` are the\n// endpoints and `P1`, `P2` are the control points in ABSOLUTE coordinates.\n// - The Lottie-style tangent storage convention is `kf.to` =\n// outgoing-from-kf-as-a-delta, `kf.ti` = incoming-at-the-next-kf-as-a-delta.\n// The wire format re-attaches them to the natural endpoints as\n// `tangentOut` on the FROM keyframe and `tangentIn` on the TO keyframe.\n// Caller is responsible for the position-to-control-point lift, i.e.\n// `P1 = fromKf.value + fromKf.tangentOut`, `P2 = toKf.value + toKf.tangentIn`.\n\n\n/**\n * Evaluate a 2D cubic Bézier at parameter `t ∈ [0, 1]` via Bernstein form:\n *\n * B(t) = (1-t)³ P0 + 3t(1-t)² P1 + 3t²(1-t) P2 + t³ P3\n *\n * `t` is the curve PARAMETER, not arc-length. For arc-length (CSS Motion Path\n * / `offset-distance`) semantics, use `bezier2D_tForDistance` first to convert\n * a distance to its parameter, then call this. Out-of-range `t` is clamped.\n */\nexport function bezier2D_pointAt(\n P0: Point2, P1: Point2, P2: Point2, P3: Point2,\n t: number\n): Point2 {\n if (t <= 0) return [P0[0], P0[1]];\n if (t >= 1) return [P3[0], P3[1]];\n const u = 1 - t;\n const u2 = u * u;\n const u3 = u2 * u;\n const t2 = t * t;\n const t3 = t2 * t;\n const w0 = u3;\n const w1 = 3 * t * u2;\n const w2 = 3 * t2 * u;\n const w3 = t3;\n return [\n w0 * P0[0] + w1 * P1[0] + w2 * P2[0] + w3 * P3[0],\n w0 * P0[1] + w1 * P1[1] + w2 * P2[1] + w3 * P3[1],\n ];\n}\n\n\n/**\n * Evaluate the derivative `B'(t)` of a 2D cubic Bézier at parameter `t`.\n *\n * B'(t) = 3(1-t)² (P1-P0) + 6t(1-t) (P2-P1) + 3t² (P3-P2)\n *\n * Returns the tangent VECTOR (not a unit vector). For auto-orient rotation,\n * caller computes `Math.atan2(d.y, d.x)`.\n *\n * Epsilon-nudge for degenerate endpoints: when a handle coincides with its\n * endpoint (e.g. `P1 === P0` and `t === 0`, common for the start/end of a\n * Lottie spatial-tangent path), the derivative collapses to zero. The\n * exact-endpoint value is then meaningless; we nudge `t` inward by `1e-4`\n * and retry.\n */\nconst BEZIER_T_NUDGE = 1e-4;\nexport function bezier2D_derivativeAt(\n P0: Point2, P1: Point2, P2: Point2, P3: Point2,\n t: number\n): Point2 {\n const result = _bezier2D_derivativeAtRaw(P0, P1, P2, P3, t);\n if (result[0] === 0 && result[1] === 0) {\n // Degenerate (handle = endpoint). Nudge inward and retry.\n const nudgedT = t < 0.5 ? t + BEZIER_T_NUDGE : t - BEZIER_T_NUDGE;\n return _bezier2D_derivativeAtRaw(P0, P1, P2, P3, nudgedT);\n }\n return result;\n}\n\nfunction _bezier2D_derivativeAtRaw(\n P0: Point2, P1: Point2, P2: Point2, P3: Point2,\n t: number\n): Point2 {\n const u = 1 - t;\n const a = 3 * u * u;\n const b = 6 * t * u;\n const c = 3 * t * t;\n return [\n a * (P1[0] - P0[0]) + b * (P2[0] - P1[0]) + c * (P3[0] - P2[0]),\n a * (P1[1] - P0[1]) + b * (P2[1] - P1[1]) + c * (P3[1] - P2[1]),\n ];\n}\n\n\n/**\n * Arc-length lookup table for a 2D cubic Bézier.\n *\n * Samples the curve at `steps + 1` evenly-spaced parameter values\n * (`t = 0, 1/steps, 2/steps, …, 1`), computes the cumulative Euclidean\n * distance between consecutive samples, and returns parallel\n * `Float64Array`s for parameter (`ts`) and arc length (`ds`). `ds[steps]`\n * is the total arc length of the curve.\n *\n * The LUT shape is `{ts, ds}` with parallel Float64Arrays rather than\n * `Array<{t, d}>` because:\n * - One contiguous allocation per array instead of `steps+1` objects.\n * - Binary search in `bezier2D_tForDistance` reads `Float64Array` directly.\n * - The structure is read-only after construction — no need for per-sample\n * field access.\n *\n * Approximation error is roughly `O((1/steps)²)` for smooth curves; the\n * default 100 samples gives <1% error vs analytic arc length on typical\n * motion paths.\n */\nexport interface ArcLengthLUT {\n readonly ts: Float64Array;\n readonly ds: Float64Array;\n}\n\nexport function bezier2D_arcLengthLUT(\n P0: Point2, P1: Point2, P2: Point2, P3: Point2,\n steps: number = 100\n): ArcLengthLUT {\n const n = steps + 1;\n const ts = new Float64Array(n);\n const ds = new Float64Array(n);\n\n let prev = bezier2D_pointAt(P0, P1, P2, P3, 0);\n ts[0] = 0;\n ds[0] = 0;\n\n let cum = 0;\n for (let i = 1; i < n; i++) {\n const t = i / steps;\n const cur = bezier2D_pointAt(P0, P1, P2, P3, t);\n const dx = cur[0] - prev[0];\n const dy = cur[1] - prev[1];\n cum += Math.sqrt(dx * dx + dy * dy);\n ts[i] = t;\n ds[i] = cum;\n prev = cur;\n }\n return { ts, ds };\n}\n\n\n/**\n * Inverse of `bezier2D_arcLengthLUT` lookup: given a distance along the\n * curve, return the curve parameter `t` reached at that distance via\n * binary search on `lut.ds` + linear interpolation between adjacent\n * samples.\n *\n * Distance is clamped to `[0, lut.ds[last]]`. The returned `t` is in\n * `[0, 1]`. Pair with `bezier2D_pointAt` to get the point at that\n * arc-length distance:\n *\n * const t = bezier2D_tForDistance(lut, distance);\n * const point = bezier2D_pointAt(P0, P1, P2, P3, t);\n */\nexport function bezier2D_tForDistance(lut: ArcLengthLUT, distance: number): number {\n const { ts, ds } = lut;\n const last = ds.length - 1;\n if (distance <= 0) return ts[0];\n if (distance >= ds[last]) return ts[last];\n\n // Binary search for the upper-bound index `hi` such that ds[hi-1] <= distance < ds[hi].\n let lo = 1;\n let hi = last;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n if (ds[mid] < distance) lo = mid + 1;\n else hi = mid;\n }\n // Linear interpolate between the bracketing samples.\n const dPrev = ds[hi - 1];\n const dCur = ds[hi];\n const span = dCur - dPrev;\n const frac = span > 0 ? (distance - dPrev) / span : 0;\n return ts[hi - 1] + frac * (ts[hi] - ts[hi - 1]);\n}\n\n\n/**\n * `bezier2D_tForDistance` convenience taking a fraction of the total arc\n * length instead of an absolute distance. `pct` is in `[0, 1]` (CSS Motion\n * Path `offset-distance` semantics — `offset-distance: 50%` ≡\n * `bezier2D_tForDistancePct(lut, 0.5)`). Out-of-range values clamp.\n */\nexport function bezier2D_tForDistancePct(lut: ArcLengthLUT, pct: number): number {\n const total = lut.ds[lut.ds.length - 1];\n return bezier2D_tForDistance(lut, pct * total);\n}\n\n\n/**\n * Inverse of {@link bezier2D_tForDistance}: given a curve parameter `t`,\n * returns the arc length from the start. Binary searches the LUT's `ts`\n * (uniformly spaced) and linearly interpolates `ds` between adjacent samples.\n */\nexport function bezier2D_arcAtT(lut: ArcLengthLUT, t: number): number {\n const { ts, ds } = lut;\n const last = ts.length - 1;\n if (t <= ts[0]) return ds[0];\n if (t >= ts[last]) return ds[last];\n let lo = 1, hi = last;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n if (ts[mid] < t) lo = mid + 1;\n else hi = mid;\n }\n const tPrev = ts[hi - 1];\n const span = ts[hi] - tPrev;\n const frac = span > 0 ? (t - tPrev) / span : 0;\n return ds[hi - 1] + frac * (ds[hi] - ds[hi - 1]);\n}\n\n\n/**\n * Inverse of {@link cubicBezier}: for a CSS easing `[x1,y1,x2,y2]` and a\n * target output `y`, returns the input `x` such that\n * `cubicBezier(easing)(x) ≈ y`. Works for monotonic easings (the CSS\n * default) by swapping the easing's x/y axes — the inverse easing has\n * controls `[y1, x1, y2, x2]`, which `cubicBezier` evaluates directly.\n *\n * `undefined` easing (linear) → identity function.\n */\nexport function invertEasing(easing: Easing | undefined): (y: number) => number {\n if (!easing) return (y) => y;\n const flipped: Easing = [easing[1], easing[0], easing[3], easing[2]];\n return cubicBezier(flipped);\n}","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport type { PxAnimatedSvgDocument } from './PxAnimatorTypes';\n\n\n/**\n * Generates a unique ID with a random suffix.\n * Format: _px_{random base36 string}\n */\nlet _idCounter = 0;\nexport function generateUniqueId(): string {\n const timestamp = Date.now().toString(36);\n const counter = (++_idCounter).toString(36);\n const random = Math.random().toString(36).substring(2, 6);\n return '_px_' + timestamp + counter + random;\n}\n\n/**\n * Deep clones a JSON-like value (objects, arrays, primitives).\n * Does not handle special types like Date, Map, Set, functions, etc.\n */\nexport function deepClone<T>(value: T): T {\n if (value === null || typeof value !== 'object') return value;\n if (Array.isArray(value)) return value.map(item => deepClone(item)) as T;\n\n const obj = value as Record<string, unknown>;\n\n const cloned: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n cloned[key] = deepClone(obj[key]);\n }\n return cloned as T;\n}\n\n/**\n * Regenerates all IDs in the document and updates references.\n *\n * This function:\n * 1. Deep clones the document to avoid mutating the original\n * 2. Traverses all nodes and regenerates IDs, keeping a mapping of old → new\n * 3. Updates all references to old IDs in attributes:\n * - Hash references: \"#old-id\" → \"#new-id\" (href, xlink:href)\n * - URL references: \"url(#old-id)\" → \"url(#new-id)\" (fill, clip-path, mask, marker, etc.)\n * - Style URL references: { offsetPath: \"url(#old-id)\" }\n *\n * @param doc - The animated SVG document to process\n * @returns A new document with regenerated IDs\n */\nexport function generateNewIds(doc: PxAnimatedSvgDocument): PxAnimatedSvgDocument {\n // Deep clone the document\n const cloned: PxAnimatedSvgDocument = deepClone(doc);\n\n // Map of old ID → new ID\n const idMap = new Map<string, string>();\n\n // Attributes that contain hash references (#id)\n const hashRefAttrs = new Set(['href', 'xlink:href']);\n\n // Attributes that contain url(#id) references\n const urlRefAttrs = new Set([\n 'fill', 'stroke', 'clip-path', 'clipPath', 'mask',\n 'marker', 'marker-start', 'marker-mid', 'marker-end',\n 'filter', 'flood-color', 'lighting-color'\n ]);\n\n // Attributes that contain direct ID references (no # or url())\n const directIdRefAttrs = new Set(['baseId', 'targetId', 'boundElementId']);\n\n // Phase 1: Collect all IDs and generate new ones\n function collectIds(node: any): void {\n if (!node || typeof node !== 'object') return;\n\n if (node.id && typeof node.id === 'string') {\n const oldId = node.id;\n const newId = generateUniqueId();\n idMap.set(oldId, newId);\n node.id = newId;\n } else if (node.animate) {\n // An animated node needs an id so the animation can bind to its rendered element.\n node.id = generateUniqueId();\n }\n\n // Process children\n if (Array.isArray(node.children)) {\n for (const child of node.children) {\n collectIds(child);\n }\n }\n }\n\n // Phase 2: Update all references to old IDs\n function updateRefs(node: any): void {\n if (!node || typeof node !== 'object') return;\n\n for (const [key, value] of Object.entries(node)) {\n if (key === 'children') {\n if (Array.isArray(value)) {\n for (const child of value) {\n updateRefs(child);\n }\n }\n continue;\n }\n\n if (typeof value === 'string') {\n // Check for hash references: href=\"#old-id\"\n if (hashRefAttrs.has(key) && value.startsWith('#')) {\n const oldId = value.slice(1);\n const newId = idMap.get(oldId);\n if (newId) {\n node[key] = '#' + newId;\n }\n }\n // Check for url() references: fill=\"url(#old-id)\"\n else if (urlRefAttrs.has(key)) {\n node[key] = replaceUrlRefs(value, idMap);\n }\n // Check for direct ID references: baseId=\"_px_xxx\"\n else if (directIdRefAttrs.has(key)) {\n const newId = idMap.get(value);\n if (newId) {\n node[key] = newId;\n }\n }\n // Check for url() in any string value (e.g., in style strings)\n else if (value.includes('url(#')) {\n node[key] = replaceUrlRefs(value, idMap);\n }\n }\n // Check style object for url() references\n else if (key === 'style' && typeof value === 'object' && value !== null) {\n for (const [styleProp, styleValue] of Object.entries(value)) {\n if (typeof styleValue === 'string') {\n (value as any)[styleProp] = replaceUrlRefs(styleValue, idMap);\n }\n }\n }\n // Recursively process nested objects (meta contains baseId/targetId refs;\n // in-place animated values like { keyframes: [{ value: \"url(#grad)\" }] }\n // also need ref rewriting on string values they contain).\n else if (typeof value === 'object' && value !== null) {\n updateRefs(value);\n }\n }\n }\n\n collectIds(cloned);\n updateRefs(cloned);\n\n // Update IDs in animator.animate map\n const docAnimate = cloned.animator?.animate;\n if (docAnimate && typeof docAnimate === 'object') {\n const updatedAnimate: Record<string, any> = {};\n for (const [id, anim] of Object.entries(docAnimate)) {\n const newId = idMap.get(id) ?? id;\n updatedAnimate[newId] = anim;\n }\n cloned.animator = { ...cloned.animator, animate: updatedAnimate };\n }\n\n return cloned;\n}\n\n/**\n * Replaces url(#old-id) references in a string with new IDs from the map.\n */\nfunction replaceUrlRefs(value: string, idMap: Map<string, string>): string {\n return value.replace(/url\\(#([^)]+)\\)/g, (match, oldId) => {\n const newId = idMap.get(oldId);\n return newId ? 'url(#' + newId + ')' : match;\n });\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { INTERNAL_ATTRS, type PxDefs } from './PxAnimatorTypes';\nimport { COLOUR_ATTR_NAMES, composeTransformParts, kebabToCamelCaseWord, toRGBA, TRANSFORM_FN_NAMES } from './PxAnimatorUtil';\n\n\n/**\n * Tags that MUST never be created — the only real XSS surfaces in SVG:\n * - `<script>` — direct JS execution.\n * - `<foreignObject>` — embeds arbitrary HTML (incl. `<script>`, `<iframe>`).\n *\n * Everything else (shape elements, gradients, patterns, markers, filters\n * including `feComponentTransfer` / `feFuncA` / `feFlood` / `feComposite` /\n * `feImage`, SMIL `<animate>` family, `<a>` hyperlinks, …) is allowed. URL\n * sanitisation in `sanitiseAttributeValue` blocks `javascript:` / external\n * refs on `href` / `src` / `mask` / `marker*`.\n */\nexport const DISALLOWED_SVG_TAGS_LOWER = new Set([\n 'script',\n 'foreignobject',\n]);\n\n\n/**\n * URL-valued attributes that must reference an internal `#id` / `url(#id)`\n * only — never an external URL, `javascript:`, etc. Values for these names\n * are sanitised in `sanitiseAttributeValue`; non-internal refs are dropped.\n *\n * Exception: image-ref attributes (`href` / `xlink:href` / `src`) ALSO\n * accept `data:image/…` URIs — base64 raster (`image/png`, `image/jpeg`,\n * `image/gif`, `image/webp`, `image/bmp`) and `image/svg+xml` (base64 or\n * URL-encoded). Browsers render any image referenced from `<image>` in\n * SVG \"secure static mode\": scripts inside the referenced SVG do NOT\n * execute, external resources don't load, and interaction is disabled —\n * the same sandbox `<img src=…svg>` uses. The `image/svg+xml` form is\n * therefore safe as an image source even though a top-level SVG document\n * with the same bytes could embed scripts.\n *\n * Stored lowercased so `sanitiseAttributeValue`'s `name.toLowerCase()`\n * lookup matches regardless of input casing (`href` / `xlink:href` /\n * `clipPath` / `clip-path` all hit the same entry).\n */\nconst URL_VALUE_ATTRS_LOWER = new Set([\n 'href', // <use>, <image>\n 'xlink:href', // legacy <use>\n 'src', // <image>\n 'filter', // url(#filterId)\n 'clippath', // clip-path=\"url(#…)\"\n 'mask', // url(#maskId)\n 'markerstart', // marker-start=\"url(#…)\"\n 'markermid', // marker-mid=\"url(#…)\"\n 'markerend', // marker-end=\"url(#…)\"\n]);\n\n/** Attrs where a `data:image/…` URI is a legitimate value (i.e. the SVG\n * element actually renders the bytes — `<image>`). Other URL-valued\n * attrs ignore data URIs at the browser layer, so widening the allow-\n * list there would be cargo-culted and noisy. */\nconst IMAGE_REF_ATTRS_LOWER = new Set(['href', 'xlink:href', 'src']);\n\n/** CSS-only properties that are NOT SVG presentation attributes — the browser\n * ignores them via `setAttribute`, so they must be applied through `element.style`.\n * Keyed camelCase to match the normalised prop names (`element.style.mixBlendMode`). */\nexport const CSS_ONLY_STYLE_PROPS = new Set<string>(['mixBlendMode', 'isolation']);\n\n/** Matches `data:image/{png|jpeg|jpg|gif|webp|bmp};base64,<payload>`.\n * Rejects any non-base64-encoded raster form. */\nconst DATA_RASTER_IMAGE_RE = /^data:image\\/(?:png|jpe?g|gif|webp|bmp);base64,/i;\n\n/** Matches `data:image/svg+xml[;params],<payload>` — base64\n * (`;base64,`), `;utf8,` / `;charset=UTF-8,`, and bare `,` (URL-encoded)\n * forms. Safe because the browser sandboxes any SVG referenced from an\n * image source (no scripts, no external loads, no interaction). */\nconst DATA_SVG_IMAGE_RE = /^data:image\\/svg\\+xml(?:;[^,]*)?,/i;\n\n/** Content-sniff fallback for `data:image/*;base64,…` URIs whose declared\n * subtype isn't a known raster type — e.g. `data:image/undefined;base64,<png>`,\n * which some Lottie exporters emit. The browser (and lottie-web) render these by\n * sniffing the leading bytes; we mirror that by matching the base64 payload\n * against common raster magic numbers (PNG `\\x89PNG`, JPEG `\\xFF\\xD8\\xFF`, GIF\n * `GIF8`, WebP/RIFF, BMP `BM`). Accepting on real image bytes keeps the\n * sanitiser's safety guarantee — raster bytes are inert — without trusting the\n * (here bogus) subtype, so the image renders instead of being dropped. */\nconst DATA_IMAGE_BASE64_PAYLOAD_RE = /^data:image\\/[^;,]*;base64,([A-Za-z0-9+/]{8})/i;\nconst BASE64_RASTER_MAGICS = ['iVBORw0K', '/9j/', 'R0lGOD', 'UklGR', 'Qk'];\nfunction isContentSniffedRasterImage(str: string): boolean {\n const m = DATA_IMAGE_BASE64_PAYLOAD_RE.exec(str);\n return !!m && BASE64_RASTER_MAGICS.some(magic => m[1].startsWith(magic));\n}\n\n\n/**\n * Attribute-name predicate: anything `name` matching this is dropped at\n * `setAttribute` time. The list is intentionally small — SVG's real\n * security surface is event handlers; every other concerning attribute\n * (URL refs, fill/stroke `url(…)`) is value-sanitised below, not name-\n * blocked. Adding entries here is a structural decision, not whack-a-mole.\n */\nfunction isDangerousAttrName(nameLower: string): boolean {\n // Event handlers — `onclick`, `onload`, `onerror`, `onmouseover`,\n // `onfocus`, `onfocusin`, SMIL `onbegin`/`onend`/`onrepeat`, … and any\n // future one. No legitimate SVG attribute starts with `on`, so this\n // prefix is a safe blanket block.\n if (nameLower.startsWith('on')) return true;\n return false;\n}\n\n\n/**\n * Returns the value to pass to `setAttribute`, or `undefined` to drop the\n * attribute entirely. Dropping leaves the DOM clean — the caller skips\n * `setAttribute` when this returns `undefined`.\n *\n * Three layers:\n * 1. Drop dangerous names (`on*` event handlers).\n * 2. Restrict `url(…)` in `fill` / `stroke` / `stop-color` to\n * internal `url(#id)` references.\n * 3. Restrict URL-valued attrs (`href`, `src`, `filter`, `clip-path`,\n * `mask`, `marker*`) to internal `#id` / `url(#id)`. Image-ref\n * attrs (`href` / `xlink:href` / `src`) additionally accept\n * `data:image/…` URIs — base64 raster (png/jpeg/gif/webp/bmp) and\n * `image/svg+xml` (sandboxed by the browser when used as an image\n * source). Blocks `javascript:` and external URLs.\n * Everything else passes through.\n */\nexport function sanitiseAttributeValue(name: string, value: any): any | undefined {\n const nameLower = name.toLowerCase();\n\n if (isDangerousAttrName(nameLower)) {\n console.warn('Attribute blocked (event handler / dangerous): ', nameLower);\n return undefined;\n }\n\n if (nameLower === 'fill' || nameLower === 'stroke' || nameLower === 'stopcolor') {\n const str = String(value);\n if (str.includes('url(') && !/^url\\(#[^)]+\\)$/.test(str)) {\n console.warn('Attribute \"' + nameLower + '\" blocked: url() must be internal url(#id), got:', value);\n return undefined;\n }\n return value;\n }\n\n if (URL_VALUE_ATTRS_LOWER.has(nameLower)) {\n const str = String(value);\n if (str.startsWith('#')) return value; // internal fragment ref\n if (/^url\\(#[^)]+\\)$/.test(str)) return value; // internal `url(#id)`\n // Image-ref attrs accept `data:image/…` URIs — raster bytes are\n // inert, and SVG referenced via an image source is sandboxed by\n // the browser (no script execution).\n if (IMAGE_REF_ATTRS_LOWER.has(nameLower) && (DATA_RASTER_IMAGE_RE.test(str) || DATA_SVG_IMAGE_RE.test(str) || isContentSniffedRasterImage(str))) return value;\n console.warn('Attribute \"' + nameLower + '\" blocked: must be #id, url(#id), or data:image/… URI, got:', value);\n return undefined;\n }\n\n return value;\n}\n\n/** FIXME - do we need this?\n * Resolves a style reference to an actual style object.\n */\nexport function resolveStyle(\n style: string | Record<string, string | number> | undefined,\n defs?: PxDefs\n): Record<string, string | number> | undefined {\n if (!style) return undefined;\n\n if (typeof style === 'string') {\n // Look up named style in defs\n return defs?.styles?.[style];\n }\n\n return style;\n}\n\n\nexport function getNormalizedProps(props: Record<string, any>) {\n const propsCopy: Record<string, any> = {};\n\n // Process regular attributes\n for (const rawKey of Object.keys(props)) {\n // Wire-format inputs may use kebab-case SVG attribute names (e.g.\n // `stroke-width`); normalise to camelCase up-front so the whitelist\n // (camelCase) and the `camelCaseToKebabWordIfNeeded` re-conversion\n // at write time both work. `kebabToCamelCaseWord` is a no-op for\n // keys with no `-`, leaving camelCase inputs untouched.\n const key = kebabToCamelCaseWord(rawKey);\n if (INTERNAL_ATTRS.has(key)) continue;\n if (key === 'style') continue;\n\n let value = props[rawKey];\n\n if (COLOUR_ATTR_NAMES.has(key) && Array.isArray(value)) {\n propsCopy[key] = toRGBA(value);\n } else if (\n key === 'transform' && value !== null && typeof value === 'object' &&\n !Array.isArray(value) && value.value && typeof value.value === 'object'\n ) {\n // Unified transform structured-static form: { value: PxTransformParts }.\n // Compose into an SVG transform string (no units — SVG transform attribute).\n propsCopy['transform'] = composeTransformParts(value.value, { withUnits: false });\n } else if (TRANSFORM_FN_NAMES.has(key)) {\n if (Array.isArray(value)) {\n if (key === 'translate') value = value.map((v: number) => v + 'px');\n value = value.join(',');\n }\n if (key === 'rotate') value = value + 'deg';\n propsCopy['transform'] = key + '(' + value + ')';\n } else if (value !== undefined && value !== null) {\n propsCopy[key] = String(value);\n }\n }\n\n return propsCopy;\n}\n\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n/**\n * Motion-along-path → plain transform keyframes.\n *\n * Editor wire format for a curved-translation (and/or `autoOrient`) animation\n * carries per-kf `tangentIn` / `tangentOut` plus an animation-level `autoOrient`\n * flag — a parametric representation that any consumer must evaluate per frame.\n *\n * This module DESUGARS that shape into a regular unified-transform animation:\n * extra `{ translate, rotate? }` keyframes are inserted at curve extrema and\n * adaptive bisection points so the linear chord between adjacent samples stays\n * within `flatnessTolerance` of the true Bezier, and the original easing is\n * SPLIT (via De Casteljau, `splitEasing` in `PxAnimatorUtil`) across the\n * sub-segments so the combined timing reproduces the input easing exactly.\n *\n * Output kfs have no tangents and no `autoOrient` — both engines (`frames` and\n * `webapi`) and any future renderer (e.g. react-native-svg) consume them via\n * their normal unified-transform code path.\n *\n * The plan + rationale (extremes-aware sampling, easing-split, full pipeline\n * order) is in `motion-along-path-waapi-rework.md`.\n */\n\n\nimport { bezier2D_arcAtT, bezier2D_arcLengthLUT, bezier2D_derivativeAt, bezier2D_pointAt, clamp, invertEasing, splitEasing } from './PxAnimatorUtil';\nimport type { ArcLengthLUT } from './PxAnimatorUtil';\nimport type { PxKeyframe, PxNode, PxPropertyAnimation, PxTransformParts } from './PxAnimatorTypes';\n\n\ntype Point2 = [number, number];\ntype Easing = [number, number, number, number];\n\n\nfunction getKfTranslate(kf: PxKeyframe): Point2 | undefined {\n const v = kf.value ?? kf.v;\n if (!v) return undefined;\n if (Array.isArray(v) && v.length >= 2 && typeof v[0] === 'number' && typeof v[1] === 'number') {\n // Composite per-part shape: `value: [x, y]` directly.\n return [v[0], v[1]];\n }\n const tr = (v as PxTransformParts).translate;\n if (Array.isArray(tr) && tr.length >= 2) return [tr[0], tr[1]];\n return undefined;\n}\n\nfunction getKfTime(kf: PxKeyframe): number {\n return (kf.time ?? kf.t ?? 0) as number;\n}\n\nfunction getKfEasing(kf: PxKeyframe): Easing | undefined {\n return (kf.easing ?? kf.e) as Easing | undefined;\n}\n\n\n/**\n * True when `anim` is a motion-along-path animation — at least one keyframe\n * carries spatial tangents (`tangentIn` / `tangentOut`) and/or the animation\n * has `autoOrient` set. Animation-level helper; works for either the body\n * `transform` slot or a composite per-part `translate` slot.\n */\nexport function propAnimIsMotionPath(anim: PxPropertyAnimation): boolean {\n const kfs: Array<PxKeyframe> | undefined = anim.keyframes ?? anim.kfs;\n if (!Array.isArray(kfs)) return false;\n if (anim.autoOrient) return true;\n for (const kf of kfs) {\n if ((kf.tangentIn ?? kf.ti) || (kf.tangentOut ?? kf.to)) return true;\n }\n return false;\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Segment cache — shared by `evaluateMotionPathSegment` (frames-mode kernel)\n// and the materialiser. Keyed by FROM-keyframe identity (WeakMap), so cache\n// entries vanish automatically when keyframes are replaced.\n// ─────────────────────────────────────────────────────────────────────────────\n\n\ninterface MotionPathSegmentCache {\n readonly P0: Point2;\n readonly P1: Point2;\n readonly P2: Point2;\n readonly P3: Point2;\n readonly lut: ArcLengthLUT;\n readonly totalArc: number;\n}\n\n// Keyed on the PAIR, not on `prevKf` alone: one keyframe can start different segments\n// across evaluations (a lookup that falls outside the keyframe range answers with a\n// first→last pair), and a `prevKf`-only key let that bogus segment's Bezier be served\n// for every later evaluation of the real `prevKf`→next segment.\nconst _segmentCache = new WeakMap<PxKeyframe, WeakMap<PxKeyframe, MotionPathSegmentCache>>();\n\nfunction getSegmentCache(\n prevKf: PxKeyframe,\n nextKf: PxKeyframe,\n prevPos: Point2,\n nextPos: Point2,\n): MotionPathSegmentCache {\n let byNext = _segmentCache.get(prevKf);\n const existing = byNext?.get(nextKf);\n if (existing) return existing;\n const to = prevKf.tangentOut ?? prevKf.to;\n const ti = nextKf.tangentIn ?? nextKf.ti;\n const P1: Point2 = [prevPos[0] + (to ? to[0] : 0), prevPos[1] + (to ? to[1] : 0)];\n const P2: Point2 = [nextPos[0] + (ti ? ti[0] : 0), nextPos[1] + (ti ? ti[1] : 0)];\n const lut = bezier2D_arcLengthLUT(prevPos, P1, P2, nextPos);\n const entry: MotionPathSegmentCache = {\n P0: prevPos, P1, P2, P3: nextPos,\n lut,\n totalArc: lut.ds[lut.ds.length - 1],\n };\n if (!byNext) { byNext = new WeakMap<PxKeyframe, MotionPathSegmentCache>(); _segmentCache.set(prevKf, byNext); }\n byNext.set(nextKf, entry);\n return entry;\n}\n\n/** Test helper. No-op in production (WeakMap; entries self-evict). Tests\n * should use fresh keyframe objects to force cache misses. */\nexport function _resetMotionPathSegmentCache(): void {\n // Intentionally empty — kept for backwards-compat with any callers.\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Frames-mode kernel — preserved for any caller that still wants parametric\n// evaluation. The binding pipeline no longer needs it (motion-path is\n// materialised at `getNormalisedBindings` time), but it's a useful primitive\n// on its own.\n// ─────────────────────────────────────────────────────────────────────────────\n\n\nexport interface MotionPathSample {\n /** Translate at the current time (motion-path arc-length-parametrised). */\n readonly translate: Point2;\n /** Auto-orient rotation in degrees (only when `autoOrient` is set). */\n readonly rotateDeg?: number;\n}\n\n/**\n * Evaluates the motion-path position (and optional auto-orient rotation) for a\n * single segment kf[i] → kf[i+1], given local progress already remapped to\n * `[0, 1]` and eased. Builds (or reuses cached) Bezier control points\n * `P1 = P0 + tangentOut`, `P2 = P3 + tangentIn`, maps `localProgress` to arc\n * length, then to curve parameter `t` via the arc-length LUT.\n */\nexport function evaluateMotionPathSegment(\n prevKf: PxKeyframe,\n nextKf: PxKeyframe,\n prevPos: Point2,\n nextPos: Point2,\n localProgress: number,\n autoOrient: boolean,\n): MotionPathSample {\n const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);\n const t = seg.totalArc === 0\n ? localProgress\n : tFromArcFraction(seg.lut, localProgress);\n const point = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);\n if (!autoOrient) return { translate: point };\n const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);\n const rotateDeg = Math.atan2(tan[1], tan[0]) * 180 / Math.PI;\n return { translate: point, rotateDeg };\n}\n\nfunction tFromArcFraction(lut: ArcLengthLUT, arcFrac: number): number {\n const total = lut.ds[lut.ds.length - 1];\n // Binary search on `ds` for `arcFrac * total` (mirrors bezier2D_tForDistance).\n const target = arcFrac * total;\n const { ts, ds } = lut;\n const last = ds.length - 1;\n if (target <= 0) return ts[0];\n if (target >= ds[last]) return ts[last];\n let lo = 1, hi = last;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n if (ds[mid] < target) lo = mid + 1;\n else hi = mid;\n }\n const dPrev = ds[hi - 1];\n const span = ds[hi] - dPrev;\n const frac = span > 0 ? (target - dPrev) / span : 0;\n return ts[hi - 1] + frac * (ts[hi] - ts[hi - 1]);\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Public API — materialise parametric motion-path into plain transform kfs\n// ─────────────────────────────────────────────────────────────────────────────\n\n\n/** Sampling configuration shared by `materialiseMotionPathInPropAnim` + `materialiseMotionPathsInTree`. */\nexport interface MotionPathMaterialisationOptions {\n /** Max chord-to-curve deviation per sub-interval, in user units (default 0.5). */\n flatnessTolerance?: number;\n /** Max rotation delta (in degrees) between adjacent samples when `autoOrient`\n * is set (default 5). */\n rotationTolerance?: number;\n /** Hard cap on samples per original segment; prevents runaway recursion on\n * pathological inputs (default 32). */\n maxSamplesPerSegment?: number;\n}\n\nconst DEFAULT_FLATNESS_TOL = 0.5;\nconst DEFAULT_ROTATION_TOL = 5;\nconst DEFAULT_MAX_SAMPLES = 32;\n\n\n/**\n * Converts ONE animated property to sampled transform kfs.\n *\n * Returns a NEW `PxPropertyAnimation` whose `kfs` are flat\n * `{ translate, rotate? }` records placed at curve extrema and adaptive\n * bisection points. Positions are arc-length-parametrised; easing is split via\n * De Casteljau so per-sub-segment easings reproduce the input easing exactly.\n * Original `loop` is carried across; `autoOrient` and per-kf `tangentIn` /\n * `tangentOut` are consumed.\n *\n * Returns the input unchanged (by reference) when it's not a motion-path\n * animation — callers can blindly run it through every propAnim.\n */\nexport function materialiseMotionPathInPropAnim(\n anim: PxPropertyAnimation,\n opts?: MotionPathMaterialisationOptions,\n): PxPropertyAnimation {\n if (!propAnimIsMotionPath(anim)) return anim;\n const kfs = (anim.keyframes ?? anim.kfs) as Array<PxKeyframe> | undefined;\n if (!Array.isArray(kfs) || kfs.length < 2) return anim;\n\n const autoOrient = !!anim.autoOrient;\n const flatnessTol = opts?.flatnessTolerance ?? DEFAULT_FLATNESS_TOL;\n const rotationTol = opts?.rotationTolerance ?? DEFAULT_ROTATION_TOL;\n const maxSamples = opts?.maxSamplesPerSegment ?? DEFAULT_MAX_SAMPLES;\n\n const out: Array<PxKeyframe> = [];\n\n // First output kf — translate from input; rotate from segment-0 derivative\n // at t=0 if autoOrient. All other transform parts (`origin`, `scale`, an\n // explicit `rotate` when `autoOrient` is false, …) come from kfs[0].value.\n const firstPos = getKfTranslate(kfs[0]);\n if (!firstPos) return anim;\n const firstRotate = autoOrient ? derivAngleForFirstKf(kfs[0], kfs[1]) : undefined;\n out.push(makeOutKf(\n getKfTime(kfs[0]),\n buildOutKfValue(getKfValueParts(kfs[0]), getKfValueParts(kfs[0]), 0, firstPos, firstRotate, autoOrient),\n ));\n\n for (let i = 0; i < kfs.length - 1; i++) {\n const prevKf = kfs[i];\n const nextKf = kfs[i + 1];\n const prevPos = getKfTranslate(prevKf);\n const nextPos = getKfTranslate(nextKf);\n if (!prevPos || !nextPos) {\n // Skip undefined translate kfs — just push next as-is.\n out.push(makeOutKf(\n getKfTime(nextKf),\n buildOutKfValue(getKfValueParts(nextKf), getKfValueParts(nextKf), 1, nextPos ?? [0, 0], undefined, autoOrient),\n ));\n continue;\n }\n\n // Sharp-corner step: between adjacent segments, the prev-segment's\n // exit tangent angle (already on out[last]) can differ from this\n // segment's entry tangent angle (deriv at t=0 of the segment about to\n // start) by a lot — e.g. a rectangular path has 90° steps at each\n // corner. Linear interp from prev-exit to the FAR-END kf of this\n // segment would slide rotation through the whole segment instead of\n // stepping at the boundary. Fix: insert a duplicate kf at the\n // boundary time carrying this segment's entry angle. With `e=undef`\n // on the prior kf, the engines render an instant step boundary then\n // constant rotation through the segment.\n if (autoOrient && i > 0) {\n insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos, rotationTol);\n }\n\n materialiseSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples);\n }\n\n // The very last out-kf inherits the original last kf's `easing` (which\n // applies to the NEXT segment after this animation, or nothing — but the\n // wire format preserves it regardless).\n const lastInE = getKfEasing(kfs[kfs.length - 1]);\n if (lastInE) out[out.length - 1].e = lastInE;\n\n // Unwrap autoOrient rotations so linear interp between samples doesn't\n // take the long way around the circle. atan2 returns in (-180°, 180°];\n // a tangent rotating slowly across the +X axis (e.g. -179° → +179°)\n // would otherwise be lerp'd as a ~358° spin instead of a ~2° step.\n if (autoOrient) unwrapAutoOrientRotations(out);\n\n const result: PxPropertyAnimation = { kfs: out } as PxPropertyAnimation;\n if (anim.loop !== undefined) (result as { loop?: unknown }).loop = anim.loop;\n return result;\n}\n\n\n/** Walks `kfs` in order; for each kf with a `rotate` value, shifts it by ±360°\n * multiples so the delta from the previous kf's rotate stays within ±180°.\n * Linear interpolation between consecutive samples then always takes the\n * shorter arc. The accumulated shift means a continuously-rotating element\n * may end up with rotate values well outside [-180°, 180°], which is fine —\n * CSS / SVG rotation accepts any range. Exported — the glyph along-path baker\n * (`buildAnimatedAlongPath`) needs the identical seam fix for its sampled\n * per-glyph tangent rotations. */\nexport function unwrapAutoOrientRotations(kfs: Array<PxKeyframe>): void {\n let prev: number | undefined;\n for (const kf of kfs) {\n const v = (kf.v ?? kf.value) as { rotate?: number } | undefined;\n if (!v || typeof v.rotate !== 'number') continue;\n if (prev === undefined) { prev = v.rotate; continue; }\n let r = v.rotate;\n while (r - prev > 180) r -= 360;\n while (r - prev < -180) r += 360;\n v.rotate = r;\n prev = r;\n }\n}\n\n\nfunction makeOutKf(time: number, value: PxTransformParts): PxKeyframe {\n return { t: time, v: value } as PxKeyframe;\n}\n\n/** Reads the kf's value-as-parts (object form). Returns `undefined` if the kf\n * has no value or it's an array form (single-part composite). */\nfunction getKfValueParts(kf: PxKeyframe): PxTransformParts | undefined {\n const v = kf.value ?? kf.v;\n if (!v || typeof v !== 'object' || Array.isArray(v)) return undefined;\n return v as PxTransformParts;\n}\n\n/** Linearly interpolates one transform-part value (number / Vec2). Returns the\n * non-undefined input when only one side is present, falls back to `prev`\n * for unsupported types. */\nfunction interpolatePart(prev: unknown, next: unknown, p: number): unknown {\n if (prev === undefined) return next;\n if (next === undefined) return prev;\n if (typeof prev === 'number' && typeof next === 'number') {\n return prev + (next - prev) * p;\n }\n if (Array.isArray(prev) && Array.isArray(next) && prev.length === next.length) {\n const out: Array<number> = new Array(prev.length);\n for (let i = 0; i < prev.length; i++) {\n const a = typeof prev[i] === 'number' ? prev[i] : 0;\n const b = typeof next[i] === 'number' ? next[i] : 0;\n out[i] = a + (b - a) * p;\n }\n return out;\n }\n return p < 0.5 ? prev : next;\n}\n\n/** Builds the value-record for one sampled output kf. `translate` overrides\n * whatever the per-part interpolation would have produced (motion path is the\n * source of truth for position); `rotateDegFromAutoOrient`, when defined, is\n * ADDED on top of the (interpolated) explicit animated `rotate` — auto-orient\n * and a user-set rotation compose, matching After Effects / Lottie semantics.\n * All OTHER parts present on `prevV` / `nextV` (origin, scale, etc.) are\n * interpolated at the eased arc-progress `p` — mirroring the frames-mode\n * `calcPropertyValue` loop. */\nfunction buildOutKfValue(\n prevV: PxTransformParts | undefined,\n nextV: PxTransformParts | undefined,\n p: number,\n translate: Point2,\n rotateDegFromAutoOrient: number | undefined,\n autoOrient: boolean,\n): PxTransformParts {\n const value: { [k: string]: unknown } = { translate };\n const keys = new Set<string>();\n if (prevV) for (const k of Object.keys(prevV)) keys.add(k);\n if (nextV) for (const k of Object.keys(nextV)) keys.add(k);\n for (const k of keys) {\n if (k === 'translate') continue; // overridden by motion path\n if (k === 'rotate' && autoOrient) continue; // composed below with autoOrient\n const pv = (prevV as Record<string, unknown> | undefined)?.[k];\n const nv = (nextV as Record<string, unknown> | undefined)?.[k];\n if (pv === undefined && nv === undefined) continue;\n value[k] = interpolatePart(pv, nv, p);\n }\n if (rotateDegFromAutoOrient !== undefined) {\n // Sum the auto-orient tangent angle with the element's own animated\n // rotation (interpolated at `p`, 0 when absent) rather than discarding it.\n value.rotate = rotateDegFromAutoOrient + explicitRotateAt(prevV, nextV, p);\n }\n return value as PxTransformParts;\n}\n\n/** Interpolated explicit `rotate` from a transform-parts pair at arc-progress\n * `p`; 0 when neither side carries a numeric rotate. */\nfunction explicitRotateAt(\n prevV: PxTransformParts | undefined,\n nextV: PxTransformParts | undefined,\n p: number,\n): number {\n const pv = typeof prevV?.rotate === 'number' ? prevV.rotate : undefined;\n const nv = typeof nextV?.rotate === 'number' ? nextV.rotate : undefined;\n if (pv === undefined && nv === undefined) return 0;\n const r = interpolatePart(pv, nv, p);\n return typeof r === 'number' ? r : 0;\n}\n\n\n/** Derivative angle at t=0 of segment kf[0] → kf[1]. Used to seed the first\n * output kf's rotation; without this the very first frame would render with\n * no rotation while every subsequent sample has one. */\nfunction derivAngleForFirstKf(kf0: PxKeyframe, kf1: PxKeyframe): number {\n const p0 = getKfTranslate(kf0);\n const p1 = getKfTranslate(kf1);\n if (!p0 || !p1) return 0;\n const seg = getSegmentCache(kf0, kf1, p0, p1);\n const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, 0);\n return Math.atan2(tan[1], tan[0]) * 180 / Math.PI;\n}\n\n\n/** Shortest signed difference of `a − b` wrapped into (-180°, 180°]. */\nfunction wrappedAngleDelta(a: number, b: number): number {\n let d = a - b;\n while (d > 180) d -= 360;\n while (d < -180) d += 360;\n return d;\n}\n\n\n/**\n * Appends a \"step\" kf to `out` at the boundary time iff the next segment's\n * entry tangent direction differs from the last emitted kf's rotation by more\n * than `rotationTol`. The new kf carries the SAME translate / origin / scale\n * as the boundary kf already in `out` (continuous in space), but a different\n * `rotate` — making engines render an instant rotation snap at the boundary\n * rather than linearly sliding rotation across the whole next segment.\n *\n * Called between `materialiseSegment` calls. The boundary kf already in `out`\n * keeps its outgoing easing as undefined (no easing between the two duplicates\n * — the step is instant); the next `materialiseSegment` will then attach its\n * sequential-split easing to the newly-inserted duplicate, so the per-sample\n * easing on segment `i+1` works exactly as before.\n */\nfunction insertSharpCornerStepKfIfNeeded(\n out: Array<PxKeyframe>,\n prevKf: PxKeyframe, nextKf: PxKeyframe,\n prevPos: Point2, nextPos: Point2,\n rotationTol: number,\n): void {\n const lastKf = out[out.length - 1];\n const lastV = (lastKf.v ?? lastKf.value) as { rotate?: number } | undefined;\n const prevExit = lastV?.rotate;\n if (typeof prevExit !== 'number') return;\n\n // `prevExit` is the SUMMED rotation (tangent + explicit). Compare pure\n // tangent-to-tangent by subtracting the boundary kf's explicit rotate,\n // which is shared by both adjoining segments at this shared keyframe.\n const boundaryV = getKfValueParts(prevKf);\n const prevExitTangent = prevExit - explicitRotateAt(boundaryV, boundaryV, 0);\n\n const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);\n const tanAtStart = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, 0);\n const nextEntry = Math.atan2(tanAtStart[1], tanAtStart[0]) * 180 / Math.PI;\n const delta = wrappedAngleDelta(nextEntry, prevExitTangent);\n if (Math.abs(delta) <= rotationTol) return; // continuous within tolerance\n\n // Step kf carrying the new entry angle, a hair AFTER the boundary — the boundary\n // time itself must render the PREVIOUS segment's exit pose. A duplicate at the exact\n // boundary time made CSS/WAAPI resolve the LATER keyframe there, so scrubbing to\n // exactly the corner showed the next segment's angle while the editor (and the\n // parametric frames engine, whose segment lookup treats a boundary as the END of the\n // segment before it) showed the previous one. The offset is far below a frame, so\n // playback still reads as an instant step at the corner.\n const prevTime = getKfTime(prevKf);\n const stepTime = Math.min(prevTime + CORNER_STEP_AFTER_BOUNDARY_MS, (prevTime + getKfTime(nextKf)) / 2);\n const dupValue = buildOutKfValue(\n getKfValueParts(prevKf), getKfValueParts(prevKf), 0,\n prevPos, nextEntry, true,\n );\n out.push(makeOutKf(stepTime, dupValue));\n}\n\n/** How far past a sharp corner the entry-angle step kf sits (ms). Small enough to be\n * invisible in playback (a frame is ~16 ms) — and strictly under the 0.1 ms step-width\n * budget the corner-step CSS spec asserts — while still a distinct WAAPI offset. */\nconst CORNER_STEP_AFTER_BOUNDARY_MS = 0.05;\n\n\n/** Materialises a single segment into `out`. Appends one kf per sample (interior\n * critical/adaptive points + the next-kf endpoint), with positions, optional\n * rotations, and split easings. */\nfunction materialiseSegment(\n out: Array<PxKeyframe>,\n prevKf: PxKeyframe, nextKf: PxKeyframe,\n prevPos: Point2, nextPos: Point2,\n autoOrient: boolean,\n flatnessTol: number, rotationTol: number, maxSamples: number,\n): void {\n const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);\n const prevTime = getKfTime(prevKf);\n const nextTime = getKfTime(nextKf);\n const prevEasing = getKfEasing(prevKf);\n const invertFn = invertEasing(prevEasing);\n const prevV = getKfValueParts(prevKf);\n const nextV = getKfValueParts(nextKf);\n\n // 1. Critical t-values: axis extrema + endpoints.\n const interiorTs = computeSampleTs(seg, autoOrient, flatnessTol, rotationTol, maxSamples);\n // `interiorTs` is the list of t in (0, 1] in ascending order, ending with t=1.\n\n // 2. For each sample t, compute position, rotation, the eased arc-fraction\n // `p` (= the value frames-mode would use for non-translate part interp),\n // and the linear-time fraction `u` (via invertEasing of `p`).\n interface Sample { u: number; p: number; pos: Point2; rotateDeg?: number; }\n const samples: Array<Sample> = [];\n for (const t of interiorTs) {\n const arc = bezier2D_arcAtT(seg.lut, t);\n const p = clamp(seg.totalArc > 0 ? arc / seg.totalArc : t, 0, 1);\n const u = clamp(invertFn(p), 0, 1);\n const pos = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);\n const sample: Sample = { u, p, pos };\n if (autoOrient) {\n const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);\n sample.rotateDeg = Math.atan2(tan[1], tan[0]) * 180 / Math.PI;\n }\n samples.push(sample);\n }\n\n // 3. Sequential easing split. The easing for sub-segment k (out[L+k-1] → out[L+k])\n // is the `left` half of splitting the still-unconsumed easing at\n // `(u_k - u_{k-1}) / (1 - u_{k-1})`.\n let remaining = prevEasing;\n let prevU = 0;\n const startIdx = out.length - 1; // out[startIdx] is the prev kf — it owns the FIRST sub-easing.\n for (let i = 0; i < samples.length; i++) {\n const s = samples[i];\n const xFrac = prevU < 1 ? clamp((s.u - prevU) / (1 - prevU), 0, 1) : 1;\n const { left, right } = splitEasing(remaining, xFrac);\n\n // Assign `left` as the outgoing easing of the kf at the end of `out`\n // (which is the kf that PRECEDES this sub-kf — the prev kf for i=0,\n // or the previously-emitted sub-kf for i>0).\n const ownerIdx = i === 0 ? startIdx : out.length - 1;\n if (left) out[ownerIdx].e = left;\n else delete out[ownerIdx].e;\n\n const tGlobal = prevTime + s.u * (nextTime - prevTime);\n const value = buildOutKfValue(prevV, nextV, s.p, s.pos, s.rotateDeg, autoOrient);\n out.push(makeOutKf(tGlobal, value));\n\n remaining = right;\n prevU = s.u;\n }\n}\n\n\n/** Returns t-values in (0, 1], sorted ascending, ending with t=1. The list\n * always includes the input segment's axis extrema interior to (0, 1), plus\n * adaptive bisection samples wherever the chord deviates from the curve by\n * more than `flatnessTol` (or the rotation delta exceeds `rotationTol` for\n * autoOrient). Capped at `maxSamples`. */\nfunction computeSampleTs(\n seg: MotionPathSegmentCache, autoOrient: boolean,\n flatnessTol: number, rotationTol: number, maxSamples: number,\n): Array<number> {\n // Axis extrema (interior to (0, 1)).\n const extremes: Array<number> = [];\n addAxisExtremes(seg.P0[0], seg.P1[0], seg.P2[0], seg.P3[0], extremes);\n addAxisExtremes(seg.P0[1], seg.P1[1], seg.P2[1], seg.P3[1], extremes);\n extremes.sort((a, b) => a - b);\n\n const critical: Array<number> = [0];\n for (const t of extremes) {\n if (t > critical[critical.length - 1] + 1e-6 && t < 1 - 1e-6) {\n critical.push(t);\n }\n }\n critical.push(1);\n\n const out: Array<number> = [];\n const budget = { remaining: maxSamples - critical.length }; // already-committed critical points count against the budget\n for (let i = 0; i < critical.length - 1; i++) {\n bisect(critical[i], critical[i + 1], out, seg, autoOrient, flatnessTol, rotationTol, budget);\n }\n return out;\n}\n\n\n/** Solves `P'(t).axis = 0` for one axis (a quadratic in t). Pushes any real\n * roots in `(0, 1)` into `out`. Coefficients via standard cubic Bezier\n * derivative: with `a = p1 − p0, b = p2 − p1, c = p3 − p2`, the equation is\n * `(a − 2b + c)·t² + 2(b − a)·t + a = 0`. */\nfunction addAxisExtremes(p0: number, p1: number, p2: number, p3: number, out: Array<number>): void {\n const a = p1 - p0;\n const b = p2 - p1;\n const c = p3 - p2;\n const A = a - 2 * b + c;\n const B = 2 * (b - a);\n const C = a;\n if (Math.abs(A) < 1e-10) {\n if (Math.abs(B) > 1e-10) {\n const t = -C / B;\n if (t > 1e-6 && t < 1 - 1e-6) out.push(t);\n }\n return;\n }\n const disc = B * B - 4 * A * C;\n if (disc < 0) return;\n const sq = Math.sqrt(disc);\n const t1 = (-B - sq) / (2 * A);\n const t2 = (-B + sq) / (2 * A);\n if (t1 > 1e-6 && t1 < 1 - 1e-6) out.push(t1);\n if (t2 > 1e-6 && t2 < 1 - 1e-6) out.push(t2);\n}\n\n\n/** Adaptive bisection between `tA` and `tB`. Always appends `tB` exactly once\n * (either directly when the chord is flat enough, or via recursion).\n *\n * Flatness is tested at THREE interior points (t = 0.25, 0.5, 0.75 of the\n * sub-interval), not just the midpoint. Symmetric Bezier segments often have\n * the curve crossing the chord exactly at t=0.5 — a single-midpoint check\n * would mistake that for flatness and skip subdivision, leaving visible\n * chord deviation between samples. */\nfunction bisect(\n tA: number, tB: number,\n out: Array<number>,\n seg: MotionPathSegmentCache,\n autoOrient: boolean,\n flatnessTol: number, rotationTol: number,\n budget: { remaining: number },\n): void {\n const tMid = (tA + tB) / 2;\n const pA = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA);\n const pB = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tB);\n const span = tB - tA;\n const p25 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA + span * 0.25);\n const p50 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tMid);\n const p75 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA + span * 0.75);\n\n const dev = Math.max(\n perpDist(p25, pA, pB),\n perpDist(p50, pA, pB),\n perpDist(p75, pA, pB),\n );\n let rotOk = true;\n if (autoOrient) {\n const tanA = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, tA);\n const tanB = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, tB);\n const angA = Math.atan2(tanA[1], tanA[0]) * 180 / Math.PI;\n const angB = Math.atan2(tanB[1], tanB[0]) * 180 / Math.PI;\n let delta = Math.abs(angA - angB);\n if (delta > 180) delta = 360 - delta;\n if (delta > rotationTol) rotOk = false;\n }\n\n if ((dev <= flatnessTol && rotOk) || budget.remaining <= 0 || span < 1e-6) {\n out.push(tB);\n return;\n }\n\n budget.remaining -= 1;\n bisect(tA, tMid, out, seg, autoOrient, flatnessTol, rotationTol, budget);\n bisect(tMid, tB, out, seg, autoOrient, flatnessTol, rotationTol, budget);\n}\n\n\nfunction perpDist(q: Point2, pA: Point2, pB: Point2): number {\n const dx = pB[0] - pA[0];\n const dy = pB[1] - pA[1];\n const len2 = dx * dx + dy * dy;\n if (len2 < 1e-20) {\n const qdx = q[0] - pA[0];\n const qdy = q[1] - pA[1];\n return Math.sqrt(qdx * qdx + qdy * qdy);\n }\n const cross = (q[0] - pA[0]) * dy - (q[1] - pA[1]) * dx;\n return Math.abs(cross) / Math.sqrt(len2);\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Tree walker — applies `materialiseMotionPathInPropAnim` to every `node.animate.transform`\n// whose propAnim is a motion-path. Immutable: returns the input by reference\n// when no changes were needed; otherwise clones along the path to each\n// converted node and shares all other sub-trees.\n// ─────────────────────────────────────────────────────────────────────────────\n\n\nexport function materialiseMotionPathsInTree(\n root: PxNode,\n opts?: MotionPathMaterialisationOptions,\n): PxNode {\n const out = walkAndMaterialise(root, opts);\n return out ?? root;\n}\n\nfunction walkAndMaterialise(node: PxNode, opts?: MotionPathMaterialisationOptions): PxNode | null {\n let newChildren: Array<PxNode> | undefined;\n if (node.children) {\n for (let i = 0; i < node.children.length; i++) {\n const ch = node.children[i];\n const ret = walkAndMaterialise(ch, opts);\n if (ret !== null) {\n if (!newChildren) newChildren = node.children.slice();\n newChildren[i] = ret;\n }\n }\n }\n\n let newAnimate: Record<string, PxPropertyAnimation> | undefined;\n const animBucket = node.animate;\n if (animBucket && typeof animBucket === 'object' && !Array.isArray(animBucket)) {\n const animDef = animBucket as Record<string, PxPropertyAnimation>;\n const transformAnim = animDef.transform;\n if (transformAnim && typeof transformAnim === 'object' && propAnimIsMotionPath(transformAnim)) {\n const materialised = materialiseMotionPathInPropAnim(transformAnim, opts);\n if (materialised !== transformAnim) {\n newAnimate = { ...animDef, transform: materialised };\n }\n }\n }\n\n if (!newChildren && !newAnimate) return null;\n const cloned: PxNode = { ...node };\n if (newChildren) cloned.children = newChildren;\n if (newAnimate) cloned.animate = newAnimate as PxNode['animate'];\n return cloned;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport {\n getAnimatorConfig,\n getBindings,\n getDefs,\n PxAnimatorEngine,\n type PxAnimatedSvgDocument,\n type PxAnimationDefinition,\n type PxBezierPath,\n type PxBinding,\n type PxDefs,\n type PxElementAnimation,\n type PxKeyframe,\n type PxLoop,\n type PxNode,\n type PxPropertyAnimation,\n type PxTransformParts\n} from './PxAnimatorTypes';\nimport { bezierToSvgPath, camelCaseToKebabWordIfNeeded, clamp, COLOUR_ATTR_NAMES, composeTransformParts, cubicBezier, interpolateBeziers, interpolateColor, interpolateNum, interpolateVec, isCamelCaseWord, parseColor, PCT_BASED_ATTR_NAMES, remap, reverseEasing, splitEasing, toRGBA, TRANSFORM_FN_NAMES } from './PxAnimatorUtil';\nimport { evaluateMotionPathSegment, materialiseMotionPathInPropAnim, propAnimIsMotionPath } from './PxMotionPath';\n\n\n// ============================================================================\n// PATH PARSING: Convert \"path(...)\" strings to PxBezierPath format\n// ============================================================================\n\ninterface PathCommand {\n type: string;\n values: Array<number>;\n}\n\n/**\n * Parses an SVG path string into command tokens.\n * Supports M, L, C, Z commands (case-insensitive).\n */\nfunction parsePathCommands(d: string): Array<PathCommand> {\n const tokens = d.split(/([MLCZmlcz]|[\\s,]+)/).map(t => t.trim()).filter(t => t && t !== ',');\n\n const commands: Array<PathCommand> = [];\n let currentCommand: PathCommand | null = null;\n\n for (const token of tokens) {\n if (/[MLCZmlcz]/.test(token)) {\n currentCommand = { type: token, values: [] };\n commands.push(currentCommand);\n } else if (currentCommand) {\n const value = +token;\n currentCommand.values.push(Number.isNaN(value) ? 0 : value);\n }\n }\n\n return commands;\n}\n\n/**\n * Parses an internal SVG path string into PxBezierPath array.\n * Handles M (moveto), L (lineto), C (curveto), Z (close) commands.\n */\nexport function parseSvgPathToBezier(d: string): Array<PxBezierPath> {\n const res: Array<PxBezierPath> = [];\n let currentPath: PxBezierPath | undefined;\n\n const commands = parsePathCommands(d);\n\n for (const command of commands) {\n const type = command.type;\n const values = command.values;\n\n if (type === 'M' || type === 'm') {\n const x = values[0] || 0;\n const y = values[1] || 0;\n currentPath = {\n v: [[x, y]],\n i: [[x, y]],\n o: [[x, y]],\n c: false\n };\n res.push(currentPath);\n continue;\n }\n\n // Ensure we have a current path\n if (!currentPath) {\n currentPath = {\n v: [[0, 0]],\n i: [[0, 0]],\n o: [[0, 0]],\n c: false\n };\n res.push(currentPath);\n }\n\n if (type === 'L') {\n const x = values[0] || 0;\n const y = values[1] || 0;\n currentPath.v.push([x, y]);\n currentPath.i!.push([x, y]);\n currentPath.o!.push([x, y]);\n\n } else if (type === 'C') {\n const outX = values[0] || 0;\n const outY = values[1] || 0;\n const inX2 = values[2] || 0;\n const inY2 = values[3] || 0;\n const x2 = values[4] || 0;\n const y2 = values[5] || 0;\n\n // Update out-point of previous vertex\n currentPath.o![currentPath.o!.length - 1] = [outX, outY];\n\n // Add new vertex with its in-point\n currentPath.v.push([x2, y2]);\n currentPath.i!.push([inX2, inY2]);\n currentPath.o!.push([x2, y2]);\n\n } else if (type === 'Z' || type === 'z') {\n currentPath.c = true;\n\n } else {\n console.warn('Unsupported path command \"' + type + '\"');\n }\n }\n\n return res;\n}\n\n/**\n * Extracts SVG path data from a string.\n * Handles both \"path(M...)\" wrapper format and raw \"M...\" format.\n * @returns The path data string, or undefined if not a valid path string\n */\nfunction extractPathData(str: string): string | undefined {\n if (str.startsWith('path(') && str.endsWith(')')) {\n return str.slice(5, -1); // Remove \"path(\" and \")\"\n }\n // Raw path string starting with a path command (M, m, or other commands)\n if (/^[MmZzLlHhVvCcSsQqTtAa]/.test(str)) {\n return str;\n }\n return undefined;\n}\n\n/**\n * Checks if the value is a path string (either \"path(...)\" or raw \"M...\").\n */\nfunction isPathString(value: any): value is string {\n return typeof value === 'string' && extractPathData(value) !== undefined;\n}\n\n/**\n * Normalizes a 'd' attribute value to { paths: PxBezierPath[] } format.\n * Handles:\n * - { path: \"M...\" } / { path: \"path(...)\" } -> { paths: [PxBezierPath] } (unified single-string form)\n * - { paths: [\"path(...)\"] } -> { paths: [PxBezierPath] }\n * - { paths: [\"M...\"] } -> { paths: [PxBezierPath] }\n * - [\"path(...)\"] -> { paths: [PxBezierPath] }\n * - [\"M...\"] -> { paths: [PxBezierPath] }\n * - \"path(...)\" -> { paths: [PxBezierPath] }\n * - \"M...\" -> { paths: [PxBezierPath] }\n * - { paths: [PxBezierPath] } -> as-is\n */\nfunction normalizePathValue(value: any): { paths: Array<PxBezierPath> } | any {\n // Unified single-string form: { path: \"M...\" } (compound = multiple `M…` sub-paths in one string).\n if (value && typeof value === 'object' && typeof value.path === 'string') {\n const d = extractPathData(value.path);\n return d ? { paths: parseSvgPathToBezier(d) } : value;\n }\n\n // If already in { paths: [...] } format\n if (value && typeof value === 'object' && 'paths' in value) {\n const pathsArray = value.paths;\n if (Array.isArray(pathsArray) && pathsArray.length > 0) {\n // Check if paths contain path strings that need parsing\n if (isPathString(pathsArray[0])) {\n const paths: Array<PxBezierPath> = [];\n for (const pathStr of pathsArray) {\n const d = extractPathData(pathStr);\n if (d) {\n paths.push(...parseSvgPathToBezier(d));\n }\n }\n return { paths };\n }\n }\n // Already in correct format\n return value;\n }\n\n // If it's an array of path strings\n if (Array.isArray(value)) {\n if (value.length > 0 && isPathString(value[0])) {\n const paths: Array<PxBezierPath> = [];\n for (const pathStr of value) {\n const d = extractPathData(pathStr);\n if (d) {\n paths.push(...parseSvgPathToBezier(d));\n }\n }\n return { paths };\n }\n // Already an array of PxBezierPath - wrap in { paths: }\n return { paths: value };\n }\n\n // If it's a single path string\n if (isPathString(value)) {\n const d = extractPathData(value)!;\n return { paths: parseSvgPathToBezier(d) };\n }\n\n return value;\n}\n\n\n// ============================================================================\n// NORMALIZATION: Convert new API format to internal normalized format\n// ============================================================================\n\n/**\n * Resolves an easing reference to a cubic-bezier array.\n * @param easing The easing reference (string name or bezier array)\n * @param defs The definitions containing named easings\n * @returns The resolved cubic-bezier array or undefined\n */\nfunction resolveEasing(\n easing: string | [number, number, number, number] | undefined,\n defs?: PxDefs\n): [number, number, number, number] | undefined {\n if (!easing) return undefined;\n\n if (Array.isArray(easing)) {\n return easing;\n }\n\n // Look up named easing in defs\n if (defs?.easings?.[easing]) {\n return defs.easings[easing];\n }\n\n // Unknown easing name - return undefined\n console.warn('Unknown easing name: ' + easing);\n return undefined;\n}\n\n/**\n * Resolves an animation reference to an AnimationDefinition.\n * @param animRef The animation reference (string name or inline definition)\n * @param defs The definitions containing named animations\n * @returns The resolved animation definition\n */\nfunction resolveAnimation(\n animRef: string | PxAnimationDefinition,\n defs?: PxDefs\n): PxAnimationDefinition | undefined {\n if (typeof animRef === 'string') {\n // Look up named animation in defs\n const resolved = defs?.animations?.[animRef];\n if (!resolved) {\n console.warn('Unknown animation name: ' + animRef);\n }\n return resolved;\n }\n\n // It's an inline definition\n return animRef;\n}\n\n/**\n * Resolves an element animation (which can be string, array, or inline) to an array of AnimationDefinitions.\n * @param animate The element animation specification\n * @param defs The definitions containing named animations\n * @returns Array of resolved animation definitions\n */\nfunction resolveElementAnimation(\n animate: PxElementAnimation | undefined,\n defs?: PxDefs\n): PxAnimationDefinition[] {\n if (!animate) return [];\n\n const results: PxAnimationDefinition[] = [];\n\n if (typeof animate === 'string') {\n const resolved = resolveAnimation(animate, defs);\n if (resolved) results.push(resolved);\n } else if (Array.isArray(animate)) {\n for (const item of animate) {\n const resolved = resolveAnimation(item, defs);\n if (resolved) results.push(resolved);\n }\n } else {\n // It's an inline AnimationDefinition\n results.push(animate);\n }\n\n return results;\n}\n\n// ============================================================================\n// LOOP EXPANSION: Duplicate keyframe segments to fill gaps in the timeline\n// ============================================================================\n\n/**\n * Interpolates between two keyframe values based on property type.\n * Returns the raw interpolated value (not a CSS string).\n *\n * Dispatch order matters — the unified-transform-record branch must run\n * BEFORE the standalone-`rotate` branch, otherwise a `transform`-named\n * animation whose kfs are number-typed (rare but valid) would be routed\n * through the vec path.\n */\nexport function interpolateValue(propName: string, a: any, b: any, t: number): any {\n if (propName === 'd') {\n const aPaths = a?.paths ?? (Array.isArray(a) ? a : []);\n const bPaths = b?.paths ?? (Array.isArray(b) ? b : []);\n return { paths: interpolateBeziers(aPaths, bPaths, t) };\n }\n if (COLOUR_ATTR_NAMES.has(propName)) {\n return interpolateColor(a || [0, 0, 0, 1], b || [0, 0, 0, 1], t);\n }\n // Unified-transform record (`{translate, rotate, scale, origin}`) — the\n // most common animated `propName === 'transform'` shape. Per-part interp\n // so `+({}) = NaN` (the old fall-through) doesn't poison the boundary kf\n // at a loop seam.\n if (propName === 'transform'\n && typeof a === 'object' && a !== null && !Array.isArray(a)\n && typeof b === 'object' && b !== null && !Array.isArray(b)\n ) {\n return interpolateTransformParts(a as PxTransformParts, b as PxTransformParts, t);\n }\n // Standalone `rotate` as a propAnim — value is a NUMBER, not a vector.\n // The general TRANSFORM_FN_NAMES branch below would route it through\n // `interpolateVec`, which on a scalar returns `[]` (length NaN → no loop)\n // — wrong CSS output.\n if (propName === 'rotate' && typeof a === 'number' && typeof b === 'number') {\n return interpolateNum(a, b, t);\n }\n if (TRANSFORM_FN_NAMES.has(propName) || propName === 'stroke-dasharray' || propName === 'strokeDasharray') {\n return interpolateVec(a || [], b || [], t);\n }\n return interpolateNum(+(a || 0), +(b || 0), t);\n}\n\n/** Per-part interpolation for a unified-transform parts record. Mirrors the\n * inline logic in `calcPropertyValue`'s transform branch. */\nfunction interpolateTransformParts(a: PxTransformParts, b: PxTransformParts, t: number): PxTransformParts {\n const keys = new Set<string>([...Object.keys(a ?? {}), ...Object.keys(b ?? {})]);\n const out: { [k: string]: unknown } = {};\n for (const k of keys) {\n const av = (a as { [k: string]: unknown })?.[k];\n const bv = (b as { [k: string]: unknown })?.[k];\n if (k === 'rotate' || k === 'skew') {\n out[k] = interpolateNum(+(av ?? 0), +(bv ?? 0), t);\n } else if (k === 'translate' || k === 'scale' || k === 'origin') {\n const fallback: Array<number> = k === 'scale' ? [1, 1] : [0, 0];\n out[k] = interpolateVec((av as Array<number>) || fallback, (bv as Array<number>) || fallback, t);\n } else {\n // Unknown part — prefer next if present, otherwise prev.\n out[k] = bv ?? av;\n }\n }\n return out as PxTransformParts;\n}\n\ninterface LoopTemplateEntry {\n relT: number; // 0..1 relative position within segment\n v: any;\n e: [number, number, number, number] | undefined;\n // Per-vertex spatial tangents (motion-along-path). Carried so repeated\n // segments keep their curvature; reversed reps swap in<->out (see appendRep).\n tangentIn?: [number, number];\n tangentOut?: [number, number];\n}\n\n/**\n * Expands keyframes by repeating a segment to fill the gap between the keyframe\n * range and the global animation duration, implementing PxLoop \"local loop\" behavior.\n */\nfunction expandLoopKeyframes(\n propName: string,\n keyframes: PxKeyframe[],\n loop: PxLoop,\n duration: number\n): PxKeyframe[] {\n const totalIntervals = keyframes.length - 1;\n const segCount = clamp(loop.segmentCount ?? totalIntervals, 1, totalIntervals);\n\n // Extract segment keyframes\n let segKfs: PxKeyframe[];\n if (loop.before) {\n segKfs = keyframes.slice(0, segCount + 1);\n } else {\n segKfs = keyframes.slice(totalIntervals - segCount);\n }\n\n // Determine fill region\n const firstT = keyframes[0].t ?? 0;\n const lastT = keyframes[keyframes.length - 1].t ?? 0;\n\n let fillStart: number, fillEnd: number;\n if (loop.before) {\n fillStart = 0;\n fillEnd = firstT;\n } else {\n fillStart = lastT;\n fillEnd = duration;\n }\n\n const fillDuration = fillEnd - fillStart;\n if (fillDuration <= 0) return keyframes;\n\n // Segment timing\n const segStartT = segKfs[0].t ?? 0;\n const segEndT = segKfs[segKfs.length - 1].t ?? 0;\n const segDuration = segEndT - segStartT;\n if (segDuration <= 0) return keyframes;\n\n // Build template with relative offsets (0..1)\n const template: LoopTemplateEntry[] = segKfs.map(kf => ({\n relT: (kf.t! - segStartT) / segDuration,\n v: kf.v,\n e: kf.e as [number, number, number, number] | undefined,\n tangentIn: (kf.tangentIn ?? kf.ti) as [number, number] | undefined,\n tangentOut: (kf.tangentOut ?? kf.to) as [number, number] | undefined\n }));\n\n const fullReps = Math.floor(fillDuration / segDuration);\n const remainder = fillDuration - fullReps * segDuration;\n const partialFraction = remainder / segDuration;\n\n const looped: PxKeyframe[] = [];\n\n // Helper: append one full or partial repetition\n function appendRep(repStart: number, isReversed: boolean, partial?: number) {\n let entries: LoopTemplateEntry[];\n if (isReversed) {\n // Reverse keyframe order and reverse easings\n entries = [];\n for (let i = template.length - 1; i >= 0; i--) {\n entries.push({\n relT: 1 - template[i].relT,\n v: template[i].v,\n // Easing for reversed transition: use reversed easing from the forward \"from\" keyframe\n e: i > 0 ? reverseEasing(template[i - 1].e) : undefined,\n // Reversed traversal swaps each vertex's in/out spatial tangents\n // (geometry is identical, walked backwards), so curvature and\n // auto-orientation survive the reversed rep.\n tangentIn: template[i].tangentOut,\n tangentOut: template[i].tangentIn\n });\n }\n } else {\n entries = template;\n }\n\n const cutRelT = partial !== undefined ? partial : 1;\n\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n if (entry.relT > cutRelT + 1e-9) {\n // Past the cut point — insert interpolated keyframe\n const prev = entries[i - 1];\n const intervalSpan = entry.relT - prev.relT;\n const localFrac = (cutRelT - prev.relT) / intervalSpan;\n\n // Apply easing to get the eased progress for value interpolation\n const easedFrac = prev.e ? cubicBezier(prev.e)(localFrac) : localFrac;\n const cutValue = interpolateValue(propName, prev.v, entry.v, easedFrac);\n\n // Split easing — use left portion for the truncated interval\n const { left: leftEasing } = splitEasing(prev.e, localFrac);\n\n // Update previous keyframe's easing to the left portion\n if (looped.length > 0 && prev.relT <= cutRelT) {\n looped[looped.length - 1].e = leftEasing;\n }\n\n looped.push({ t: repStart + cutRelT * segDuration, v: cutValue, e: undefined });\n return;\n }\n\n const pushed: PxKeyframe = {\n t: repStart + entry.relT * segDuration,\n v: entry.v,\n e: i < entries.length - 1 ? entry.e : undefined\n };\n // Carry per-vertex spatial tangents so the repeated segment keeps its\n // motion-path curvature (reversed reps already have in/out swapped above).\n if (entry.tangentIn) pushed.tangentIn = entry.tangentIn;\n if (entry.tangentOut) pushed.tangentOut = entry.tangentOut;\n looped.push(pushed);\n }\n }\n\n // Like {@link appendRep} but emits only the TAIL of the segment — relT ∈\n // [1-tailFraction, 1] — over [repStart, repStart + tailFraction*segDuration].\n // Used for the leftover (partial) rep of a `before` loop: it sits at fillStart\n // and runs UP TO the segment-end value, so the full reps after it align to end\n // exactly at the first original keyframe (firstT). A head-truncated partial here\n // (as appendRep does) would land the leftover ADJACENT to firstT and desync the\n // whole backward fill — the loopIn `f0` bug.\n function appendRepTail(repStart: number, isReversed: boolean, tailFraction: number) {\n let entries: LoopTemplateEntry[];\n if (isReversed) {\n entries = [];\n for (let i = template.length - 1; i >= 0; i--) {\n entries.push({\n relT: 1 - template[i].relT,\n v: template[i].v,\n e: i > 0 ? reverseEasing(template[i - 1].e) : undefined,\n tangentIn: template[i].tangentOut,\n tangentOut: template[i].tangentIn\n });\n }\n } else {\n entries = template;\n }\n\n const startRelT = 1 - tailFraction;\n\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n if (entry.relT < startRelT - 1e-9) continue; // wholly before the tail window\n const prev = entries[i - 1];\n\n // If startRelT falls strictly inside (prev, entry), the tail begins\n // mid-interval — emit an interpolated keyframe at repStart carrying the\n // RIGHT split of prev's easing.\n if (prev && prev.relT < startRelT - 1e-9 && entry.relT > startRelT + 1e-9) {\n const intervalSpan = entry.relT - prev.relT;\n const localFrac = (startRelT - prev.relT) / intervalSpan;\n const easedFrac = prev.e ? cubicBezier(prev.e)(localFrac) : localFrac;\n const startValue = interpolateValue(propName, prev.v, entry.v, easedFrac);\n const { right: rightEasing } = splitEasing(prev.e, localFrac);\n looped.push({ t: repStart, v: startValue, e: rightEasing });\n }\n\n const pushed: PxKeyframe = {\n t: repStart + (entry.relT - startRelT) * segDuration,\n v: entry.v,\n e: i < entries.length - 1 ? entry.e : undefined\n };\n if (entry.tangentIn) pushed.tangentIn = entry.tangentIn;\n if (entry.tangentOut) pushed.tangentOut = entry.tangentOut;\n looped.push(pushed);\n }\n }\n\n // Generate repetitions.\n // The rep closest to the original keyframes boundary must be reversed first\n // in pingpong mode (the animation just finished going forward, so the next\n // iteration goes backward).\n if (loop.before) {\n // loopIn — the fill must END exactly at the first keyframe (firstT), so the\n // reps tile BACKWARD from that boundary: the leftover (partial) rep sits at\n // fillStart showing the segment's tail, then `fullReps` full reps run up to\n // firstT. (Forward-tiling — as loopOut does — would push the partial next to\n // firstT and desync the fill: the loopIn `f0` regression.)\n if (partialFraction > 1e-9) {\n const isReversed = !!loop.alternate && (fullReps % 2 === 0);\n appendRepTail(fillStart, isReversed, partialFraction);\n }\n for (let rep = 0; rep < fullReps; rep++) {\n const distFromBoundary = fullReps - 1 - rep;\n const isReversed = !!loop.alternate && (distFromBoundary % 2 === 0);\n const repStart = fillStart + remainder + rep * segDuration;\n appendRep(repStart, isReversed);\n }\n } else {\n // loopOut — boundary is at fillStart (lastT); tile forward, partial at the end.\n for (let rep = 0; rep < fullReps; rep++) {\n const isReversed = !!loop.alternate && (rep % 2 === 0);\n const repStart = fillStart + rep * segDuration;\n appendRep(repStart, isReversed);\n }\n if (partialFraction > 1e-9) {\n const isReversed = !!loop.alternate && (fullReps % 2 === 0);\n const repStart = fillStart + fullReps * segDuration;\n appendRep(repStart, isReversed, partialFraction);\n }\n }\n\n // Assemble: looped keyframes go before or after the original keyframes.\n // No junction deduplication — cycle mode relies on value jumps at boundaries.\n if (loop.before) {\n return [...looped, ...keyframes];\n } else {\n return [...keyframes, ...looped];\n }\n}\n\n\n// ============================================================================\n// KEYFRAME NORMALIZATION\n// ============================================================================\n\n/**\n * Normalizes keyframes from the new API format (time in ms) to internal format (time as 0-1 fraction).\n * Resolves easing references, normalizes times, and converts path strings for 'd' attribute.\n * If a loop configuration is present, expands the keyframes to fill the global duration.\n * @param propName The property name (e.g., 'd' for path)\n * @param propAnim The property animation with keyframes\n * @param duration The total animation duration in ms\n * @param defs The definitions containing named easings\n * @returns Array of normalized keyframes (same structure, resolved refs, normalized times)\n */\nfunction normalizeKeyframes(\n propName: string,\n propAnim: PxPropertyAnimation,\n duration: number,\n defs?: PxDefs\n): PxKeyframe[] {\n const keyframes = propAnim.keyframes || propAnim.kfs || [];\n\n const normalized: PxKeyframe[] = [];\n\n for (const kf of keyframes) {\n const timePct = kf.time ?? kf.t ?? 0;\n let value = kf.value ?? kf.v;\n const easing = kf.easing ?? kf.e;\n\n // Normalize path values for 'd' attribute\n if (propName === 'd') {\n value = normalizePathValue(value);\n }\n\n // Normalize color values (hex/rgb/rgba strings to [0-1] vectors).\n // `COLOUR_ATTR_NAMES` is keyed in kebab-case (`stop-color`, `flood-color`,\n // `lighting-color`); the wire format uses both kebab AND camelCase\n // (`stopColor`) for these props. Without converting, frames-mode would\n // call `interpolateColor` on the raw strings and produce `NaN` channels\n // — the visible \"rgba(NaN,NaN,NaN,…)\" bug on stop-color animations.\n const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;\n if (COLOUR_ATTR_NAMES.has(propNameKebab)) {\n value = parseColor(value) ?? value;\n }\n\n const normKf: PxKeyframe = {\n t: timePct,\n v: value,\n e: resolveEasing(easing, defs)\n };\n // Motion-along-path: keep the spatial tangents so the downstream\n // `materialiseMotionPathInPropAnim` (called in `normalizeAnimationDefinition`) can\n // sample them into transform kfs. Short aliases `ti` / `to` collapse\n // into their canonical names.\n const tIn = kf.tangentIn ?? kf.ti;\n const tOut = kf.tangentOut ?? kf.to;\n if (tIn) normKf.tangentIn = tIn;\n if (tOut) normKf.tangentOut = tOut;\n\n normalized.push(normKf);\n }\n\n // Sort by time\n normalized.sort((a, b) => (a.t ?? 0) - (b.t ?? 0));\n\n // Expand loop if configured (loop:true is shorthand for default PxLoop)\n const loopRaw = propAnim.loop;\n const loop: PxLoop | undefined = loopRaw === true ? {} : loopRaw || undefined;\n if (loop && normalized.length >= 2) {\n return expandLoopKeyframes(propName, normalized, loop, duration);\n }\n\n return normalized;\n}\n\n/**\n * Merges multiple animation definitions into a single combined definition.\n * Later definitions override earlier ones for the same property.\n */\nfunction mergeAnimationDefinitions(\n animations: PxAnimationDefinition[]\n): PxAnimationDefinition {\n const merged: PxAnimationDefinition = {};\n\n for (const anim of animations) {\n for (const [prop, propAnim] of Object.entries(anim)) {\n merged[prop] = propAnim;\n }\n }\n\n return merged;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Public loop-materialisation API\n//\n// Used internally by `normalizeKeyframes` (where `expandLoopKeyframes` is\n// already called at the tail of normalisation). Exposed here at the propAnim\n// and tree levels so the Editor (or any external caller) can compose:\n// root = applyPlayerEffects(root).root;\n// root = materialiseInternalLoopsInTree(root, duration);\n// root = materialiseMotionPathsInTree(root);\n// to produce a fully-flat document with no `loop`, no `effects`, no tangents.\n// ─────────────────────────────────────────────────────────────────────────────\n\n\n/**\n * Replaces `propAnim.loop` with explicit repeated keyframes via\n * `expandLoopKeyframes`. Returns the input by reference when no loop is\n * configured (no-op). Output drops the `loop` field (consumed).\n */\nexport function materialiseInternalLoopsInPropAnim(\n propName: string,\n propAnim: PxPropertyAnimation,\n duration: number,\n): PxPropertyAnimation {\n const loopRaw = propAnim.loop;\n if (loopRaw === undefined || loopRaw === null || loopRaw === false) return propAnim;\n const loop: PxLoop = loopRaw === true ? {} : (loopRaw as PxLoop);\n const rawKfs = (propAnim.keyframes ?? propAnim.kfs) as PxKeyframe[] | undefined;\n if (!Array.isArray(rawKfs) || rawKfs.length < 2) return propAnim;\n\n // `expandLoopKeyframes` reads kf.t / kf.v / kf.e (short form). When this\n // function is called from the materialisation pipeline OUTSIDE the\n // binding-normalisation path (e.g. by `materialiseAllInTree`), the input\n // kfs may still be in long form (`time` / `value` / `easing`) AND the\n // values may be unparsed (hex colour strings, raw path-`d`). Normalise\n // both here so `interpolateValue` (called by `expandLoopKeyframes` at the\n // loop seam) sees structured data — without this, a colour boundary kf\n // ends up `[NaN,NaN,NaN,NaN]` and the bug stays visible until the\n // animation cycle restarts.\n const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;\n const isColour = COLOUR_ATTR_NAMES.has(propNameKebab);\n const kfs: PxKeyframe[] = rawKfs.map(kf => {\n const t = kf.t ?? kf.time;\n let v: unknown = kf.v ?? kf.value;\n if (propName === 'd') v = normalizePathValue(v);\n if (isColour) v = parseColor(v) ?? v;\n const e = kf.e ?? kf.easing;\n const out: PxKeyframe = { t, v, e } as PxKeyframe;\n if (kf.tangentIn ?? kf.ti) out.tangentIn = (kf.tangentIn ?? kf.ti) as [number, number];\n if (kf.tangentOut ?? kf.to) out.tangentOut = (kf.tangentOut ?? kf.to) as [number, number];\n return out;\n });\n\n const expanded = expandLoopKeyframes(propName, kfs, loop, duration);\n const out: PxPropertyAnimation = { kfs: expanded } as PxPropertyAnimation;\n if (propAnim.autoOrient !== undefined) (out as { autoOrient?: unknown }).autoOrient = propAnim.autoOrient;\n return out;\n}\n\n\n/**\n * Walks `root` and materialises every animated property's `loop` via\n * `materialiseInternalLoopsInPropAnim`. Immutable — returns the input by\n * reference when no loop was found anywhere; otherwise clones along the path\n * to each affected node, sharing untouched sub-trees.\n */\nexport function materialiseInternalLoopsInTree(\n root: PxNode,\n duration: number,\n): PxNode {\n const ret = walkAndMaterialiseLoops(root, duration);\n return ret ?? root;\n}\n\nfunction walkAndMaterialiseLoops(node: PxNode, duration: number): PxNode | null {\n let newChildren: Array<PxNode> | undefined;\n if (node.children) {\n for (let i = 0; i < node.children.length; i++) {\n const ret = walkAndMaterialiseLoops(node.children[i], duration);\n if (ret !== null) {\n if (!newChildren) newChildren = node.children.slice();\n newChildren[i] = ret;\n }\n }\n }\n let newAnimate: Record<string, PxPropertyAnimation> | undefined;\n const animBucket = node.animate;\n if (animBucket && typeof animBucket === 'object' && !Array.isArray(animBucket)) {\n const animDef = animBucket as Record<string, PxPropertyAnimation>;\n for (const propName of Object.keys(animDef)) {\n const propAnim = animDef[propName];\n const materialised = materialiseInternalLoopsInPropAnim(propName, propAnim, duration);\n if (materialised !== propAnim) {\n if (!newAnimate) newAnimate = { ...animDef };\n newAnimate[propName] = materialised;\n }\n }\n }\n if (!newChildren && !newAnimate) return null;\n const cloned: PxNode = { ...node };\n if (newChildren) cloned.children = newChildren;\n if (newAnimate) cloned.animate = newAnimate as PxNode['animate'];\n return cloned;\n}\n\n\n/**\n * Generates a unique element ID for internal tracking during DOM rendering.\n */\nlet _elementIdCounter = 0;\nexport function generateElementId(): string {\n return '_px_el_' + (++_elementIdCounter);\n}\n\n/**\n * Resets the element ID counter (useful for testing).\n */\nexport function resetElementIdCounter(): void {\n _elementIdCounter = 0;\n}\n\n/**\n * Normalizes an animation definition by resolving easing references and normalizing keyframe times.\n * Keeps the key/value mapping structure. `engine` controls motion-along-path\n * handling — see {@link PxAnimatorEngine}.\n */\nfunction normalizeAnimationDefinition(\n animDef: PxAnimationDefinition,\n duration: number,\n defs?: PxDefs,\n engine: PxAnimatorEngine = PxAnimatorEngine.webapi,\n): PxAnimationDefinition {\n const normalized: PxAnimationDefinition = {};\n\n for (const [propName, propAnim] of Object.entries(animDef)) {\n const normalizedKfs = normalizeKeyframes(propName, propAnim, duration, defs);\n if (normalizedKfs.length > 0) {\n const out: PxPropertyAnimation = { kfs: normalizedKfs };\n // Carry top-level animation flags through normalization — `materialiseMotionPathInPropAnim`\n // and the runtime evaluators need `autoOrient` / `loop` to be present\n // alongside the kfs.\n if (propAnim.autoOrient !== undefined) out.autoOrient = propAnim.autoOrient;\n if (propAnim.loop !== undefined) out.loop = propAnim.loop;\n\n // Pipeline: loops are already expanded by `normalizeKeyframes` above.\n // For the `webapi` engine ONLY, materialise motion-along-path\n // (tangented `transform` kfs + autoOrient) into plain sampled\n // `{ translate, rotate? }` kfs — CSS WAAPI can't evaluate parametric\n // tangents at runtime. Frames-mode keeps the parametric form so the\n // frame-loop kernel `evaluateMotionPathSegment` can sample per frame\n // (better spatial fidelity than any finite sampling).\n // `materialiseMotionPathInPropAnim` is a no-op for non-motion-path\n // animations, so non-transform props pay zero cost.\n normalized[propName] = (engine === PxAnimatorEngine.webapi && propName === 'transform')\n ? materialiseMotionPathInPropAnim(out)\n : out;\n }\n }\n\n return normalized;\n}\n\n/**\n * Normalizes a PxAnimatedSvgDocument to a PxAnimatorConfig for the animation engines.\n * This is the main entry point for converting the new API format to internal format.\n * Resolves animation/easing references. `engine` controls motion-along-path\n * handling — see {@link PxAnimatorEngine}.\n */\nexport function getNormalisedBindings(\n doc: PxAnimatedSvgDocument,\n engine: PxAnimatorEngine = PxAnimatorEngine.webapi,\n): PxBinding[] {\n const animatorConfig = getAnimatorConfig(doc) || {};\n const defs = getDefs(doc);\n const duration = animatorConfig.duration || 1000; // FIXME - get rid of 1000 here\n\n const bindings: PxBinding[] = [];\n\n // Helper to resolve and normalize animation for a binding\n const processAnimation = (\n id: string,\n animate: PxElementAnimation | undefined\n ): PxBinding | null => {\n if (!animate) return null;\n\n const animDefs = resolveElementAnimation(animate, defs);\n if (animDefs.length === 0) return null;\n\n const merged = mergeAnimationDefinitions(animDefs);\n const normalizedAnim = normalizeAnimationDefinition(merged, duration, defs, engine);\n\n if (Object.keys(normalizedAnim).length === 0) return null;\n\n return {\n id,\n animate: normalizedAnim\n };\n };\n\n // Process bindings (for pre-rendered DOM)\n const docBindings = getBindings(doc);\n if (docBindings) {\n for (const binding of docBindings) {\n const normalized = processAnimation(binding.id, binding.animate);\n if (normalized) bindings.push(normalized);\n }\n }\n\n // Process children (for rendered DOM).\n //\n // Per-element animations live under the node's `animate` bucket, keyed by\n // SVG/CSS property name — a PxAnimationDefinition (`{ transform: {keyframes},\n // fill: {keyframes}, … }`). The static initial value of each animated\n // property is carried separately as a plain attribute on the element body.\n // On-disk locations: top-level `node.animate` (JSON form).\n const processNode = (node: PxNode) => {\n const inlineAnim = node.animate;\n if (inlineAnim && Object.keys(inlineAnim).length > 0) {\n const nodeId = node.id || generateElementId();\n node.id = nodeId; // Ensure the node has an ID\n const normalized = processAnimation(nodeId, inlineAnim);\n if (normalized) bindings.push(normalized);\n }\n\n // Process children\n if (node.children) {\n for (let i = 0; i < node.children.length; i++) {\n processNode(node.children[i]);\n }\n }\n };\n\n // Process children of the root\n if (doc.children) {\n for (let i = 0; i < doc.children.length; i++) {\n processNode(doc.children[i]);\n }\n }\n\n return bindings;\n}\n\n\n// ============================================================================\n// ATTRIBUTE VALUE CALCULATION (used by frame loop animator)\n// ============================================================================\n\n/**\n * Finds prev/next keyframes for a given progress.\n */\nfunction getKeyframesPair(keyframes: PxKeyframe[], progress: number) {\n // Outside the keyframe range, clamp to the NEAREST REAL segment (the caller clamps\n // `localProgress` to 0/1, so that holds the boundary pose). Spanning first→last\n // instead would invent a segment that exists nowhere in the animation: for keyframes\n // that start part-way into the timeline, the pre-start frames used to interpolate\n // straight from the first to the LAST keyframe — skipping everything between, and\n // handing motion-path evaluation a chord it then cached (see `getSegmentCache`).\n const last = keyframes.length - 1;\n let prevKf = keyframes[0];\n let nextKf = keyframes[last > 0 ? 1 : 0];\n\n for (let j = 0; j < last; j++) {\n const aOff = (keyframes[j].t ?? 0);\n const bOff = (keyframes[j + 1].t ?? 0);\n if (aOff <= progress && progress <= bOff) {\n prevKf = keyframes[j];\n nextKf = keyframes[j + 1];\n break;\n }\n // Past this segment and not bracketed by any later one → hold the final segment.\n if (progress > bOff && j === last - 1) {\n prevKf = keyframes[last > 0 ? last - 1 : 0];\n nextKf = keyframes[last];\n }\n }\n return { prevKf, nextKf };\n}\n\n/**\n * Calculates interpolated value for a single property animation.\n */\nfunction calcPropertyValue(\n propName: string,\n propAnim: PxPropertyAnimation,\n progress: number\n): { k: string, v: string } | null {\n const keyframes = propAnim.kfs || propAnim.keyframes || [];\n if (keyframes.length === 0) return null;\n\n const { prevKf, nextKf } = getKeyframesPair(keyframes, progress);\n\n // remap to local 0..1 within prevKf..nextKf\n let localProgress = (prevKf === nextKf) ? 0 : remap(progress, prevKf.t ?? 0, nextKf.t ?? 0, 0, 1);\n localProgress = clamp(localProgress, 0, 1);\n const easing = prevKf.e ?? prevKf.easing; // e is on the source keyframe: applied from this KF to the next\n if (easing && Array.isArray(easing)) {\n try {\n localProgress = cubicBezier(easing as [number, number, number, number])(localProgress);\n } catch (e) {\n // fallback: ignore easing if parsing fails\n }\n }\n\n let cssAttrName = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;\n let cssValue: string | number | null = null;\n\n const prevV = prevKf?.v ?? prevKf?.value;\n const nextV = nextKf?.v ?? nextKf?.value;\n\n if (cssAttrName === 'd') {\n // Extract paths from { paths: [...] } format\n const prevPaths = prevV?.paths ?? (Array.isArray(prevV) ? prevV : []);\n const nextPaths = nextV?.paths ?? (Array.isArray(nextV) ? nextV : []);\n cssValue = interpolateBeziers(\n prevPaths,\n nextPaths,\n localProgress\n ).map(bz => bezierToSvgPath(bz)).join('');\n } else if (COLOUR_ATTR_NAMES.has(cssAttrName)) {\n cssValue = toRGBA(interpolateColor(\n prevV || [0, 0, 0, 1],\n nextV || [0, 0, 0, 1],\n localProgress\n ));\n cssAttrName = propName;\n } else if (cssAttrName === 'stroke-dasharray') {\n cssValue = interpolateVec(\n prevV || [],\n nextV || [],\n localProgress\n ).join(' ');\n cssAttrName = propName;\n } else if (\n cssAttrName === 'transform' &&\n prevV !== null && typeof prevV === 'object' && !Array.isArray(prevV)\n ) {\n // Unified transform: keyframe values are PxTransformParts records.\n // Interpolate each present part separately, then compose into a transform\n // string for the SVG `transform` attribute (no units).\n const partKeys = new Set<string>([\n ...(prevV ? Object.keys(prevV) : []),\n ...(nextV ? Object.keys(nextV) : []),\n ]);\n const partsResult: PxTransformParts = {};\n for (const partKey of partKeys) {\n const prevPart = prevV?.[partKey];\n const nextPart = nextV?.[partKey];\n if (partKey === 'rotate' || partKey === 'skew') {\n partsResult[partKey] = interpolateNum(+(prevPart ?? 0), +(nextPart ?? 0), localProgress);\n } else if (partKey === 'translate' || partKey === 'scale' || partKey === 'origin') {\n const fallback = partKey === 'scale' ? [1, 1] : [0, 0];\n const interp = interpolateVec(prevPart || fallback, nextPart || fallback, localProgress);\n (partsResult as any)[partKey] = interp;\n }\n }\n // Motion-along-path override (frames-mode only). The WAAPI binding\n // pipeline materialises tangents + autoOrient into sampled\n // `{translate, rotate}` kfs upstream (in `normalizeAnimationDefinition`),\n // so for WAAPI this branch is a no-op (`propAnimIsMotionPath` returns\n // false on already-materialised kfs). Frames-mode preserves the\n // parametric form and we evaluate the Bezier per frame here — gives\n // exact spatial fidelity vs. any finite sampling.\n if (propAnimIsMotionPath(propAnim)) {\n const prevTr = (prevV as { translate?: [number, number] }).translate;\n const nextTr = (nextV as { translate?: [number, number] }).translate;\n if (Array.isArray(prevTr) && Array.isArray(nextTr)) {\n const sample = evaluateMotionPathSegment(\n prevKf, nextKf,\n [+prevTr[0], +prevTr[1]],\n [+nextTr[0], +nextTr[1]],\n localProgress,\n !!propAnim.autoOrient,\n );\n partsResult.translate = [sample.translate[0], sample.translate[1]];\n if (sample.rotateDeg !== undefined) partsResult.rotate = sample.rotateDeg;\n }\n }\n cssValue = composeTransformParts(partsResult, { withUnits: false });\n cssAttrName = 'transform';\n } else if (cssAttrName === 'translate') {\n const v = interpolateVec(\n prevV || [0, 0],\n nextV || [0, 0],\n localProgress\n );\n cssValue = 'translate(' + v.join(',') + ')';\n cssAttrName = 'transform';\n } else if (cssAttrName === 'rotate') {\n const v = interpolateNum(\n +(prevV || 0),\n +(nextV || 0),\n localProgress\n );\n cssValue = 'rotate(' + v + ')';\n cssAttrName = 'transform';\n } else if (cssAttrName === 'scale') {\n const v = interpolateVec(\n prevV || [1, 1],\n nextV || [1, 1],\n localProgress\n );\n cssValue = 'scale(' + v.join(',') + ')';\n cssAttrName = 'transform';\n } else {\n // numeric attr\n const num = interpolateNum(\n +(prevV || 0),\n +(nextV || 0),\n localProgress\n );\n cssValue = num;\n }\n\n if (PCT_BASED_ATTR_NAMES.has(cssAttrName) && typeof cssValue === 'number') {\n cssValue = (cssValue * 100) + '%';\n }\n\n return { k: cssAttrName, v: cssValue === null ? '' : '' + cssValue };\n}\n\n/**\n * Calculates interpolated attribute values for an animation definition.\n * @param animDef The animation definition (with resolved refs and normalized times)\n * @param progress The current animation progress (0-1)\n * @returns Object with computed attribute name/value pairs\n */\nexport function calcAnimationValues(\n animDef: PxAnimationDefinition,\n progress: number\n): Record<string, string> {\n const result: Record<string, string> = {};\n\n for (const [propName, propAnim] of Object.entries(animDef)) { \n const computed = calcPropertyValue(propName, propAnim, progress);\n if (computed) {\n result[computed.k] = computed.v;\n }\n }\n\n return result;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n/**\n * Shared \"clone a subtree and rewire its internal references\" primitives.\n *\n * Used by:\n * - The retime effect's `<use>` chain materialiser (`effects/util.ts`'s\n * `clone` + `regenerateIdsInClone`, which now delegate here).\n * - `PxAnimatorUseMaterialiser` — the WAAPI-side post-pass that replaces\n * `<use>` instances referencing animated subtrees with deep clones.\n *\n * Both call sites need the exact same two operations: a structural deep clone\n * of a `PxNode` subtree, and a renumber-all-ids pass that also rewrites\n * internal `href=\"#X\"` / `url(#X)` references to the new ids while leaving\n * outward-facing references alone.\n */\n\nimport type { PxNode } from './PxAnimatorTypes';\n\n\n/** Recursive deep clone for plain JSON-shaped `PxNode` data (objects, arrays,\n * primitives). Faster than `JSON.parse(JSON.stringify(x))` for large trees,\n * no behaviour difference for our wire format (no `Date` / `Map` / functions).\n */\nexport function deepClonePxNode<T>(value: T): T {\n if (value === null || typeof value !== 'object') return value;\n if (Array.isArray(value)) return value.map(deepClonePxNode) as unknown as T;\n const out: { [k: string]: unknown } = {};\n for (const k of Object.keys(value as object)) out[k] = deepClonePxNode((value as { [k: string]: unknown })[k]);\n return out as T;\n}\n\n\n/**\n * Regenerates every `id` inside `root` (root included) using fresh ids from\n * `genId()`, then rewrites internal DOM references (`href=\"#oldId\"` and\n * `url(#oldId)` inside string attrs) to the new ids. References that point\n * OUTSIDE the cloned subtree are left untouched.\n *\n * `meta.*`, `effects.*`, `animate.*` are intentionally skipped — they don't\n * carry DOM-reference syntax, and walking them per-string is wasted work.\n *\n * Returns the old→new id map so callers can rewrite their own outward-facing\n * references (e.g. a `<use>` href pointing at the cloned subtree root).\n */\nexport function regenerateIdsAndRewriteRefs(\n root: PxNode,\n genId: () => string,\n): Map<string, string> {\n const oldToNew = new Map<string, string>();\n\n const walkAssign = (n: PxNode): void => {\n if (typeof n.id === 'string') {\n const newId = genId();\n oldToNew.set(n.id, newId);\n n.id = newId;\n }\n n.children?.forEach(walkAssign);\n };\n walkAssign(root);\n\n const rewriteUrl = (s: string): string => s.replace(/url\\(#([^)]+)\\)/g, (m, oldId) => {\n const newId = oldToNew.get(oldId);\n return newId ? 'url(#' + newId + ')' : m;\n });\n\n const walkRewrite = (n: PxNode): void => {\n if (typeof n.href === 'string' && n.href.startsWith('#')) {\n const newId = oldToNew.get(n.href.slice(1));\n if (newId) n.href = '#' + newId;\n }\n for (const k of Object.keys(n)) {\n if (k === 'children' || k === 'effects' || k === 'meta' || k === 'animate' || k === 'href' || k === 'id') continue;\n const v = (n as { [k: string]: unknown })[k];\n if (typeof v === 'string' && v.indexOf('url(#') !== -1) {\n (n as { [k: string]: unknown })[k] = rewriteUrl(v);\n }\n }\n n.children?.forEach(walkRewrite);\n };\n walkRewrite(root);\n\n return oldToNew;\n}\n\n\nfunction toFiniteNum(v: unknown): number {\n const n = typeof v === 'number' ? v : typeof v === 'string' ? parseFloat(v) : NaN;\n return Number.isFinite(n) ? n : 0;\n}\n\n/**\n * Applies a `<use>`'s `x`/`y` offset when it is materialised into a `<g>`.\n *\n * Per SVG 2, `<use x y>` is an extra `translate(x, y)` appended AFTER the use's\n * own `transform`, so it composes innermost (closest to the referenced content).\n * `<g>` has no `x`/`y`, so the offset must become a transform — and when the use\n * also carries a (possibly animated) `transform`, the two can't be merged into a\n * single attribute, so the content is wrapped in an inner offset `<g>`:\n *\n * <use transform=\"T\" x=\"X\" y=\"Y\">\n * → <g transform=\"T\"><g transform=\"translate(X,Y)\">…content…</g></g>\n *\n * With no transform/animation, a single `<g transform=\"translate(X,Y)\">` suffices.\n *\n * `gNode` is the `<g>` already derived from the use (type:'g', href dropped, the\n * use's `transform`/`animate`/etc. carried over, `x`/`y` still present). Mutates\n * and returns it; `x`/`y` are removed.\n */\nexport function applyUseOffsetToG(gNode: PxNode): PxNode {\n const x = toFiniteNum((gNode as { x?: unknown }).x);\n const y = toFiniteNum((gNode as { y?: unknown }).y);\n delete (gNode as { x?: unknown }).x;\n delete (gNode as { y?: unknown }).y;\n if (!x && !y) return gNode;\n\n const offset = 'translate(' + x + ',' + y + ')';\n\n // Any existing transform/animation on the outer <g> must apply OUTSIDE the\n // offset, so push the offset into an inner wrapper rather than risk\n // overwriting/conflicting with the carried-over `transform`/`animate`.\n const carriesTransform =\n (gNode as { transform?: unknown }).transform !== undefined ||\n (gNode as { animate?: unknown }).animate !== undefined;\n\n if (carriesTransform) {\n const inner: PxNode = { type: 'g', transform: offset, children: gNode.children ?? [] } as PxNode;\n gNode.children = [inner];\n } else {\n (gNode as { transform?: string }).transform = offset;\n }\n return gNode;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n/**\n * `<use>` instance materialiser.\n *\n * WAAPI / CSS animations applied to an SVG source element don't reliably\n * render through `<use>` shadow trees in Chrome and Safari — the source\n * animates, the `<use>` shows static. This module fixes that by deep-cloning\n * every animated target into the corresponding `<use>` site (with fresh ids\n * and rewritten internal refs), and replacing the `<use>` with a `<g>` that\n * carries the use's transform/x/y attributes. Both engines (frames + webapi)\n * then animate the cloned nodes directly.\n *\n * Shares the deep-clone + id-regen + ref-rewrite primitives with the retime\n * effect (see `PxNodeCloneUtil`).\n *\n * Immutable: returns the input by reference when no `<use>` needs\n * materialisation; otherwise returns a new tree sharing untouched sub-trees.\n */\n\nimport { applyUseOffsetToG, deepClonePxNode, regenerateIdsAndRewriteRefs } from './PxNodeCloneUtil';\nimport type { PxNode } from './PxAnimatorTypes';\n\n\n/**\n * Walks `root`. For every `<use>` whose `href` target subtree contains any\n * `animate` bucket (recursively, following further `<use>` chains and\n * children), replaces the `<use>` with a `<g>` carrying a deep clone of the\n * target. The clone gets a fresh id on every node, and any internal `href` /\n * `url(#…)` refs that pointed at ids inside the cloned subtree are rewritten\n * to the new ids. Refs that point OUTSIDE the cloned subtree (e.g. a sibling\n * gradient) are left untouched.\n *\n * Recursive: if the materialised clone itself contains a `<use>` that needs\n * materialisation, that's handled in the same pass.\n */\nexport function materialiseAnimatedUseInstances(root: PxNode): PxNode {\n const idMap = buildIdMap(root);\n const animatedIds = computeAnimatedSubtreeIds(root, idMap);\n if (animatedIds.size === 0) return root;\n\n let idCounter = 0;\n const genId = (): string => '_lw_use_mat_' + (++idCounter);\n\n // The use's default width/height resolves against its viewport (= the\n // root `<svg>`). We snapshot the root's viewBox dimensions once so the\n // symbol-rewrite below can compute the viewBox-to-use-viewport scaling\n // without re-walking the tree for each use.\n const rootViewport = readRootViewport(root);\n\n // Collects clipPath / other defs minted by the symbol-rewrite path. After\n // the walk completes, these are spliced into the root tree's `<defs>`.\n const defsCollector: Array<PxNode> = [];\n const walked = walkAndMaterialise(root, idMap, animatedIds, genId, defsCollector, rootViewport);\n if (defsCollector.length === 0) return walked;\n\n // Append a `<defs>` child carrying every collected def. Browsers honour\n // multiple `<defs>` on the same SVG root, so we don't need to splice into\n // an existing one (which would also be more invasive — defs may have been\n // shared by reference with the original tree).\n const defsNode: PxNode = { type: 'defs', children: defsCollector };\n const newChildren = [...(walked.children ?? []), defsNode];\n return { ...walked, children: newChildren };\n}\n\n\n/** Reads the root `<svg>`'s effective viewport dimensions. Used as the\n * default for `<use>` width/height (which default to 100% of viewport per\n * SVG spec). Tries `viewBox` first (the typical authored shape from our\n * serialiser), then falls back to explicit `width`/`height` attrs. */\nfunction readRootViewport(root: PxNode): [number, number] {\n const vb = parseViewBox((root as { viewBox?: unknown }).viewBox);\n if (vb) return [vb[2], vb[3]];\n const w = numericAttr((root as { width?: unknown }).width);\n const h = numericAttr((root as { height?: unknown }).height);\n if (w !== undefined && h !== undefined) return [w, h];\n // No info — fall back to a 1:1 viewport so the scale degrades to \"identity\n // along the limiting axis\" (= the historical no-scale behaviour). Better\n // than NaN; the failing case is \"root has no viewport info at all\".\n return [1, 1];\n}\n\nfunction numericAttr(v: unknown): number | undefined {\n if (typeof v === 'number') return v;\n if (typeof v === 'string') {\n // Strip a trailing `px` or `%` — for percentages we don't have an\n // outer container to resolve against, so we treat the raw number as\n // the absolute size (correct when the user only authored a viewBox\n // and width/height match it).\n const n = parseFloat(v);\n return Number.isFinite(n) ? n : undefined;\n }\n return undefined;\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Internals\n// ─────────────────────────────────────────────────────────────────────────────\n\n\nfunction buildIdMap(root: PxNode): Map<string, PxNode> {\n const map = new Map<string, PxNode>();\n const visit = (n: PxNode): void => {\n if (typeof n.id === 'string') map.set(n.id, n);\n n.children?.forEach(visit);\n };\n visit(root);\n return map;\n}\n\n\n/** Returns the set of ids whose subtree (including descendants and any\n * `<use>`-referenced sub-subtrees) contains at least one `animate` bucket.\n * Uses a per-walk `visited` set to avoid infinite recursion on `<use>` cycles. */\nfunction computeAnimatedSubtreeIds(root: PxNode, idMap: Map<string, PxNode>): Set<string> {\n const cache = new WeakMap<PxNode, boolean>();\n const result = new Set<string>();\n\n const hasAnim = (n: PxNode, visiting: Set<PxNode>): boolean => {\n const cached = cache.get(n);\n if (cached !== undefined) return cached;\n if (visiting.has(n)) return false; // cycle guard\n visiting.add(n);\n\n let r = false;\n if (n.animate && typeof n.animate === 'object' && !Array.isArray(n.animate)) {\n for (const _ in n.animate) { r = true; break; }\n }\n if (!r && n.children) {\n for (const ch of n.children) {\n if (hasAnim(ch, visiting)) { r = true; break; }\n }\n }\n if (!r && n.type === 'use' && typeof n.href === 'string') {\n const targetId = stripHash(n.href);\n const target = targetId ? idMap.get(targetId) : undefined;\n if (target) r = hasAnim(target, visiting);\n }\n\n visiting.delete(n);\n cache.set(n, r);\n return r;\n };\n\n for (const [id, node] of idMap) {\n if (hasAnim(node, new Set())) result.add(id);\n }\n return result;\n}\n\n\nfunction stripHash(href: unknown): string | undefined {\n if (typeof href !== 'string') return undefined;\n return href.startsWith('#') ? href.slice(1) : href;\n}\n\n\n/** Builds the materialised `<g>` replacement for one `<use>` whose target's\n * subtree is animated. Carries the use's transform / position attributes. */\nfunction materialiseOneUse(\n useNode: PxNode,\n target: PxNode,\n idMap: Map<string, PxNode>,\n animatedIds: Set<string>,\n genId: () => string,\n defsCollector: Array<PxNode>,\n rootViewport: [number, number],\n): PxNode {\n const clone = deepClonePxNode(target);\n regenerateIdsAndRewriteRefs(clone, genId);\n\n // Use's effective width/height — explicit attrs if set; else the referenced\n // `<symbol>`'s OWN viewBox size (a `<use>` on a symbol-with-viewBox renders at\n // the symbol's natural size, NOT 100% of the viewport — the latter scales the\n // symbol up, e.g. 80×80 → 139×139). Our serialiser now always emits explicit\n // width/height, so this fallback is the safety net for inputs that omit them.\n // Falls back to the root viewport only when there's no viewBox to size from.\n const symbolViewBox = clone.type === 'symbol' ? parseViewBox((clone as { viewBox?: unknown }).viewBox) : undefined;\n const useW = numericAttr((useNode as { width?: unknown }).width) ?? symbolViewBox?.[2] ?? rootViewport[0];\n const useH = numericAttr((useNode as { height?: unknown }).height) ?? symbolViewBox?.[3] ?? rootViewport[1];\n\n // `<symbol>` is invisible unless instantiated by `<use>` — a bare clone\n // of it inside our wrapping `<g>` would render nothing. Rewrite the\n // clone-root `<symbol>` into a `<g>` carrying the symbol's viewBox-derived\n // transform + clip (mirroring the browser's `<use href=\"#symbol\">`\n // viewport mapping). Any clipPath defs created go into `defsCollector`.\n const rewrittenClone = clone.type === 'symbol'\n ? rewriteSymbolRootToGroup(clone, genId, defsCollector, useW, useH)\n : clone;\n\n // Recurse into the clone — any nested `<use>` it contains may itself\n // reference an animated subtree and need materialisation.\n const materialisedClone = walkAndMaterialise(rewrittenClone, idMap, animatedIds, genId, defsCollector, rootViewport);\n\n // Replace `<use>` with `<g>` wrapping the clone. Keep all of use's own\n // attrs except `href` (now meaningless). `<g>` has no `x`/`y`, so the use's\n // position offset is converted to a `translate(x,y)` (applied AFTER any\n // transform — see `applyUseOffsetToG`) rather than silently dropped.\n const newNode: PxNode = { ...useNode, type: 'g', children: [materialisedClone] };\n delete (newNode as { href?: string }).href;\n // The viewport-mapping `<g>` we just emitted on the clone root already\n // carries its own width/height-derived scale/translate. Drop the use's\n // own `width`/`height` so they don't appear on the outer `<g>` (where\n // they'd be ignored anyway — `<g>` has no width/height — but emitting\n // them as attributes would be misleading).\n delete (newNode as { width?: unknown }).width;\n delete (newNode as { height?: unknown }).height;\n return applyUseOffsetToG(newNode);\n}\n\n\n/** `<symbol>` doesn't render directly. To keep the visual result when a\n * cloned `<symbol>` lands as the root of a materialised `<use>` target, we\n * rewrite it into a `<g>` whose transform + clip mirror the browser's\n * `<use href=\"#symbol-with-viewBox\">` viewport mapping:\n *\n * - `transform = \"translate(xOff, yOff) scale(s) translate(-vbX, -vbY)\"`\n * where `s` and the centering offsets are derived from the symbol's\n * `viewBox` and the use's effective width/height per `preserveAspectRatio`\n * (default `xMidYMid meet`). Without the scale the clone renders at 1:1\n * in symbol coords, which doesn't match `<use>`'s natural behaviour.\n * - `clipPath = \"url(#<fresh-id>)\"` referencing a `<rect>` matching the\n * viewBox extent (in symbol coords). With the surrounding transform\n * above the clip rect maps to the visible viewport area, matching how\n * `<symbol>` viewport clipping works.\n *\n * Symbols without a `viewBox` rewrite to a plain `<g>` — no viewport\n * mapping to preserve.\n *\n * The created clipPath defs are appended to `defsCollector`; the caller\n * splices them into the root tree once materialisation finishes.\n */\nfunction rewriteSymbolRootToGroup(\n symbolNode: PxNode,\n genId: () => string,\n defsCollector: Array<PxNode>,\n useW: number,\n useH: number,\n): PxNode {\n const viewBox = parseViewBox((symbolNode as { viewBox?: unknown }).viewBox);\n const g: PxNode = { ...symbolNode, type: 'g' };\n // Strip symbol-only attributes that don't belong on `<g>`.\n delete (g as { viewBox?: unknown }).viewBox;\n delete (g as { preserveAspectRatio?: unknown }).preserveAspectRatio;\n delete (g as { width?: unknown }).width;\n delete (g as { height?: unknown }).height;\n\n if (!viewBox) return g; // no viewBox → no transform / clip required\n\n const [vbX, vbY, vbW, vbH] = viewBox;\n // `xMidYMid meet` (SVG default) — uniform scale, fit the longer axis;\n // center the shorter axis. Mirrors what the browser does on `<use>` for\n // a symbol-with-viewBox without an explicit preserveAspectRatio override.\n const scale = vbW > 0 && vbH > 0 ? Math.min(useW / vbW, useH / vbH) : 1;\n const xOff = (useW - vbW * scale) / 2;\n const yOff = (useH - vbH * scale) / 2;\n\n const parts: Array<string> = [];\n if (xOff !== 0 || yOff !== 0) parts.push('translate(' + xOff + ',' + yOff + ')');\n if (scale !== 1) parts.push('scale(' + scale + ')');\n if (vbX !== 0 || vbY !== 0) parts.push('translate(' + (-vbX) + ',' + (-vbY) + ')');\n if (parts.length) (g as { transform?: string }).transform = parts.join('');\n\n const clipId = genId();\n defsCollector.push({\n type: 'clipPath',\n id: clipId,\n children: [{ type: 'rect', x: vbX, y: vbY, width: vbW, height: vbH }],\n } as PxNode);\n (g as { clipPath?: string }).clipPath = 'url(#' + clipId + ')';\n return g;\n}\n\n\nfunction parseViewBox(v: unknown): [number, number, number, number] | undefined {\n if (typeof v !== 'string') return undefined;\n const parts = v.trim().split(/[\\s,]+/).map(Number);\n if (parts.length < 4 || parts.some(n => !Number.isFinite(n))) return undefined;\n return [parts[0], parts[1], parts[2], parts[3]];\n}\n\n\nfunction walkAndMaterialise(\n node: PxNode,\n idMap: Map<string, PxNode>,\n animatedIds: Set<string>,\n genId: () => string,\n defsCollector: Array<PxNode>,\n rootViewport: [number, number],\n): PxNode {\n if (node.type === 'use' && typeof node.href === 'string') {\n const targetId = stripHash(node.href);\n if (targetId && animatedIds.has(targetId)) {\n const target = idMap.get(targetId);\n if (target) return materialiseOneUse(node, target, idMap, animatedIds, genId, defsCollector, rootViewport);\n }\n }\n\n if (!node.children) return node;\n let changed = false;\n const newChildren = node.children.map(ch => {\n const m = walkAndMaterialise(ch, idMap, animatedIds, genId, defsCollector, rootViewport);\n if (m !== ch) changed = true;\n return m;\n });\n return changed ? { ...node, children: newChildren } : node;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\n/**\n * Helpers for reading animatable transform parts and shaping them into the\n * player's `PxTransformParts` records. Shared by the transformation and\n * masked-by effects (the latter builds INVERSE parts).\n */\n\nimport type { PxAnimatable, PxKeyframe, PxLoop, Vec2 } from '../PxAnimatorTypes';\nimport type { ApplyContext } from './types';\n\n\n/**\n * Names of the transform parts emitted into a `PxTransformParts` record. The\n * enum's STRING VALUES double as the wire-format object keys, so callers can\n * write `rec[TransformPart.Translate] = …` and produce `{translate: …}`.\n */\nexport enum TransformPart {\n Translate = 'translate',\n Rotate = 'rotate',\n Scale = 'scale',\n Skew = 'skew',\n Origin = 'origin',\n}\n\n\n/** Result kinds for `readAnimatable` — discriminator on `ReadPart<T>`. */\nexport enum ReadKind {\n Absent = 'absent',\n Static = 'static',\n Animated = 'animated',\n}\n\n\n/** Builds a player `PxTransformParts` record for one part (+ optional origin). */\nexport function partsRecord(part: TransformPart, value: any, origin: Vec2 | undefined) {\n const rec: { translate?: Vec2; rotate?: number; skew?: number; scale?: Vec2; origin?: Vec2 } = {};\n if (part === TransformPart.Translate) rec.translate = value;\n else if (part === TransformPart.Rotate) rec.rotate = value;\n else if (part === TransformPart.Skew) rec.skew = value;\n else rec.scale = value;\n if (origin && part !== TransformPart.Translate) rec.origin = origin;\n return rec;\n}\n\nexport type ReadPart<T> =\n | { kind: ReadKind.Absent }\n | { kind: ReadKind.Static; value: T }\n | { kind: ReadKind.Animated; keyframes: Array<PxKeyframe<T>>; autoOrient?: boolean; loop?: PxLoop | boolean };\n\n/** Normalises an animatable field into a static value or a keyframe list (with\n * `autoOrient` and `loop` propagated — the latter so timeline-level loop config\n * reaches the per-attribute `animate.X.loop` emitted by callers; without it,\n * effect-driven animations would silently ignore `loop.alternate`/cycle while\n * every non-effect property loops fine). */\nexport function readAnimatable<T>(raw: PxAnimatable<T> | undefined): ReadPart<T> {\n if (raw === undefined) return { kind: ReadKind.Absent };\n if (Array.isArray(raw)) return { kind: ReadKind.Static, value: raw as unknown as T };\n if (typeof raw === 'object') {\n const obj = raw as { value?: T; keyframes?: Array<PxKeyframe<T>>; autoOrient?: boolean; loop?: PxLoop | boolean };\n if (obj.keyframes) {\n return { kind: ReadKind.Animated, keyframes: obj.keyframes, autoOrient: obj.autoOrient, loop: obj.loop };\n }\n if (obj.value !== undefined) return { kind: ReadKind.Static, value: obj.value };\n }\n return { kind: ReadKind.Static, value: raw as T };\n}\n\n/** Origin used inside rotate/scale records. Animated origin falls back to frame 0. */\nexport function readStaticOrigin(raw: PxAnimatable<Vec2> | undefined, ctx: ApplyContext): Vec2 | undefined {\n const o = readAnimatable<Vec2>(raw);\n if (o.kind === ReadKind.Absent) return undefined;\n if (o.kind === ReadKind.Static) return o.value;\n ctx.warnings.push('transformation.origin: animated origin approximated by its first keyframe');\n return o.keyframes[0]?.value;\n}\n\n/** Copies a keyframe's time / easing / motion-path tangent handles onto a new parts-record value. */\nexport function keyframeWith(kf: PxKeyframe<any>, value: any): PxKeyframe<any> {\n const out: PxKeyframe<any> = { value };\n if (kf.time !== undefined) out.time = kf.time;\n if (kf.easing !== undefined) out.easing = kf.easing;\n if (kf.tangentOut !== undefined) out.tangentOut = kf.tangentOut;\n if (kf.tangentIn !== undefined) out.tangentIn = kf.tangentIn;\n return out;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\nimport { keyframeWith, partsRecord, ReadKind, readAnimatable, TransformPart } from './transformParts';\nimport type { PxAnimatable, PxNode, PxTransformationEffect, Vec2 } from '../PxAnimatorTypes';\nimport type { ApplyContext } from './types';\n\n\n/**\n * TRANSFORMATION → one `<g>` wrapper per part (translate/rotate/scale/skew),\n * with origin emitted as SEPARATE `+origin` / `-origin` wrappers flanking the\n * rotate/scale pair.\n *\n * Per-wrapper kfs:\n * - each wrapper carries ONE animatable quantity, so animated origin / rotate /\n * scale all play correctly per their own keyframe timelines — nothing is\n * baked into another part's wrapper.\n * - the `+o · ... · -o` sandwich pivots rotate+scale around the (possibly\n * animated) origin; translates compose flat (commute).\n *\n * Wrapper nesting (outer → inner):\n *\n * translate → +origin → rotate → scale → -origin → skew → element\n *\n * Composition: `M = translate(t) · +origin(t) · rotate(t) · scale(t) · -origin(t) · skew`\n * (skew is appended innermost and not composed here).\n */\nexport function applyTransformationEffect(node: PxNode, fx: PxTransformationEffect | undefined, ctx: ApplyContext): PxNode {\n if (!fx) return node;\n\n // The element's own `transform` string is the frame-0 baseline; wrappers\n // carry the full (animated) transform, so the baseline is dropped.\n delete node.transform;\n\n // Innermost first. Order outer→inner: [+o, t, -o, +o, r, skew, s, -o] for\n // auto-orient (translate carries motion-path rotation that must pivot around\n // origin too), else [t, +o, r, skew, s, -o] (translate composes flat).\n // Skew sits BETWEEN rotate and scale, inside the origin sandwich — the canonical\n // slot shared with the unified body transform and Lottie (see skew-support.plan.md).\n let n = node;\n n = wrapOrigin(n, fx.origin, /*invert=*/true); // -origin (r/k/s sandwich)\n n = wrapTransformPart(n, TransformPart.Scale, normalizeScale(fx.scale), ctx);\n n = wrapTransformPart(n, TransformPart.Skew, fx.skew, ctx);\n n = wrapTransformPart(n, TransformPart.Rotate, fx.rotate, ctx);\n n = wrapOrigin(n, fx.origin, /*invert=*/false); // +origin (r/k/s sandwich)\n\n if (translateHasAutoOrient(fx.translate)) {\n // Sandwich translate with its own +o/-o so the motion-path tangent\n // rotation built into the translate wrapper pivots around origin\n // (the `[+o, t_path_ao, -o]` branch).\n n = wrapOrigin(n, fx.origin, /*invert=*/true); // -origin (translate sandwich)\n n = wrapTransformPart(n, TransformPart.Translate, fx.translate, ctx);\n n = wrapOrigin(n, fx.origin, /*invert=*/false); // +origin (translate sandwich)\n } else {\n n = wrapTransformPart(n, TransformPart.Translate, fx.translate, ctx);\n }\n return n;\n}\n\n/** True when the translate animation carries motion-path tangent handles or\n * `autoOrient` — the path-tangent rotation needs origin-sandwich to pivot. */\nfunction translateHasAutoOrient(translate: PxAnimatable<Vec2> | undefined): boolean {\n if (!translate || typeof translate !== 'object') return false;\n const obj = translate as { autoOrient?: boolean; keyframes?: Array<{ tangentOut?: Vec2; tangentIn?: Vec2 }> };\n if (obj.autoOrient) return true;\n return Array.isArray(obj.keyframes) && obj.keyframes.some(kf => kf.tangentOut || kf.tangentIn);\n}\n\n/**\n * The wire `effects.transformation.scale` emits **percent units** (150 = 150%)\n * for the bare-array static form, but emits **1.0-units** (1.5 = 150%) inside\n * `{keyframes: [...]}` (matching the body `transform` baseline). The bare-array\n * form is the one we have to convert.\n */\nfunction normalizeScale(raw: PxAnimatable<Vec2> | undefined): PxAnimatable<Vec2> | undefined {\n if (raw === undefined) return undefined;\n if (Array.isArray(raw)) return [raw[0] / 100, raw[1] / 100] as Vec2;\n return raw;\n}\n\n/** Wraps `inner` in a `<g>` carrying a single transform part, static or animated. */\nfunction wrapTransformPart(\n inner: PxNode, part: TransformPart,\n raw: PxAnimatable<any> | undefined, ctx: ApplyContext\n): PxNode {\n if (raw === undefined) return inner;\n\n const v = readAnimatable<any>(raw);\n if (v.kind === ReadKind.Static) {\n return { type: 'g', transform: { value: partsRecord(part, v.value, undefined) }, children: [inner] };\n }\n if (v.kind === ReadKind.Animated) {\n const animTr: any = { keyframes: v.keyframes.map(kf => keyframeWith(kf, partsRecord(part, kf.value, undefined))) };\n if (v.autoOrient) animTr.autoOrient = true;\n if (v.loop !== undefined) animTr.loop = v.loop;\n return {\n type: 'g',\n animate: { transform: animTr },\n children: [inner],\n };\n }\n return inner;\n}\n\n/**\n * Wraps `inner` in a `<g translate>` that shifts by `+origin` (invert=false) or\n * `-origin` (invert=true). Origin is animatable — keyframes are carried through.\n *\n * Emitted as a `{translate}` PartsRecord (not the `{origin}` field) so a `+o`\n * wrapper is just a plain translate in the walker's eyes: the walker composes\n * the origin-sandwich rotation/scale around origin by stacking the wrappers,\n * NOT by reading `origin` off the rotate/scale wrapper's parts record.\n */\nfunction wrapOrigin(inner: PxNode, raw: PxAnimatable<Vec2> | undefined, invert: boolean): PxNode {\n if (raw === undefined) return inner;\n const v = readAnimatable<Vec2>(raw);\n const sign = (value: Vec2): Vec2 => invert ? [-value[0], -value[1]] : value;\n\n if (v.kind === ReadKind.Absent) return inner;\n if (v.kind === ReadKind.Static) {\n if (v.value[0] === 0 && v.value[1] === 0) return inner; // identity — skip\n return { type: 'g', transform: { value: { translate: sign(v.value) } }, children: [inner] };\n }\n if (v.kind === ReadKind.Animated) {\n const animTr: any = { keyframes: v.keyframes.map(kf => keyframeWith(kf, { translate: sign(kf.value as Vec2) })) };\n if (v.loop !== undefined) animTr.loop = v.loop;\n return {\n type: 'g',\n animate: { transform: animTr },\n children: [inner],\n };\n }\n return inner;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\n/**\n * CONTENT-REF SOURCE SPLIT.\n *\n * When a `<use>` references another element with `ref:{type:'content'}` it wants\n * to render the source EXCLUDING the source's own translate (and along-path\n * positioning for auto-orient). The heavy form achieves this by materialising the\n * source as a wrapper tree\n *\n * <g translate> ← outer, holds translate (+ along-path/origin for autoOrient)\n * <g rotate scale +o-o> ← inner, holds rotate/scale (origin sandwich)\n * <element /> ← bare shape, no transform\n * </g>\n * </g>\n *\n * and points the `<use>` at the INNER `<g>`. The use's reference therefore\n * renders rotate/scale around the use's position — never the source's translate.\n *\n * In the lightweight format the source is emitted as a flat element (translate\n * baked onto the body or into `effects.transformation`). The applier's\n * `splitForContentRef` re-creates the multi-layer structure on the fly:\n * 1. extract translate parts from the source body (`transform` string,\n * `animate.transform.keyframes` PartsRecord) and from\n * `effects.transformation` → outer wrapper\n * 2. keep rotate / scale (with origin sandwich) on the inner wrapper\n * 3. assign the ORIGINAL id to the outer, a fresh id to the inner\n * 4. `applyRefAndTransformationEffect` then rewrites the use's `href`\n * to the inner id (see `ctx.contentRefInnerIds`).\n *\n * Auto-orient / motion-path: when the translate animation carries tangent\n * handles (`tangentOut`/`tangentIn`) or `autoOrient`, the path tangent produces\n * a rotation at the OUTER level — so the origin moves to the outer too, so the\n * tangent rotation pivots around it (the `[+o, t_path_ao, -o]` branch).\n *\n * \"Always-split\" simplicity: even when a layer would be empty (e.g. source has\n * no rotate/scale), the inner wrapper is still emitted as an identity `<g>`.\n * The use needs a stable target regardless of which transform parts the source\n * carries, and an extra empty `<g>` is render-neutral.\n */\n\nimport { applyTransformationEffect } from './transformationEffect';\nimport type { PxAnimatable, PxAnimationDefinition, PxKeyframe, PxNode, PxTransformationEffect, Vec2 } from '../PxAnimatorTypes';\nimport type { ApplyContext } from './types';\n\n\n/** Walks the tree and collects every id referenced by a `<use>` with `ref:{type:'content'}`. */\nexport function identifyContentRefTargets(node: PxNode, ctx: ApplyContext, allocator: (key: string) => string): void {\n if (node.type === 'use' && node.effects?.clone?.type === 'content') {\n const baseId = node.effects.clone.baseId;\n if (typeof baseId === 'string' && baseId && !ctx.contentRefInnerIds.has(baseId)) {\n ctx.contentRefInnerIds.set(baseId, allocator(baseId));\n }\n }\n node.children?.forEach(c => identifyContentRefTargets(c, ctx, allocator));\n}\n\n\n/**\n * Splits `node` into outer-translate + inner-rest + bare element. `node` is\n * mutated in place: its body translate is moved to the outer wrapper, leaving\n * the rotate/scale parts (and the element body) inside the inner wrapper.\n *\n * Outer wrapper gets `originalId` (so `idMap` and whole-element refs still\n * resolve correctly). Inner wrapper gets `innerId` (the use's `ref:content`\n * target). The returned node is the OUTER wrapper.\n */\nexport function splitForContentRef(\n node: PxNode,\n transformation: PxTransformationEffect | undefined,\n originalId: string,\n innerId: string,\n ctx: ApplyContext,\n): PxNode {\n\n // 1. Lift translate parts off the body (`transform` string + `animate.transform`)\n // onto a fresh outer-side bag. After this, `node` no longer carries them.\n // `transformation` is passed in so that when its `translate` part will go to\n // the outer wrapper, the body's baked-in translate baseline is stripped too\n // (otherwise it'd double-up against the outer wrapper's first keyframe).\n const outerBody = liftBodyTranslate(node, transformation);\n\n // Strip the bare element's `id` — the outer wrapper takes ownership of `originalId`,\n // and the inner wrapper carries `innerId`. The element itself doesn't need either;\n // leaving it would create a duplicate of `originalId` in the materialised tree.\n if (typeof node.id === 'string') delete node.id;\n\n // 2. Split `effects.transformation` between outer (translate, plus origin for\n // auto-orient/motion-path) and inner (rotate / scale, with origin sandwich).\n const { outer: outerTr, inner: innerTr } = splitTransformationEffect(transformation);\n\n // 3. Inner: apply inner transformation around the original element, then wrap\n // in an identity `<g>` with `innerId`. The extra wrapper guarantees the use\n // has a stable target regardless of what parts were present.\n let innerNode: PxNode = node;\n innerNode = applyTransformationEffect(innerNode, innerTr, ctx);\n const innerWrapper: PxNode = { type: 'g', id: innerId, children: [innerNode] };\n\n // 4. Outer: build a `<g>` carrying the lifted body translate, with `innerWrapper`\n // as its child. Then apply outer transformation (translate). Move id to the\n // outermost so whole-element refs still resolve to the full source.\n let outerWrapper: PxNode = { type: 'g', id: originalId, children: [innerWrapper] };\n if (outerBody.transform !== undefined) outerWrapper.transform = outerBody.transform;\n if (outerBody.animate !== undefined) outerWrapper.animate = outerBody.animate;\n if (outerTr) {\n delete outerWrapper.id;\n outerWrapper = applyTransformationEffect(outerWrapper, outerTr, ctx);\n outerWrapper.id = originalId;\n }\n return outerWrapper;\n}\n\n\n////////////////////////////////////////////////////////////////\n//// Body lifting (transform string + animate.transform)\n////////////////////////////////////////////////////////////////\n\ninterface OuterBody {\n transform?: string | { value?: any; keyframes?: Array<any> };\n animate?: { transform: any };\n}\n\n/** Removes translate parts from `node.transform` (string) and from `node.animate.transform`,\n * returning what was extracted (to live on the outer wrapper). When either\n * animate.transform is lifted OR `effects.transformation.translate` will be lifted\n * via the outer wrapper, the body `transform` translate becomes a redundant t=0\n * baseline and is stripped from `node` (otherwise it'd compose on top of the\n * outer's first keyframe / static translate). */\nfunction liftBodyTranslate(node: PxNode, transformation: PxTransformationEffect | undefined): OuterBody {\n const out: OuterBody = {};\n\n // 1. animate.transform — extract translate from every keyframe value.\n // `autoOrient` and `tangentOut`/`tangentIn` are motion-path metadata that\n // belong to translate; they go to the OUTER wrapper with translate, never\n // to the inner one (the inner has rotate/scale only).\n let didLiftAnimate = false;\n // In-place animations on a node body are always the record form\n // (`{propName: PxPropertyAnimation}`) at this point in the pipeline —\n // narrow the `PxElementAnimation` union accordingly.\n const animTr = (node.animate as PxAnimationDefinition | undefined)?.transform;\n if (animTr && typeof animTr === 'object' && Array.isArray(animTr.keyframes)) {\n const kfs: Array<PxKeyframe<any>> = animTr.keyframes;\n const hasTranslate = kfs.some(kf => kf.value && (kf.value as any).translate);\n if (hasTranslate) {\n const outerHasOrigin = needsOriginOnOuter(animTr as PxAnimatable<Vec2>);\n const outerKfs = kfs.map(kf => {\n const v = (kf.value || {}) as any;\n const newValue: any = {};\n if (v.translate !== undefined) newValue.translate = v.translate;\n if (outerHasOrigin && v.origin !== undefined) newValue.origin = v.origin;\n const outerKf: any = { value: newValue };\n if (kf.time !== undefined) outerKf.time = kf.time;\n if (kf.easing !== undefined) outerKf.easing = kf.easing;\n if ((kf as any).tangentOut !== undefined) outerKf.tangentOut = (kf as any).tangentOut;\n if ((kf as any).tangentIn !== undefined) outerKf.tangentIn = (kf as any).tangentIn;\n return outerKf;\n });\n const outerAnimTr: any = { keyframes: outerKfs };\n if ((animTr as any).autoOrient) outerAnimTr.autoOrient = true;\n // Forward `loop` so the split outer/inner halves keep the source\n // alternate/cycle semantics; otherwise lifting a transform with\n // `loop.alternate` silently drops the loop on translate side.\n const srcLoop = (animTr as any).loop;\n if (srcLoop !== undefined) outerAnimTr.loop = srcLoop;\n out.animate = { transform: outerAnimTr };\n\n const innerHasPivotedPart = kfs.some(kf => {\n const v = (kf.value || {}) as any;\n return v.rotate !== undefined || v.scale !== undefined;\n });\n const innerKfs = kfs.map(kf => {\n const v = (kf.value || {}) as any;\n const newValue: any = {};\n if (v.rotate !== undefined) newValue.rotate = v.rotate;\n if (v.scale !== undefined) newValue.scale = v.scale;\n // Origin lives on inner kfs whenever rotate/scale need a pivot —\n // a separate origin sandwich at the inner layer (even when origin\n // is also on outer for the auto-orient sandwich).\n if (v.origin !== undefined && (!outerHasOrigin || innerHasPivotedPart)) newValue.origin = v.origin;\n // Inner kf intentionally drops tangentOut/tangentIn (translate-only).\n const innerKf: any = { value: newValue };\n if (kf.time !== undefined) innerKf.time = kf.time;\n if (kf.easing !== undefined) innerKf.easing = kf.easing;\n return innerKf;\n });\n const allInnerEmpty = innerKfs.every(kf => Object.keys(kf.value as object).length === 0);\n if (allInnerEmpty) {\n delete (node.animate as any).transform;\n if (node.animate && Object.keys(node.animate).length === 0) delete node.animate;\n } else {\n // Inner animate keeps non-translate kfs; autoOrient flag is intentionally dropped.\n // `loop` is forwarded so the inner rotate/scale half also alternates/cycles.\n const innerAnimTr: any = { keyframes: innerKfs };\n if (srcLoop !== undefined) innerAnimTr.loop = srcLoop;\n (node.animate as any).transform = innerAnimTr;\n }\n didLiftAnimate = true;\n }\n }\n\n // 2. Body `transform` — only the string form carries baked translates. Object\n // forms ({value}/{keyframes}) come from the writer's transformation-effect\n // path and are handled via `effects.transformation`, not the body.\n const transformationHasTranslate = transformation?.translate !== undefined;\n const stripBodyTranslateOnly = didLiftAnimate || transformationHasTranslate;\n // Autoorient / motion-path lift: when the lifted animate.transform carries\n // tangents or `autoOrient`, the body baseline is the FULL t=0 matrix\n // (translate × path-tangent rotation), not just a translate. The outer\n // wrapper recomputes both at every frame (including t=0) via the lifted\n // keyframes + autoOrient, so the body baseline is redundant and would\n // double-apply on top of it.\n const liftedAnimateIsAutoOriented = didLiftAnimate && needsOriginOnOuter((node.animate as PxAnimationDefinition | undefined)?.transform as any || undefined)\n || didLiftAnimate && needsOriginOnOuter((out.animate as PxAnimationDefinition | undefined)?.transform as any || undefined);\n if (typeof node.transform === 'string') {\n const split = splitTransformString(node.transform);\n if (stripBodyTranslateOnly) {\n // Outer wrapper will carry the translate (via animate.transform or\n // effects.transformation); the body string is just a t=0 baseline.\n // Strip body translates so they don't double-up.\n if (split.translate !== undefined) {\n if (split.rest) node.transform = split.rest;\n else delete node.transform;\n } else if (isPureTranslateBody(node.transform)) {\n // Body is a single `matrix(...)` representing pure translate — same\n // redundancy as a `translate(...)` string. Wipe.\n delete node.transform;\n } else if (liftedAnimateIsAutoOriented && isSingleMatrixBody(node.transform)) {\n // Body is a non-pure `matrix(…)` — the autoOrient-materialised t=0\n // value baked by the writer. The outer wrapper reproduces it via\n // `animate.transform` + `autoOrient`; wipe to avoid double-apply.\n delete node.transform;\n }\n } else if (split.translate) {\n out.transform = split.translate;\n if (split.rest) node.transform = split.rest;\n else delete node.transform;\n }\n }\n\n return out;\n}\n\n/** True when the body string is a single `matrix(...)` op (any 6-arg matrix —\n * pure-translate is a more specific case handled by `isPureTranslateBody`). */\nfunction isSingleMatrixBody(s: string): boolean {\n const re = /(translate|rotate|scale|matrix|skewX|skewY)\\(([^)]*)\\)/g;\n let count = 0;\n let isMatrix = false;\n let m: RegExpExecArray | null;\n while ((m = re.exec(s))) {\n count++;\n if (m[1] === 'matrix') isMatrix = true;\n }\n return count === 1 && isMatrix;\n}\n\n/** True when the body transform is a single op equivalent to pure translate\n * (either `translate(...)` or a `matrix(1,0,0,1,e,f)`). Used to decide whether\n * to wipe the body when `animate.transform.translate` has already been lifted. */\nfunction isPureTranslateBody(s: string): boolean {\n const re = /(translate|rotate|scale|matrix|skewX|skewY)\\(([^)]*)\\)/g;\n const ops: Array<{ name: string; full: string }> = [];\n let m: RegExpExecArray | null;\n while ((m = re.exec(s))) ops.push({ name: m[1], full: m[0] });\n if (ops.length !== 1) return false;\n if (ops[0].name === 'translate') return true;\n if (ops[0].name !== 'matrix') return false;\n const args = /matrix\\(([^)]*)\\)/.exec(ops[0].full);\n if (!args) return false;\n const nums = args[1].split(/[\\s,]+/).filter(Boolean).map(Number);\n return nums.length >= 4 && nums[0] === 1 && nums[1] === 0 && nums[2] === 0 && nums[3] === 1;\n}\n\n/**\n * Body-string lift heuristic. The body `transform=\"\"` is the t=0 baseline that\n * the WRITER bakes in the canonical order `translate · +origin · rotate · scale · -origin`.\n *\n * Lift LEADING `translate(...)` ops ONLY when the string does NOT end with a\n * `translate(...)`. A trailing translate is the `-origin` half of an origin\n * sandwich — leaving any translate inside the sandwich would break the pivot,\n * so we leave the whole body alone in that case (the corresponding\n * `effects.transformation` is the structured source we lift from instead).\n *\n * (`matrix(...)` and `skewX/Y` are not lifted — they don't carry \"user\n * translate\" semantics. If the leading op isn't `translate`, nothing is lifted.)\n */\nfunction splitTransformString(s: string): { translate?: string; rest?: string } {\n const ops: Array<{ name: string; full: string }> = [];\n const re = /(translate|rotate|scale|matrix|skewX|skewY)\\(([^)]*)\\)/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(s))) ops.push({ name: m[1], full: m[0] });\n\n if (!ops.length) return { rest: s || undefined };\n\n // All-translate string — no origin-sandwich without rotate/scale in the\n // middle. Lift everything.\n if (ops.every(o => o.name === 'translate')) {\n return { translate: ops.map(o => o.full).join('') };\n }\n\n const leading = ops[0];\n const trailing = ops[ops.length - 1];\n\n // Origin sandwich: writer's canonical order is `translate · +origin ·\n // rotate · scale · -origin`, with `translate + +origin` typically FUSED\n // into one leading translate. We can recover the user-translate by reading\n // the trailing `-origin` value and subtracting `+origin` from the leading.\n if (trailing.name === 'translate' && leading.name === 'translate') {\n const trailingVec = parseTranslateArgs(trailing.full);\n const leadingVec = parseTranslateArgs(leading.full);\n const ox = -trailingVec[0]; // -origin → +origin\n const oy = -trailingVec[1];\n const userTx = leadingVec[0] - ox;\n const userTy = leadingVec[1] - oy;\n\n // Pure origin sandwich (user-translate cancels to 0) — leave the body alone.\n if (userTx === 0 && userTy === 0) return { rest: s };\n\n // Replace the leading translate with the bare `+origin` (=ox,oy), keep\n // the rest of the sandwich unchanged, and lift `translate(userT)`.\n const middleAndTrailing = 'translate(' + ox + ',' + oy + ')' + ops.slice(1).map(o => o.full).join('');\n return { translate: 'translate(' + userTx + ',' + userTy + ')', rest: middleAndTrailing };\n }\n\n // Trailing translate without a matching leading translate — unusual. Be\n // conservative and don't lift.\n if (trailing.name === 'translate') return { rest: s };\n\n // No trailing translate → no origin sandwich; lift all leading translates.\n const lifted: Array<string> = [];\n let i = 0;\n while (i < ops.length && ops[i].name === 'translate') {\n lifted.push(ops[i].full);\n i++;\n }\n if (!lifted.length) return { rest: s };\n\n const rest = ops.slice(i).map(o => o.full).join('');\n return {\n translate: lifted.join(''),\n rest: rest || undefined,\n };\n}\n\nfunction parseTranslateArgs(translateOp: string): [number, number] {\n const m = /translate\\(([^)]*)\\)/.exec(translateOp);\n if (!m) return [0, 0];\n const nums = m[1].split(/[\\s,]+/).filter(Boolean).map(Number);\n return [nums[0] || 0, nums[1] || 0];\n}\n\n\n////////////////////////////////////////////////////////////////\n//// effects.transformation split\n////////////////////////////////////////////////////////////////\n\nfunction splitTransformationEffect(fx: PxTransformationEffect | undefined): {\n outer?: PxTransformationEffect;\n inner?: PxTransformationEffect;\n} {\n if (!fx) return {};\n const originOnOuter = needsOriginOnOuter(fx.translate);\n const innerHasPivotedPart = fx.rotate !== undefined || fx.scale !== undefined;\n\n const outer: PxTransformationEffect = {};\n const inner: PxTransformationEffect = {};\n\n if (fx.translate !== undefined) outer.translate = fx.translate;\n // Origin lives on outer when translate carries auto-orient (so the\n // path-tangent rotation pivots around origin too).\n if (originOnOuter && fx.origin !== undefined) outer.origin = fx.origin;\n\n if (fx.rotate !== undefined) inner.rotate = fx.rotate;\n if (fx.scale !== undefined) inner.scale = fx.scale;\n if (fx.skew !== undefined) inner.skew = fx.skew;\n // Origin also lives on inner whenever rotate/scale need a pivot — duplicate\n // origin across outer + inner is fine: two separate origin sandwiches\n // ([+o, t, -o] outer + [+o, r, s, -o] inner).\n if (fx.origin !== undefined && (!originOnOuter || innerHasPivotedPart)) inner.origin = fx.origin;\n\n return {\n outer: Object.keys(outer).length ? outer : undefined,\n inner: Object.keys(inner).length ? inner : undefined,\n };\n}\n\n\n////////////////////////////////////////////////////////////////\n//// Auto-orient / motion-path detection\n////////////////////////////////////////////////////////////////\n\n/** True when the translate animation produces rotation at the outer level\n * (tangent handles or `autoOrient`) — meaning origin must sit on the outer\n * with translate so the path-tangent rotation pivots around it. */\nfunction needsOriginOnOuter(translateAnim: PxAnimatable<Vec2> | undefined): boolean {\n if (!translateAnim || typeof translateAnim !== 'object') return false;\n const obj = translateAnim as { autoOrient?: boolean; keyframes?: Array<PxKeyframe<Vec2> & { tangentOut?: Vec2; tangentIn?: Vec2 }> };\n if (obj.autoOrient) return true;\n if (Array.isArray(obj.keyframes)) {\n return obj.keyframes.some(kf => kf.tangentOut || kf.tangentIn);\n }\n return false;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\n/** Generic, effect-agnostic helpers for the player-effects applier. */\n\nimport { deepClonePxNode, regenerateIdsAndRewriteRefs } from '../PxNodeCloneUtil';\nimport type { PxNode, Vec2 } from '../PxAnimatorTypes';\nimport type { ApplyContext } from './types';\n\n/** Mints a deterministic id for a generated node (`<mask>`, retimed `<symbol>`, …). */\nexport function genId(ctx: ApplyContext, prefix: string): string {\n return '_lw_' + prefix + '_' + (ctx.nextId++);\n}\n\nexport function stripHash(href: any): string | undefined {\n return typeof href === 'string' ? href.replace(/^#/, '') : undefined;\n}\n\n/** Reads the leading `translate(x,y)` from an SVG transform string. */\nexport function readTranslateFromTransform(transform: any): Vec2 | undefined {\n if (typeof transform !== 'string') return undefined;\n const m = transform.match(/translate\\(\\s*(-?[\\d.]+)\\s*,\\s*(-?[\\d.]+)\\s*\\)/);\n return m ? [Number(m[1]), Number(m[2])] : undefined;\n}\n\n/** Records every node carrying an `id` into the lookup map. */\nexport function indexById(node: PxNode, map: Map<string, PxNode>): void {\n if (typeof node.id === 'string') map.set(node.id, node);\n node.children?.forEach(child => indexById(child, map));\n}\n\n/** Inserts generated <defs> nodes at the front of the root's children. */\nexport function spliceDefs(root: PxNode, defs: Array<PxNode>): void {\n if (!defs.length) return;\n const existing = root.children || (root.children = []);\n existing.unshift({ type: 'defs', children: defs });\n}\n\n/** Deep-clone a `PxNode` subtree. Thin wrapper around the shared\n * {@link deepClonePxNode}; retained as `clone` for the existing call sites. */\nexport const clone = deepClonePxNode;\n\n/**\n * Regenerates every `id` inside `root` (root included) using `genId(ctx, 'retimed')`\n * and rewrites internal `href=\"#X\"` / `url(#X)` refs. Thin wrapper around the\n * shared {@link regenerateIdsAndRewriteRefs}; encapsulates the retime-specific\n * id-prefix convention so retime call sites stay unchanged.\n */\nexport function regenerateIdsInClone(root: PxNode, ctx: ApplyContext): Map<string, string> {\n return regenerateIdsAndRewriteRefs(root, () => genId(ctx, 'retimed'));\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\nimport type { PxAnimatable, PxFillGradientEffect, PxGradientStop, PxKeyframe, PxLoop, PxNode, PxStrokeGradientEffect } from '../PxAnimatorTypes';\nimport { PxGradientType } from '../PxAnimatorTypes';\nimport type { ApplyContext } from './types';\nimport { genId } from './util';\n\n\n/**\n * `effects.fillGradient` / `effects.strokeGradient` materialiser.\n *\n * Mirrors `maskedByEffect`: mint a `<linearGradient>` or `<radialGradient>`\n * def into `ctx.defs`, push the host element's `fill` / `stroke` to\n * `url(#auto-id)`. Same shape used for both fill and stroke — the only\n * difference is which host attribute is rewritten.\n *\n * The wire shape is a gradient as one animatable stop timeline + static geometry\n * (see `_PxFillGradientEffect`). When materialising:\n * - geometry parts (`p1`, `p2`, `c`, `r`, `fp`) become static body attrs\n * on the gradient def;\n * - the stops array is either static (each `<stop>` is bare) or animated\n * (each `<stop>` gets `animate.stopColor.keyframes` derived from the\n * single source timeline by SLICING each kf's full snapshot at this\n * stop's index).\n *\n * The per-stop slicing produces the standard `<linearGradient>` + `<stop>`\n * def chain, so the materialised tree round-trips through the usual reader.\n */\nexport function applyFillGradientEffect(node: PxNode, fx: PxFillGradientEffect | undefined, ctx: ApplyContext): PxNode {\n return applyGradient(node, fx, ctx, 'fill');\n}\n\nexport function applyStrokeGradientEffect(node: PxNode, fx: PxStrokeGradientEffect | undefined, ctx: ApplyContext): PxNode {\n return applyGradient(node, fx, ctx, 'stroke');\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Internals\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction applyGradient(node: PxNode, fx: PxFillGradientEffect | undefined, ctx: ApplyContext, attr: 'fill' | 'stroke'): PxNode {\n if (!fx) return node;\n\n const id = genId(ctx, 'grad');\n const def = synthesiseGradientDef(fx, id, ctx);\n ctx.defs.push(def);\n node[attr] = 'url(#' + id + ')';\n return node;\n}\n\nfunction synthesiseGradientDef(fx: PxFillGradientEffect, id: string, ctx: ApplyContext): PxNode {\n const out: PxNode = {\n type: fx.type === PxGradientType.radial ? 'radialGradient' : 'linearGradient',\n id,\n };\n\n // Geometry — static base values…\n if (fx.type === PxGradientType.linear) {\n if (fx.p1) { out.x1 = String(fx.p1[0]); out.y1 = String(fx.p1[1]); }\n if (fx.p2) { out.x2 = String(fx.p2[0]); out.y2 = String(fx.p2[1]); }\n } else {\n if (fx.c) { out.cx = String(fx.c[0]); out.cy = String(fx.c[1]); }\n if (fx.r !== undefined) out.r = String(fx.r);\n if (fx.fp) { out.fx = String(fx.fp[0]); out.fy = String(fx.fp[1]); }\n }\n if (fx.gradientUnits) out.gradientUnits = fx.gradientUnits;\n if (fx.spreadMethod) out.spreadMethod = fx.spreadMethod;\n if (fx.gradientTransform) out.gradientTransform = fx.gradientTransform;\n\n // …plus ANIMATED geometry: the wire carries per-channel keyframes under\n // `fx.animate` (`gradientX1`, `gradientFy`, …). Map them onto the def node's own\n // `animate` under the real SVG attr names — the frames engine then drives the def's\n // attrs exactly like it drives the stops' `stopColor` (CSS/WAAPI can't, but this\n // materialiser feeds the JS frame loop).\n type ElementAnim = NonNullable<PxNode['animate']>;\n const animate = (fx as { animate?: ElementAnim }).animate;\n if (animate) {\n const mapped: ElementAnim = {};\n for (const wireKey of Object.keys(animate)) {\n const attr = GRADIENT_ANIM_CHANNEL_TO_ATTR[wireKey];\n if (attr) mapped[attr] = animate[wireKey];\n }\n if (Object.keys(mapped).length) out.animate = mapped;\n }\n\n out.children = buildStopChildren(fx.stops, ctx);\n return out;\n}\n\n/** Wire `fx.animate` channel → the SVG gradient-def attribute it drives. */\nconst GRADIENT_ANIM_CHANNEL_TO_ATTR: Record<string, string> = {\n gradientX1: 'x1', gradientY1: 'y1', gradientX2: 'x2', gradientY2: 'y2',\n gradientCx: 'cx', gradientCy: 'cy', gradientFx: 'fx', gradientFy: 'fy', gradientR: 'r',\n};\n\n/** Emits one `<stop>` per gradient stop. Stops come from EITHER the static\n * array form (`stops: [{offset, color}, …]`) or the animated form\n * (`stops: {keyframes:[{time, value:[stops], easing?}]}`). For the\n * animated form, each emitted `<stop>` gets `animate.stopColor.keyframes`\n * whose values are sliced out of the source timeline at this stop's\n * index — the standard `<stop>` def chain. */\nfunction buildStopChildren(stops: PxAnimatable<Array<PxGradientStop>> | undefined, ctx: ApplyContext): Array<PxNode> {\n if (!stops) return [];\n\n // Static shapes — bare array or `{value: […]}`.\n if (Array.isArray(stops)) return stops.map(staticStopNode);\n if (typeof stops === 'object' && Array.isArray((stops as { value?: any }).value)) {\n return (stops as { value: Array<PxGradientStop> }).value.map(staticStopNode);\n }\n\n // Animated — `{keyframes: [{time, value: [stops], easing?}], loop?, ...}`.\n const animBlock = stops as { keyframes?: Array<PxKeyframe>, loop?: PxLoop | boolean };\n const kfs = animBlock.keyframes;\n if (!Array.isArray(kfs) || !kfs.length) return [];\n // Per-stop animations inherit the timeline-level `loop` (alternate/cycle/etc.).\n // Without forwarding it, animating a gradient with `loop.alternate:true`\n // would slice each stop's colours into separate `animate.stopColor`\n // entries that lose the loop config → no reversal past the last kf,\n // even though every non-gradient animatable property loops fine. See\n // also: the gradient stop \"slice\" docstring above.\n const loopFromSource = animBlock.loop;\n\n // Stop count: take the LARGEST across kfs (constraint says constant\n // count, but defensive — when missing, hold the last value).\n let stopCount = 0;\n for (const kf of kfs) {\n const v = (kf.value ?? kf.v) as Array<PxGradientStop> | undefined;\n if (Array.isArray(v) && v.length > stopCount) stopCount = v.length;\n }\n if (!stopCount) return [];\n\n // Baseline stop info from kf[0] — offsets stay fixed across kfs, only\n // colours animate; offset rarely animates but if it does we sample at\n // each kf.\n const firstKfValue = (kfs[0].value ?? kfs[0].v) as Array<PxGradientStop> | undefined;\n const baselineStops: Array<PxGradientStop> = [];\n for (let i = 0; i < stopCount; i++) {\n const s = firstKfValue?.[i] ?? prevDefinedStop(kfs, 0, i) ?? { offset: i / Math.max(1, stopCount - 1), color: '#000000' };\n baselineStops.push({ offset: s.offset, color: s.color });\n }\n\n return baselineStops.map((bs, i) => animatedStopNode(bs, kfs, i, ctx, loopFromSource));\n}\n\nfunction staticStopNode(s: PxGradientStop): PxNode {\n return {\n type: 'stop',\n offset: formatOffset(s.offset),\n stopColor: s.color,\n };\n}\n\nfunction animatedStopNode(baseline: PxGradientStop, kfs: Array<PxKeyframe>, stopIdx: number, _ctx: ApplyContext, loop: PxLoop | boolean | undefined): PxNode {\n const colorKfs: Array<PxKeyframe> = [];\n const offsetKfs: Array<PxKeyframe> = [];\n // Only emit an `offset` timeline when the offset actually moves across\n // kfs — most gradients animate colour only, and a static offset attr is\n // cheaper than a runtime binding that recomputes the same value.\n let offsetVaries = false;\n for (const kf of kfs) {\n const t = kf.time ?? kf.t ?? 0;\n const arr = (kf.value ?? kf.v) as Array<PxGradientStop> | undefined;\n const sliced = arr?.[stopIdx] ?? prevDefinedStop(kfs, kfs.indexOf(kf), stopIdx);\n if (!sliced) continue;\n const easing = kf.easing ?? kf.e;\n\n const colorOut: PxKeyframe = { time: t, value: sliced.color };\n if (easing !== undefined) colorOut.easing = easing;\n colorKfs.push(colorOut);\n\n // Offset is a unitless 0..1 fraction (SVG `<stop offset>` accepts it\n // bare); the runtime interpolates it as a numeric attr.\n const offsetOut: PxKeyframe = { time: t, value: sliced.offset };\n if (easing !== undefined) offsetOut.easing = easing;\n offsetKfs.push(offsetOut);\n if (sliced.offset !== baseline.offset) offsetVaries = true;\n }\n\n const stop: PxNode = {\n type: 'stop',\n offset: formatOffset(baseline.offset),\n stopColor: baseline.color,\n };\n const animate: { [k: string]: { keyframes: Array<PxKeyframe>, loop?: PxLoop | boolean } } = {};\n if (colorKfs.length) {\n animate.stopColor = { keyframes: colorKfs };\n if (loop !== undefined) animate.stopColor.loop = loop;\n }\n if (offsetVaries && offsetKfs.length) {\n animate.offset = { keyframes: offsetKfs };\n if (loop !== undefined) animate.offset.loop = loop;\n }\n if (Object.keys(animate).length) stop.animate = animate;\n return stop;\n}\n\n/** Walks backwards from `fromIdx` looking for a kf whose stops array has\n * an entry at `stopIdx`. Used when a kf's stops array is shorter than the\n * global stop count (shouldn't happen if writer respects the constraint,\n * but degrades gracefully). */\nfunction prevDefinedStop(kfs: Array<PxKeyframe>, fromIdx: number, stopIdx: number): PxGradientStop | undefined {\n for (let i = fromIdx; i >= 0; i--) {\n const arr = (kfs[i].value ?? kfs[i].v) as Array<PxGradientStop> | undefined;\n if (arr?.[stopIdx]) return arr[stopIdx];\n }\n for (let i = fromIdx + 1; i < kfs.length; i++) {\n const arr = (kfs[i].value ?? kfs[i].v) as Array<PxGradientStop> | undefined;\n if (arr?.[stopIdx]) return arr[stopIdx];\n }\n return undefined;\n}\n\n/** `0.5` → `\"50%\"`; `1` → `\"100%\"`; `0.123` → `\"12.3%\"`. Matches SVG\n * convention for `<stop offset>`. */\nfunction formatOffset(o: number): string {\n const pct = Math.round(o * 1000) / 10;\n return pct + '%';\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\nimport type { PxClipPathEffect, PxNode } from '../PxAnimatorTypes';\nimport type { ApplyContext } from './types';\nimport { genId } from './util';\n\n\n/**\n * CLIP-PATH → a `<clipPath>` in defs holding a single `<path>` built from the effect's\n * `d`, referenced via `clip-path=\"url(#…)\"` on the host element.\n *\n * Materialiser pattern, mirroring `applyMaskedByEffect` (mint a def, set a URL ref on the\n * node) but far simpler — the clip geometry is a self-contained vector path (no ancestor\n * transform compensation, no source lookup).\n *\n * ANIMATED clip: when `fx.animate` is present it becomes the child `<path>`'s `animate.d`\n * block. The def is spliced into the walked tree, so `collectIds` auto-assigns the animated\n * path an id and the frame loop rewrites its `d` per frame. `clip-path` is a live reference\n * (verified: the browser re-clips on every `d` change across SMIL/CSS/JS/WAAPI), so the clip\n * animates without any per-frame re-binding on the host.\n */\nexport function applyClipPathEffect(\n node: PxNode,\n fx: PxClipPathEffect | undefined,\n ctx: ApplyContext,\n): PxNode {\n if (!fx || (!fx.d && !fx.animate)) return node;\n\n const clipId = genId(ctx, 'clip');\n const pathChild: PxNode = { type: 'path', d: fx.d };\n if (fx.animate) pathChild.animate = { d: fx.animate };\n ctx.defs.push({ type: 'clipPath', id: clipId, children: [pathChild] });\n node.clipPath = 'url(#' + clipId + ')';\n return node;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\nimport type { PxAnimatable, PxMaskedByEffect, PxNode, PxTransformationEffect, Vec2 } from '../PxAnimatorTypes';\nimport { keyframeWith, partsRecord, ReadKind, readAnimatable, readStaticOrigin, TransformPart } from './transformParts';\nimport type { ApplyContext, MaskAncestorTransform } from './types';\nimport { genId } from './util';\n\n\n/**\n * MASKED-BY → a `<mask>` in defs holding the source `<use>` wrapped in\n * (forward of mask source's ancestors) · (inverse of masked element's full\n * transform chain) · (inverse of masked element's own `effects.transformation`)\n *\n * The mask source must paint at its ORIGINAL world position, but\n * `maskUnits=\"userSpaceOnUse\"` (default) interprets the mask in the masked\n * element's local coord system. The wrapper sequence above first cancels\n * out the masked element's accumulated ancestor / own transforms, then\n * re-applies the mask source's ancestor transforms so the `<use>` ends up\n * at the same world matrix it would have if rendered in place.\n *\n * Composes the masked element's own transform with the mask source's, so the\n * mask renders at the right world matrix.\n *\n * Implementation note — this first cut only composes TRANSLATE parts (static\n * and animated). Rotate / scale on the ancestor chains aren't supported yet\n * and will warn if present. `effects.transformation` on the masked element\n * keeps working (passed in as `transformation` and inverted separately).\n */\nexport function applyMaskedByEffect(\n node: PxNode,\n fx: PxMaskedByEffect | undefined,\n transformation: PxTransformationEffect | undefined,\n ctx: ApplyContext,\n): PxNode {\n if (!fx) return node;\n if (!fx.href) { ctx.errors.push('maskedBy.href missing — cannot build mask'); return node; }\n\n const maskId = genId(ctx, 'mask');\n\n let content: PxNode = { type: 'use', href: '#' + fx.href };\n // `effects.transformation` (split-timing form) gets full per-part inversion\n // through `wrapInverseTransform`. With no `effects.transformation` the\n // masked element's transform lives on the body — invert the STATIC part\n // (`node.transform` string) via the same per-part machinery, then on top\n // emit an animated inverse wrapper for `node.animate.transform.keyframes`\n // (per-kf parts-record inversion). Either way, the ancestor-chain\n // compensation runs on top with translate-only composition for now.\n if (transformation) {\n content = wrapInverseTransform(content, transformation, ctx);\n } else if (hasAnimateTransform(node)) {\n // `animate.transform` overrides `node.transform` per-frame in the\n // visualModel, so inverting BOTH would double-count. Animated wins.\n content = wrapInverseAnimatedBodyTransform(content, node, ctx);\n } else {\n const bodyStatic = readTransformationFromBody(node);\n if (bodyStatic) content = wrapInverseTransform(content, bodyStatic, ctx);\n }\n // Skip `targetOwn` translate when we already inverted the body (otherwise\n // the translate would be subtracted twice).\n const includeTargetOwn = transformation === undefined && !nodeHasBodyTransform(node);\n content = wrapAncestorChainCompensation(content, node, fx.href, ctx, includeTargetOwn);\n\n const mask: PxNode = { type: 'mask', id: maskId, children: [content] };\n if (fx.maskType) mask.maskType = fx.maskType;\n if (fx.maskUnits) mask.maskUnits = fx.maskUnits;\n if (fx.maskContentUnits) mask.maskContentUnits = fx.maskContentUnits;\n ctx.defs.push(mask);\n\n node.mask = 'url(#' + maskId + ')';\n return node;\n}\n\n/** Wraps `inner` in inverse-transform `<g>`s built from the masked element's\n * own `effects.transformation` payload (translate / rotate / scale). The\n * ancestor-chain wrappers are added separately by\n * `wrapAncestorChainCompensation`. */\nfunction wrapInverseTransform(inner: PxNode, fx: PxTransformationEffect | undefined, ctx: ApplyContext): PxNode {\n if (!fx) return inner;\n const origin = readStaticOrigin(fx.origin, ctx);\n\n let n = inner;\n n = wrapInversePart(n, TransformPart.Translate, fx.translate, undefined, ctx);\n n = wrapInversePart(n, TransformPart.Rotate, fx.rotate, origin, ctx);\n n = wrapInversePart(n, TransformPart.Scale, fx.scale, origin, ctx);\n return n;\n}\n\nfunction wrapInversePart(\n inner: PxNode, part: TransformPart,\n raw: PxAnimatable<any> | undefined, origin: Vec2 | undefined, ctx: ApplyContext\n): PxNode {\n if (raw === undefined) return inner;\n // `fx.scale` in BARE-ARRAY form is PERCENT (150 = 1.5×), matching\n // `applyTransformationEffect`'s forward `normalizeScale`. Convert to\n // 1.0-units before reading, so `invertPartValue([1.5,1.5])` produces\n // the right `[2/3, 2/3]` instead of `[1/150, 1/150]`. Keyframe / {value}\n // forms already use 1.0-units per the wire convention.\n const normalisedRaw: PxAnimatable<any> | undefined = (part === TransformPart.Scale && Array.isArray(raw))\n ? [raw[0] / 100, raw[1] / 100] as unknown as PxAnimatable<any>\n : raw;\n const v = readAnimatable<any>(normalisedRaw);\n if (v.kind === ReadKind.Static) {\n return { type: 'g', transform: { value: partsRecord(part, invertPartValue(part, v.value), origin) }, children: [inner] };\n }\n if (v.kind === ReadKind.Animated) {\n const animTr: any = { keyframes: v.keyframes.map(kf => {\n const out = keyframeWith(kf, partsRecord(part, invertPartValue(part, kf.value), origin));\n return part === TransformPart.Translate ? { ...out, ...negatedSpatialTangents(kf) } : out;\n }) };\n if (v.loop !== undefined) animTr.loop = v.loop;\n return {\n type: 'g',\n animate: { transform: animTr },\n children: [inner],\n };\n }\n return inner;\n}\n\nfunction invertPartValue(part: TransformPart, value: any): any {\n if (part === TransformPart.Translate) return [-value[0], -value[1]];\n if (part === TransformPart.Rotate) return -value;\n return [1 / value[0], 1 / value[1]]; // scale\n}\n\n/**\n * Spatial tangents (`tangentOut`/`tangentIn`, wire aliases `to`/`ti`) are\n * RELATIVE control-point offsets (control = value + tangent), so an inverse\n * translate keyframe must negate them along with the value — copying them\n * verbatim keeps the ORIGINAL curve direction and the derived mask sags\n * mid-segment on a motion-along-path masked element (endpoints stay exact,\n * which is why only mid-frame sampling exposes it).\n */\nfunction negatedSpatialTangents(kf: Record<string, any>): Record<string, any> {\n const out: Record<string, any> = {};\n const to = kf.tangentOut ?? kf.to;\n const ti = kf.tangentIn ?? kf.ti;\n if (Array.isArray(to)) out.tangentOut = [-to[0], -to[1]];\n if (Array.isArray(ti)) out.tangentIn = [-ti[0], -ti[1]];\n return out;\n}\n\n\n/**\n * Wraps `inner` with the per-part INVERSE of the masked element's\n * `node.animate.transform.keyframes` records. Each kf carries a parts record\n * `{translate?, rotate?, scale?, origin?}` with matrix\n * `T(t)·T(o)·R·S·T(-o)`. The matrix inverse is\n * `T(o)·S^-1·R^-1·T(-o)·T(-t)` — which can't be expressed as ONE parts\n * record when both rotate and scale are present (S would have to precede R).\n *\n * Split into separate per-part wrappers, layered from innermost (translate)\n * outwards (rotate, then scale), so the overall composition matches the\n * matrix-level inverse:\n *\n * <g scale^-1> <g rotate^-1> <g translate^-1> {use} </g></g></g>\n *\n * Each wrapper carries an animated parts record over the input kf times.\n * The `origin` for rotate / scale wrappers comes from each kf (the wire emits\n * it alongside whenever rotate or scale is present), so an animated origin\n * sandwich pivots correctly per frame.\n */\nfunction wrapInverseAnimatedBodyTransform(inner: PxNode, node: PxNode, _ctx: ApplyContext): PxNode {\n const animate = node.animate && typeof node.animate === 'object' && !Array.isArray(node.animate)\n ? (node.animate as Record<string, any>) : undefined;\n const animTr = animate?.transform;\n const kfs = animTr && typeof animTr === 'object' && Array.isArray((animTr as Record<string, any>).keyframes)\n ? ((animTr as Record<string, any>).keyframes as Array<Record<string, any>>)\n : undefined;\n if (!kfs || !kfs.length) return inner;\n\n const translateKfs: Array<Record<string, any>> = [];\n const rotateKfs: Array<Record<string, any>> = [];\n const scaleKfs: Array<Record<string, any>> = [];\n\n for (const kf of kfs) {\n const v = (kf.value ?? kf.v) || {};\n const baseKf = keyframeWith(kf as any, undefined); // copies time / easing / tangents\n if (Array.isArray(v.translate)) {\n translateKfs.push({ ...baseKf, ...negatedSpatialTangents(kf), value: { translate: [-v.translate[0], -v.translate[1]] } });\n }\n if (typeof v.rotate === 'number') {\n const rec: Record<string, any> = { rotate: -v.rotate };\n if (Array.isArray(v.origin)) rec.origin = [v.origin[0], v.origin[1]];\n rotateKfs.push({ ...baseKf, value: rec });\n }\n if (Array.isArray(v.scale)) {\n const rec: Record<string, any> = { scale: [1 / v.scale[0], 1 / v.scale[1]] };\n if (Array.isArray(v.origin)) rec.origin = [v.origin[0], v.origin[1]];\n scaleKfs.push({ ...baseKf, value: rec });\n }\n }\n\n // Forward the source animate.transform's loop config (alternate/cycle/etc.)\n // onto each per-part inverse wrapper so a loop on the masked element's body\n // transform survives the inversion split.\n const srcLoop = (animTr as Record<string, any> | undefined)?.loop;\n const withLoop = (kfs: Array<Record<string, any>>): Record<string, any> => {\n const block: Record<string, any> = { keyframes: kfs };\n if (srcLoop !== undefined) block.loop = srcLoop;\n return block;\n };\n\n let n = inner;\n // Innermost = translate (matches `wrapInverseTransform`'s order).\n if (translateKfs.length) n = { type: 'g', animate: { transform: withLoop(translateKfs) }, children: [n] };\n if (rotateKfs.length) n = { type: 'g', animate: { transform: withLoop(rotateKfs) }, children: [n] };\n if (scaleKfs.length) n = { type: 'g', animate: { transform: withLoop(scaleKfs) }, children: [n] };\n return n;\n}\n\n\n/** True when the node carries any body-side transform (the static `transform`\n * string OR an `animate.transform` block). */\nfunction nodeHasBodyTransform(node: PxNode): boolean {\n if (typeof node.transform === 'string') return true;\n if (node.transform && typeof node.transform === 'object') return true;\n return hasAnimateTransform(node);\n}\n\n/** True when the node carries an `animate.transform` block (per-frame\n * override of `node.transform`). */\nfunction hasAnimateTransform(node: PxNode): boolean {\n const animate = node.animate && typeof node.animate === 'object' && !Array.isArray(node.animate)\n ? (node.animate as Record<string, any>) : undefined;\n return !!(animate && animate.transform);\n}\n\n/** Parses the masked element's body transform (`node.transform` string) into a\n * `PxTransformationEffect`-like static parts record so the existing\n * `wrapInverseTransform` machinery can produce its inverse `<g>` wrappers.\n *\n * ANIMATED body transforms (`node.animate.transform.keyframes`) aren't\n * supported yet — they'd require splitting a parts-record keyframe stream\n * into per-part animations to feed into `wrapInversePart`. Falls back with a\n * warning. (In practice the writer emits `effects.transformation` whenever the\n * masked element is animated, so this caller path is reached only for static\n * cases anyway.) */\nfunction readTransformationFromBody(node: PxNode): PxTransformationEffect | undefined {\n if (typeof node.transform === 'string') {\n const parts = parseTransformStringToParts(node.transform);\n if (!parts) return undefined;\n const out: PxTransformationEffect = {};\n if (parts.translate) out.translate = parts.translate;\n if (parts.rotate !== undefined) out.rotate = parts.rotate;\n // Scale parsed from the string is in 1.0-units (e.g. `scale(1.5)`).\n // Pass it through the `{value}` form so `wrapInversePart`'s\n // bare-array → percent normalisation doesn't re-divide by 100.\n if (parts.scale) out.scale = { value: parts.scale };\n if (parts.origin) out.origin = parts.origin;\n return Object.keys(out).length ? out : undefined;\n }\n return undefined;\n}\n\n/** Parses the canonical body-transform string of the form\n * `translate(t)? translate(o)? rotate? scale? translate(-o)?`\n * — back into a `PxTransformParts`-style record. The origin sandwich\n * (`translate(o) … translate(-o)`) is recovered as `origin: o`; the leading\n * translate (if any) becomes `translate: t`. Returns `undefined` when no\n * recognised ops are found. */\nfunction parseTransformStringToParts(s: string): { translate?: Vec2; rotate?: number; scale?: Vec2; origin?: Vec2 } | undefined {\n interface Op { name: string; args: Array<number>; }\n const re = /([a-zA-Z]+)\\s*\\(([^)]*)\\)/g;\n let m: RegExpExecArray | null;\n const ops: Array<Op> = [];\n while ((m = re.exec(s)) !== null) {\n const args = m[2].split(/[\\s,]+/).filter(a => a.length > 0).map(Number);\n ops.push({ name: m[1], args });\n }\n if (!ops.length) return undefined;\n\n // Detect origin sandwich: a trailing `translate(-ox,-oy)` matching an\n // earlier `translate(+ox,+oy)`. Recover origin / inner rotate / scale.\n const last = ops[ops.length - 1];\n if (last.name === 'translate') {\n for (let j = ops.length - 2; j >= 0; j--) {\n const cand = ops[j];\n if (cand.name !== 'translate') continue;\n const ox = cand.args[0] ?? 0;\n const oy = cand.args[1] ?? 0;\n const lx = last.args[0] ?? 0;\n const ly = last.args[1] ?? 0;\n if (lx !== -ox || ly !== -oy) continue;\n // `cand` = +origin, `last` = −origin. Anything BEFORE `cand` may\n // be a body translate; anything BETWEEN them is rotate / scale.\n const out: { translate?: Vec2; rotate?: number; scale?: Vec2; origin?: Vec2 } = {};\n out.origin = [ox, oy];\n for (let k = 0; k < j; k++) {\n if (ops[k].name === 'translate') {\n const tx = ops[k].args[0] ?? 0;\n const ty = ops[k].args[1] ?? 0;\n out.translate = out.translate ? [out.translate[0] + tx, out.translate[1] + ty] : [tx, ty];\n }\n }\n for (let k = j + 1; k < ops.length - 1; k++) {\n const op = ops[k];\n if (op.name === 'rotate') out.rotate = (out.rotate ?? 0) + (op.args[0] ?? 0);\n else if (op.name === 'scale') {\n const sx = op.args[0] ?? 1;\n const sy = op.args.length > 1 ? op.args[1] : sx;\n out.scale = out.scale ? [out.scale[0] * sx, out.scale[1] * sy] : [sx, sy];\n }\n }\n return out;\n }\n }\n\n // No sandwich — flat sequence. `translate`s sum, `rotate`s sum, `scale`s\n // multiply. Order isn't preserved but it works for the cases emitted without\n // origin (translates commute; only one rotate or scale).\n let translate: Vec2 | undefined;\n let rotate: number | undefined;\n let scale: Vec2 | undefined;\n for (const op of ops) {\n if (op.name === 'translate') {\n const dx = op.args[0] ?? 0;\n const dy = op.args[1] ?? 0;\n translate = translate ? [translate[0] + dx, translate[1] + dy] : [dx, dy];\n } else if (op.name === 'rotate') {\n rotate = (rotate ?? 0) + (op.args[0] ?? 0);\n } else if (op.name === 'scale') {\n const sx = op.args[0] ?? 1;\n const sy = op.args.length > 1 ? op.args[1] : sx;\n scale = scale ? [scale[0] * sx, scale[1] * sy] : [sx, sy];\n }\n }\n const out: { translate?: Vec2; rotate?: number; scale?: Vec2 } = {};\n if (translate) out.translate = translate;\n if (rotate !== undefined) out.rotate = rotate;\n if (scale) out.scale = scale;\n return Object.keys(out).length ? out : undefined;\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Ancestor-chain compensation\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Wraps `inner` in a single `<g>` that carries\n * translate = sum(maskSource.ancestors) − sum(maskedElement.ancestors)\n * (separately for the static baseline + every keyframe time observed on any\n * animated ancestor in either chain).\n *\n * Translations commute, so a single wrapper suffices for the translate-only\n * case. When any chain entry has a non-translate part, this function emits a\n * warning and falls back to translate-only — visually wrong but a graceful\n * degradation until the rotate/scale composition is implemented.\n */\nfunction wrapAncestorChainCompensation(inner: PxNode, maskedNode: PxNode, sourceId: string, ctx: ApplyContext, includeTargetOwn: boolean): PxNode {\n const sourceNode = ctx.idMap.get(sourceId);\n\n // M_target = (ancestors) · (target's own). When `effects.transformation`\n // is present, `wrapInverseTransform` already covers target's own; pass\n // `includeTargetOwn=false` to skip the duplicate. With no `effects.\n // transformation`, the baseline `node.transform` string is the element's\n // only transform — include it.\n const targetAncestors = ctx.maskAncestorChains.get(maskedNode) || [];\n const targetOwn = includeTargetOwn ? extractTranslateOnly(maskedNode, ctx) : undefined;\n const targetChain = targetOwn ? [...targetAncestors, targetOwn] : targetAncestors;\n const sourceChain = (sourceNode && ctx.maskAncestorChains.get(sourceNode)) || [];\n\n if (!targetChain.length && !sourceChain.length) return inner;\n\n // Union of all keyframe times across both chains. Static-only chains end\n // up with `times = []`, which short-circuits below to a static wrapper.\n const times = new Set<number>();\n for (const a of targetChain) if (a.translateKeyframes) for (const kf of a.translateKeyframes) times.add(kf.time);\n for (const a of sourceChain) if (a.translateKeyframes) for (const kf of a.translateKeyframes) times.add(kf.time);\n const animated = times.size > 0;\n\n if (!animated) {\n const tgt = sumStaticTranslate(targetChain);\n const src = sumStaticTranslate(sourceChain);\n const dx = src[0] - tgt[0];\n const dy = src[1] - tgt[1];\n if (dx === 0 && dy === 0) return inner;\n return { type: 'g', transform: 'translate(' + dx + ',' + dy + ')', children: [inner] };\n }\n\n const sortedTimes = Array.from(times).sort((a, b) => a - b);\n const keyframes = sortedTimes.map(t => {\n const tgt = sumTranslateAt(targetChain, t);\n const src = sumTranslateAt(sourceChain, t);\n return { time: t, value: { translate: [src[0] - tgt[0], src[1] - tgt[1]] as [number, number] } };\n });\n return { type: 'g', animate: { transform: { keyframes } }, children: [inner] };\n}\n\n/** Sums every translate (baseline) entry in the chain. Ignores animated kfs. */\nfunction sumStaticTranslate(chain: Array<MaskAncestorTransform>): [number, number] {\n let x = 0, y = 0;\n for (const a of chain) {\n if (a.translate) { x += a.translate[0]; y += a.translate[1]; }\n }\n return [x, y];\n}\n\n/** Sums every translate at time `t` in the chain. Animated entries are sampled\n * via linear interpolation between their kfs; static entries contribute their\n * baseline. */\nfunction sumTranslateAt(chain: Array<MaskAncestorTransform>, t: number): [number, number] {\n let x = 0, y = 0;\n for (const a of chain) {\n if (a.translateKeyframes && a.translateKeyframes.length) {\n const v = interpKfs(a.translateKeyframes, t);\n x += v[0]; y += v[1];\n } else if (a.translate) {\n x += a.translate[0]; y += a.translate[1];\n }\n }\n return [x, y];\n}\n\nfunction interpKfs(kfs: Array<{ time: number; value: [number, number] }>, t: number): [number, number] {\n if (t <= kfs[0].time) return kfs[0].value;\n if (t >= kfs[kfs.length - 1].time) return kfs[kfs.length - 1].value;\n for (let i = 1; i < kfs.length; i++) {\n if (t <= kfs[i].time) {\n const prev = kfs[i - 1];\n const cur = kfs[i];\n const a = (t - prev.time) / (cur.time - prev.time);\n return [prev.value[0] + (cur.value[0] - prev.value[0]) * a, prev.value[1] + (cur.value[1] - prev.value[1]) * a];\n }\n }\n return kfs[kfs.length - 1].value;\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Pre-pass: walk tree, record ancestor chains for every (target, source) pair\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Walks `root` top-down and records — for every element involved in an\n * `effects.maskedBy` pair (the masked element AND the mask source it\n * references) — the chain of translate transforms on its `<g>` ancestors.\n * Results land in `ctx.maskAncestorChains`.\n *\n * The walk runs BEFORE pass 1 so it sees the untouched lightweight tree:\n * ancestor `<g transform=\"...\">` strings + `animate.transform` kfs are still\n * intact and easy to parse.\n */\nexport function collectMaskAncestorChains(root: PxNode, ctx: ApplyContext): void {\n // Two-pass: first find the actual NODE references that are masked elements\n // or mask source elements (the source via idMap, the masked element by\n // walking the tree). Then on a second walk, store ancestor chains for\n // those nodes.\n const interestingNodes = new Set<PxNode>();\n const collectInterestingNodes = (n: PxNode): void => {\n const href = n.effects?.maskedBy?.href;\n if (typeof href === 'string') {\n interestingNodes.add(n); // masked element\n const sourceNode = ctx.idMap.get(href);\n if (sourceNode) interestingNodes.add(sourceNode); // mask source\n }\n if (Array.isArray(n.children)) for (const ch of n.children) collectInterestingNodes(ch);\n };\n collectInterestingNodes(root);\n if (interestingNodes.size === 0) return;\n\n const walk = (node: PxNode, chain: Array<MaskAncestorTransform>): void => {\n if (interestingNodes.has(node)) ctx.maskAncestorChains.set(node, chain);\n if (Array.isArray(node.children)) {\n const own = extractTranslateOnly(node, ctx);\n const next = own ? [...chain, own] : chain;\n for (const ch of node.children) walk(ch, next);\n }\n };\n walk(root, []);\n}\n\n/** Extracts only the TRANSLATE part from a node's `transform` + `animate.transform`.\n * Returns `undefined` when the node has no transform OR carries only\n * non-translate parts. Pushes a warning when a non-translate part is dropped. */\nfunction extractTranslateOnly(node: PxNode, ctx: ApplyContext): MaskAncestorTransform | undefined {\n const tr = node.transform;\n const animateBlock = node.animate && typeof node.animate === 'object' && !Array.isArray(node.animate)\n ? (node.animate as Record<string, any>).transform : undefined;\n if (tr === undefined && !animateBlock) return undefined;\n\n const out: MaskAncestorTransform = {};\n\n if (typeof tr === 'string') {\n const parts = parseTranslateOnlyFromString(tr, ctx);\n if (parts) out.translate = parts;\n } else if (tr && typeof tr === 'object') {\n const value = (tr as Record<string, any>).value;\n if (value && typeof value === 'object' && Array.isArray(value.translate)) {\n out.translate = [value.translate[0] || 0, value.translate[1] || 0];\n }\n if (value && (value.rotate !== undefined || value.scale !== undefined || value.skew !== undefined)) {\n ctx.warnings.push('maskedBy ancestor: non-translate transform parts ignored (rotate/scale not yet supported)');\n }\n }\n\n if (animateBlock && Array.isArray((animateBlock as Record<string, any>).keyframes)) {\n const kfs = (animateBlock as Record<string, any>).keyframes as Array<Record<string, any>>;\n const translateKfs: Array<{ time: number; value: [number, number] }> = [];\n for (const kf of kfs) {\n const v = kf.value ?? kf.v;\n const t = (kf.time ?? kf.t ?? 0) as number;\n if (v && typeof v === 'object' && Array.isArray(v.translate)) {\n translateKfs.push({ time: t, value: [v.translate[0] || 0, v.translate[1] || 0] });\n if (v.rotate !== undefined || v.scale !== undefined || v.skew !== undefined) {\n ctx.warnings.push('maskedBy ancestor: animated non-translate parts ignored');\n }\n }\n }\n if (translateKfs.length) out.translateKeyframes = translateKfs;\n }\n\n return (out.translate || out.translateKeyframes) ? out : undefined;\n}\n\n/** Parses ONLY `translate(x[, y])` ops out of an SVG transform string, summing\n * multiple translates and ignoring anything else (with a one-shot warning).\n * The lightweight writer emits the masked / source ancestors' transforms as\n * these simple strings, so this stays a tiny single-purpose parser. */\nfunction parseTranslateOnlyFromString(s: string, ctx: ApplyContext): [number, number] | undefined {\n const re = /([a-zA-Z]+)\\s*\\(([^)]*)\\)/g;\n let m: RegExpExecArray | null;\n let x = 0, y = 0;\n let seen = false;\n let droppedNonTranslate = false;\n while ((m = re.exec(s)) !== null) {\n const name = m[1];\n const args = m[2].split(/[\\s,]+/).filter(a => a.length > 0).map(Number);\n if (name === 'translate') {\n x += args[0] || 0;\n y += args[1] || 0;\n seen = true;\n } else {\n droppedNonTranslate = true;\n }\n }\n if (droppedNonTranslate) ctx.warnings.push('maskedBy ancestor: non-translate transform in string ignored: ' + s);\n return seen ? [x, y] : undefined;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\n/**\n * REF + TRANSFORMATION (combined). The use's `href` is set BEFORE\n * `applyTransformationEffect` wraps the node so it lands on the actual `<use>`\n * rather than on an outer `<g>` wrapper.\n *\n * For `ref:{type:'content'}` the source is materialised as multi-layer by\n * `splitForContentRef` (see `contentRefSplit.ts`), and the use's `href` is\n * rewritten to point at the inner (no-translate) layer's id. No translate\n * cancellation is needed on the use side any more.\n */\n\nimport { applyTransformationEffect } from './transformationEffect';\nimport type { PxCloneEffect, PxNode, PxTransformationEffect } from '../PxAnimatorTypes';\nimport type { ApplyContext } from './types';\n\nconst CONTENT_SUBREF = 'content';\n\n/**\n * Rewrites `node.href` from the clone's reference part (`type`/`baseId`) —\n * content-ref → the inner-layer id minted by `splitForContentRef`, whole-element\n * ref → `baseId`. Pure href mutation (no wrapping), so it can run even when `node`\n * is ALSO a content-ref SOURCE that gets split: a `<use>` that both references\n * content (consumer) and is itself referenced (source) must get its own href\n * rewritten BEFORE the split moves its body inward — otherwise its body keeps the\n * editor-side content id, which doesn't exist in the lightweight tree (dangling\n * href → retime can't follow the chain → the retimed instance renders nothing).\n *\n * A direct-link clone (no `baseId`, e.g. `clone:{retime}`) keeps its existing\n * `href` — there's nothing to redirect; only content-ref REQUIRES a `baseId`.\n */\nexport function applyRefHref(\n node: PxNode,\n clone: PxCloneEffect | undefined,\n ctx: ApplyContext,\n): void {\n if (!clone) return;\n const baseId = clone.baseId;\n if (!baseId) {\n if (clone.type === CONTENT_SUBREF) ctx.errors.push('clone: content ref missing baseId');\n return; // direct link → href already correct, nothing to rewrite\n }\n // For content-ref, redirect href to the inner-layer id produced by\n // `splitForContentRef`. For whole-element ref (or when no split has\n // happened, e.g. target not in the tree), fall back to baseId.\n const targetId = clone.type === CONTENT_SUBREF\n ? (ctx.contentRefInnerIds.get(baseId) || baseId)\n : baseId;\n node.href = '#' + targetId;\n}\n\nexport function applyRefAndTransformationEffect(\n node: PxNode,\n clone: PxCloneEffect | undefined,\n transformation: PxTransformationEffect | undefined,\n ctx: ApplyContext,\n): PxNode {\n applyRefHref(node, clone, ctx);\n return applyTransformationEffect(node, transformation, ctx);\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\nimport { applyTransformationEffect } from './transformationEffect';\nimport type { PxAnimatable, PxAnimationDefinition, PxNode, PxRepeaterEffect, PxTransformationEffect, Vec2 } from '../PxAnimatorTypes';\nimport type { ApplyContext } from './types';\nimport { clone } from './util';\n\n\n/**\n * REPEATER → N clones inside a `<g>` wrapper. Copy 0 is the unmodified base;\n * copies 1..N-1 are wrapped with a per-copy `PxTransformationEffect` synthesised\n * from the repeater parts:\n *\n * - translate × i\n * - rotate × i\n * - scale ^ i (per-axis geometric compound)\n * - origin CONSTANT — rotation/scale center stays put across copies\n *\n * The origin is the rotation/scale CENTER for the sandwich\n * `T(+o) · T(t·i) · R(r·i) · S(s^i) · T(-o)`. Scaling `o` by `i` would shift the\n * center per copy and produce a spiral instead of a repeated rotation.\n *\n * Each part is independently animatable:\n * - Static parts → emitted as structured `transform: {value:…}` on the per-copy wrapper.\n * - Animated parts → emitted as `animate.transform.keyframes` with each kf value\n * scaled by the rule above (time/easing preserved).\n *\n * Uses the same per-copy matrix formula as the heavy SVG render.\n */\nexport function applyRepeaterEffect(node: PxNode, fx: PxRepeaterEffect | undefined, ctx: ApplyContext): PxNode {\n if (!fx) return node;\n\n const copies = fx.copies ?? 1;\n if (copies < 1) { ctx.errors.push('repeater.copies invalid: ' + fx.copies); return node; }\n\n // The base element's SHARED transform (static baseline + any animation) is\n // lifted onto the wrapper so the per-copy increments compose in the wrapper's\n // coordinate space. Non-transform animations (opacity, fill) stay per copy.\n const sharedTransform = node.transform;\n // In-place animations on a node body are always the record form here —\n // narrow the `PxElementAnimation` union accordingly.\n const sharedAnimTransform = (node.animate as PxAnimationDefinition | undefined)?.transform;\n\n const base = clone(node);\n delete base.transform;\n if (base.animate) {\n delete (base.animate as PxAnimationDefinition).transform;\n if (Object.keys(base.animate).length === 0) delete base.animate;\n }\n // The WRAPPER owns the source id (assigned below): a whole-element `<use>` must\n // resolve to the FULL repeated result including the shared transform. Leaving the\n // id on the base would duplicate it across every copy-clone, and href resolution\n // would land on a bare, transform-stripped copy (rendered at the use's position\n // with no body translate — visibly mis-placed).\n delete base.id;\n\n const children: Array<PxNode> = [base];\n for (let i = 1; i < copies; i++) {\n const baseClone = clone(base);\n const synthFx = synthesisePerCopyFx(fx, i);\n // Run through the standard transformation-effect machinery — gets\n // origin sandwich, animated kfs, etc. for free.\n const wrapped = synthFx ? applyTransformationEffect(baseClone, synthFx, ctx) : baseClone;\n children.push(wrapped);\n }\n\n const wrapper: PxNode = { type: 'g', children };\n if (node.id) wrapper.id = node.id;\n if (sharedTransform !== undefined) wrapper.transform = sharedTransform;\n if (sharedAnimTransform !== undefined) wrapper.animate = { transform: sharedAnimTransform };\n return wrapper;\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// PER-COPY SYNTHESIS\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Builds a per-copy `PxTransformationEffect` for copy index `i`. */\nfunction synthesisePerCopyFx(fx: PxRepeaterEffect, i: number): PxTransformationEffect | undefined {\n const out: PxTransformationEffect = {};\n\n if (fx.translate !== undefined) {\n out.translate = mapAnimatableVec2(fx.translate, v => [v[0] * i, v[1] * i]);\n }\n if (fx.rotate !== undefined) {\n out.rotate = mapAnimatableNumber(fx.rotate, v => v * i);\n }\n if (fx.scale !== undefined) {\n out.scale = synthesiseScale(fx.scale, i);\n }\n if (fx.origin !== undefined) {\n // CONSTANT — rotation/scale center stays put across copies. Scaling by `i`\n // would drift the center per copy (spiral instead of repeated rotation).\n out.origin = fx.origin;\n }\n\n return Object.keys(out).length ? out : undefined;\n}\n\n/** Applies `fn` to every value in an animatable Vec2 (static / `{value}` / `{keyframes}`). */\nfunction mapAnimatableVec2(raw: PxAnimatable<Vec2>, fn: (v: Vec2) => Vec2): PxAnimatable<Vec2> {\n if (Array.isArray(raw)) return fn(raw as Vec2);\n if (raw && typeof raw === 'object') {\n const obj = raw as { value?: Vec2; keyframes?: Array<any>; autoOrient?: boolean };\n if (Array.isArray(obj.keyframes)) {\n return {\n ...obj,\n keyframes: obj.keyframes.map(kf => kf && kf.value !== undefined ? { ...kf, value: fn(kf.value) } : kf),\n } as PxAnimatable<Vec2>;\n }\n if (obj.value !== undefined) {\n return { ...obj, value: fn(obj.value) } as PxAnimatable<Vec2>;\n }\n }\n return raw;\n}\n\n/** Applies `fn` to every value in an animatable number (static / `{value}` / `{keyframes}`). */\nfunction mapAnimatableNumber(raw: PxAnimatable<number>, fn: (v: number) => number): PxAnimatable<number> {\n if (typeof raw === 'number') return fn(raw);\n if (raw && typeof raw === 'object') {\n const obj = raw as { value?: number; keyframes?: Array<any>; autoOrient?: boolean };\n if (Array.isArray(obj.keyframes)) {\n return {\n ...obj,\n keyframes: obj.keyframes.map(kf => kf && kf.value !== undefined ? { ...kf, value: fn(kf.value) } : kf),\n } as PxAnimatable<number>;\n }\n if (obj.value !== undefined) {\n return { ...obj, value: fn(obj.value) } as PxAnimatable<number>;\n }\n }\n return raw;\n}\n\n/**\n * Per-copy scale: per-axis geometric compounding `s^i`. Always emitted in\n * **1.0-units** so it bypasses `applyTransformationEffect.normalizeScale`\n * (which only divides BARE-array static scale by 100 — `{value:…}` and\n * `{keyframes:…}` are expected to be already-1.0-units).\n *\n * Wire convention for repeater.scale is irregular:\n * - **Bare-array static** is PERCENT (e.g. `[85, 85]` = 0.85×); needs `/100`\n * before compounding.\n * - **`{keyframes:…}` animated** values are already 1.0-units (the writer\n * converts) — no `/100`.\n * - `{value:…}` static (rare; uses same convention as bare-array → PERCENT).\n */\nfunction synthesiseScale(raw: PxAnimatable<Vec2>, i: number): PxAnimatable<Vec2> {\n const scalePowerFromPercent = (v: Vec2): Vec2 => [Math.pow(v[0] / 100, i), Math.pow(v[1] / 100, i)];\n const scalePowerFromUnits = (v: Vec2): Vec2 => [Math.pow(v[0], i), Math.pow(v[1], i)];\n\n if (Array.isArray(raw)) {\n // Bare-array static (PERCENT) → emit as `{value:[…]}` in 1.0-units to\n // bypass normalizeScale.\n return { value: scalePowerFromPercent(raw as Vec2) };\n }\n if (raw && typeof raw === 'object') {\n const obj = raw as { value?: Vec2; keyframes?: Array<any>; autoOrient?: boolean };\n if (Array.isArray(obj.keyframes)) {\n // Animated values are already 1.0-units on the wire.\n return {\n ...obj,\n keyframes: obj.keyframes.map(kf => kf && kf.value !== undefined ? { ...kf, value: scalePowerFromUnits(kf.value) } : kf),\n } as PxAnimatable<Vec2>;\n }\n if (obj.value !== undefined) {\n // `{value:…}` static — treated as PERCENT like the bare-array case.\n return { ...obj, value: scalePowerFromPercent(obj.value) } as PxAnimatable<Vec2>;\n }\n }\n return raw;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\n/**\n * RETIME (`<use>` timeline remap) — runs AFTER every other pass-1 effect has\n * materialised, so the `<use>`'s `href` already points at the right post-pass-1\n * target (e.g. the inner-content layer that `contentRefSplit` produced).\n *\n * Retime lives nested under the merged `clone` effect (`effects.clone.retime`).\n * For every `<use>` carrying it we:\n * 1. follow `useNode.href` (no `baseId` lookup — the editor-side id wouldn't\n * resolve in the lightweight tree);\n * 2. recursively materialise the chain target-side, preserving each\n * intermediate `<use>`'s offset/transform and accumulating retime at every\n * nested-retime hop (`concatRetime(child, parent)`);\n * 3. wire the chain root into the `<use>` site — see RETIME_MATERIALISATION_MODE.\n *\n * Each chain link becomes its own defs entry with the right accumulated retime\n * applied to ITS OWN kfs, and the link's `href` rewritten to point at the\n * next-level materialisation.\n *\n * NB: `clone.baseId` is intentionally IGNORED by retime — it carries an\n * upstream core id that does not exist in the lightweight tree; retime\n * follows `href`.\n */\n\nimport type { PxNode, PxRetimeEffect } from '../PxAnimatorTypes';\nimport type { ApplyContext } from './types';\nimport { applyUseOffsetToG } from '../PxNodeCloneUtil';\nimport { clone, genId, indexById, regenerateIdsInClone, stripHash } from './util';\n\n\n/** Mode A (true): replace `<use>` with `<g>` whose child IS the chain-root clone.\n * Mode B (false): push the chain-root clone into `<defs>`, rewrite `<use>.href`.\n *\n * Mode B is the default — it preserves the `<use>`'s native semantics (x/y\n * positioning, width/height — none of which `<g>` interprets). Mode A would\n * need to bake those into the new `<g>`'s transform to stay equivalent. */\nconst RETIME_MATERIALISATION_MODE_INLINE_G = false;\n\n\ninterface Retime { start: number; stretch: number; }\n\nfunction asRetime(r: PxRetimeEffect): Retime {\n // `timeCrop` is declared on the wire schema but not implemented yet —\n // warn instead of silently dropping it so producers notice.\n if (r.timeCrop) {\n console.warn('retime: `timeCrop` is not supported yet and will be ignored');\n }\n return { start: r.start ?? 0, stretch: r.stretch ?? 1 };\n}\n\n/** parent applied OUTSIDE, child INSIDE → `t = parent.start + parent.stretch * (child.start + child.stretch * t_local)`. */\nfunction concatRetime(child: Retime, parent: Retime): Retime {\n return {\n start: parent.start + parent.stretch * child.start,\n stretch: parent.stretch * child.stretch,\n };\n}\n\n/** Retime lives nested under the `clone` effect (`effects.clone.retime`). */\nfunction readCloneRetime(n: PxNode): PxRetimeEffect | undefined {\n return n.effects?.clone?.retime;\n}\n\n/** Removes the retime slice and prunes now-empty `clone` / `effects` buckets. */\nfunction clearCloneRetime(n: PxNode): void {\n const clone = n.effects?.clone;\n if (!clone) return;\n delete clone.retime;\n if (Object.keys(clone).length === 0) delete n.effects!.clone;\n if (n.effects && Object.keys(n.effects).length === 0) delete n.effects;\n}\n\n\n/** Pass-2 driver. Re-indexes ids (pass-1 mints new ones like `_lw_inner_0`),\n * then materialises retime at every site. Order-independent: each site\n * recursively expands its own chain via the original retime layout. */\nexport function applyAllRetimeEffects(root: PxNode, ctx: ApplyContext): void {\n ctx.idMap.clear();\n indexById(root, ctx.idMap);\n\n const sites: Array<PxNode> = [];\n const collect = (n: PxNode): void => {\n if (readCloneRetime(n)) sites.push(n);\n n.children?.forEach(collect);\n };\n collect(root);\n\n // OUTER-most sites first. Materialising a site CONSUMES its retime in place (see the\n // load-bearing note below) — so when an outer use's chain later clones a subtree whose\n // inner retimed use was already processed, the inner retime is gone and never composes\n // with the outer one: a doubly-retimed chain started at +inner instead of\n // +inner∘outer. Document order only happens to work when the outer use serialises\n // first; a symbol-heavy document (e.g. one imported from Lottie precomps) puts the\n // template's inner use ahead of the outer site. Order by reachability instead: a site\n // whose chain can reach other sites materialises before them.\n const reachCount = new Map<PxNode, number>();\n for (const site of sites) {\n let count = 0;\n const visited = new Set<string>();\n const walk = (n: PxNode | undefined): void => {\n if (!n) return;\n if (n !== site && readCloneRetime(n)) count++;\n if (n.type === 'use' && n.href) {\n const id = stripHash(n.href);\n if (id && !visited.has(id)) { visited.add(id); walk(ctx.idMap.get(id)); }\n }\n n.children?.forEach(walk);\n };\n const rootId = stripHash(site.href);\n if (rootId) { visited.add(rootId); walk(ctx.idMap.get(rootId)); }\n reachCount.set(site, count);\n }\n // Stable sort: deeper reach first; equal reach keeps document order.\n sites.sort((a, b) => (reachCount.get(b) ?? 0) - (reachCount.get(a) ?? 0));\n\n for (const useNode of sites) {\n const retime = readCloneRetime(useNode);\n if (!retime) continue;\n // Per-site delete is LOAD-BEARING, not just cleanup: once this use is\n // materialised its `href` is rewritten to an already-time-shifted clone, so\n // a downstream use that references THIS one must NOT re-compose this retime\n // (buildChainClone reads `target`'s clone.retime). Deleting it here makes\n // that read return undefined → no double-count. Moving cleanup to a single\n // end-of-pipeline strip regresses nested retime to +750 instead of +500.\n clearCloneRetime(useNode);\n materialiseRetime(useNode, asRetime(retime), ctx);\n }\n}\n\n\n/** Materialises `retime` on `useNode` by cloning the chain rooted at\n * `useNode.href` and wiring the clone into the `<use>` site. */\nfunction materialiseRetime(useNode: PxNode, retime: Retime, ctx: ApplyContext): void {\n const targetId = stripHash(useNode.href);\n if (!targetId) { ctx.errors.push('retime: <use> has no href to follow'); return; }\n\n const chainRootId = buildChainClone(targetId, retime, ctx, new Set());\n if (!chainRootId) return;\n\n if (RETIME_MATERIALISATION_MODE_INLINE_G) {\n const cloneNode = ctx.idMap.get(chainRootId)!;\n useNode.type = 'g';\n delete useNode.href;\n useNode.children = [cloneNode];\n // `<g>` ignores `x`/`y`; preserve the use's position offset as a\n // `translate(x,y)` applied AFTER any transform (nested inner `<g>`).\n applyUseOffsetToG(useNode);\n ctx.defs = ctx.defs.filter(d => d !== cloneNode); // un-defs it since it's inline now\n } else {\n useNode.href = '#' + chainRootId;\n }\n}\n\n\n/** Clones `targetId`'s node, remaps its OWN kfs by `accum`, then — if the target\n * is a `<use>` — recursively materialises ITS target (folding any nested retime\n * into accum via `concatRetime`). Returns the clone's new id, or undefined on\n * dangling refs / loops. The clone is pushed to `ctx.defs` and indexed in\n * `ctx.idMap` so siblings can resolve it. */\nfunction buildChainClone(targetId: string, accum: Retime, ctx: ApplyContext, chain: Set<string>): string | undefined {\n if (chain.has(targetId)) { ctx.errors.push('retime: loop via \"' + targetId + '\"'); return undefined; }\n const target = ctx.idMap.get(targetId);\n if (!target) { ctx.warnings.push('retime: target \"' + targetId + '\" not found'); return undefined; }\n\n const cloneNode = clone(target);\n regenerateIdsInClone(cloneNode, ctx);\n\n // Clone's OWN body kfs (intermediate-use's animated transform, ball's animation, …).\n // For a use, this is usually a no-op (no kfs on the use itself); for a leaf it\n // remaps the entire reachable subtree.\n if (target.type === 'use') {\n remapKeyframeTimesOnly(cloneNode, accum.start, accum.stretch);\n } else {\n remapKeyframeTimes(cloneNode, accum.start, accum.stretch);\n }\n\n // Strip any retime carried into the clone (already consumed via the chain).\n clearCloneRetime(cloneNode);\n\n // If the target is a `<use>`, recurse on ITS href. Nested retime on the\n // intermediate use folds in via concat.\n if (target.type === 'use' && target.href) {\n const subId = stripHash(target.href);\n if (subId) {\n const innerRetime = readCloneRetime(target);\n const subAccum = innerRetime ? concatRetime(asRetime(innerRetime), accum) : accum;\n const subChain = new Set(chain); subChain.add(targetId);\n const subId2 = buildChainClone(subId, subAccum, ctx, subChain);\n if (subId2) cloneNode.href = '#' + subId2;\n }\n } else {\n // Container target (e.g. a content-ref split wrapper) may HOLD nested\n // `<use>` children that themselves carry retime — the nested content-ref\n // case `use → <g> → use(retime) → …`. Those uses aren't in the pass-2\n // site list (they only exist inside this fresh clone), so materialise\n // them here, composing their retime with `accum` (recurse into children).\n // Without this the inner use's retime stays dangling and the subtree\n // renders un-shifted.\n materialiseNestedRetimeUses(cloneNode, accum, ctx, chain, targetId);\n }\n\n ctx.defs.push(cloneNode);\n if (typeof cloneNode.id === 'string') ctx.idMap.set(cloneNode.id, cloneNode);\n return typeof cloneNode.id === 'string' ? cloneNode.id : undefined;\n}\n\n\n/** Walks a freshly-cloned container subtree and materialises every nested\n * `<use>` that carries retime: composes its retime with `accum` and rewires its\n * href to a fresh chain clone (then drops the now-consumed retime). The\n * container analogue of `buildChainClone`'s use-target recursion — needed for\n * nested content-ref retime where the inner `<use retime>` lives INSIDE the\n * cloned wrapper rather than at its href root. */\nfunction materialiseNestedRetimeUses(node: PxNode, accum: Retime, ctx: ApplyContext, chain: Set<string>, parentTargetId: string): void {\n const visit = (n: PxNode): void => {\n const retime = readCloneRetime(n);\n if (n.type === 'use' && retime && n.href) {\n const subId = stripHash(n.href);\n if (subId) {\n const subAccum = concatRetime(asRetime(retime), accum);\n const subChain = new Set(chain); subChain.add(parentTargetId);\n const subId2 = buildChainClone(subId, subAccum, ctx, subChain);\n if (subId2) n.href = '#' + subId2;\n }\n clearCloneRetime(n);\n }\n n.children?.forEach(visit);\n };\n visit(node);\n}\n\n\n/** Remaps every keyframe `time` in `node` and its subtree: `t' = start + t·stretch`. */\nfunction remapKeyframeTimes(node: PxNode, start: number, stretch: number): void {\n remapKeyframeTimesOnly(node, start, stretch);\n node.children?.forEach(c => remapKeyframeTimes(c, start, stretch));\n}\n\nfunction remapKeyframeTimesOnly(node: PxNode, start: number, stretch: number): void {\n const remap = (kfs: Array<any>): void => {\n for (const kf of kfs) if (typeof kf.time === 'number') kf.time = start + kf.time * stretch;\n };\n if (node.transform && typeof node.transform === 'object' && Array.isArray((node.transform as any).keyframes)) {\n remap((node.transform as any).keyframes);\n }\n if (node.animate && typeof node.animate === 'object') {\n for (const prop of Object.keys(node.animate)) {\n const anim = (node.animate as any)[prop];\n if (anim && Array.isArray(anim.keyframes)) remap(anim.keyframes);\n }\n }\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\n/**\n * Arc-length sampler for an SVG path `d` — the geometry backing along-path glyph\n * placement. Parses the path into cubic Bézier segments (lines and quadratics\n * up-converted), builds a per-segment arc-length LUT, and answers\n * `sampleAtDistance(dist) → { x, y, angle }` (angle = path tangent, radians).\n *\n * Supported commands: M/L/H/V/C/S/Q/T/Z (absolute + relative). Arcs (A/a) are\n * approximated as a straight line to the endpoint (editor paths never emit them;\n * this only guards odd imports). Multiple subpaths are concatenated by arc\n * length (gaps between them are ignored — text flows continuously).\n */\n\nimport { bezier2D_arcLengthLUT, bezier2D_derivativeAt, bezier2D_pointAt, bezier2D_tForDistance, type ArcLengthLUT } from '../PxAnimatorUtil';\n\ntype Pt = [number, number];\n\ninterface Cubic { P0: Pt; P1: Pt; P2: Pt; P3: Pt; lut: ArcLengthLUT; len: number; }\n\nexport interface PathPoint { x: number; y: number; angle: number; }\n\nexport interface PathSampler {\n totalLength: number;\n /** True when the path loops back on itself (explicit `Z` or coincident ends) —\n * no open tip to run off, so overflow clamps/wraps rather than clipping. */\n closed: boolean;\n sampleAtDistance(dist: number): PathPoint;\n}\n\nconst LUT_STEPS = 48;\nconst CMD_RE = /[MmLlHhVvCcSsQqTtAaZz]/;\n\n/** Tokenises `d` into command letters and numbers, preserving order. */\nfunction tokenize(d: string): Array<string> {\n const tokens: Array<string> = [];\n const re = /([MmLlHhVvCcSsQqTtAaZz])|(-?\\d*\\.?\\d+(?:[eE][-+]?\\d+)?)/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(d)) !== null) tokens.push(m[0]);\n return tokens;\n}\n\nfunction quadToCubic(P0: Pt, Qc: Pt, P3: Pt): { P1: Pt; P2: Pt } {\n return {\n P1: [P0[0] + 2 / 3 * (Qc[0] - P0[0]), P0[1] + 2 / 3 * (Qc[1] - P0[1])],\n P2: [P3[0] + 2 / 3 * (Qc[0] - P3[0]), P3[1] + 2 / 3 * (Qc[1] - P3[1])],\n };\n}\n\n/** Parses `d` into cubic segments. Returns null when nothing usable was found. */\nfunction parseCubics(d: string): Array<Cubic> | null {\n const tokens = tokenize(d);\n const segs: Array<Cubic> = [];\n\n let i = 0;\n let cx = 0, cy = 0; // current point\n let sx = 0, sy = 0; // subpath start\n let pcx = 0, pcy = 0; // previous cubic control point (for S)\n let pqx = 0, pqy = 0; // previous quad control point (for T)\n let prevCmd = '';\n\n const num = (): number => parseFloat(tokens[i++]);\n const push = (P1: Pt, P2: Pt, P3: Pt): void => {\n const P0: Pt = [cx, cy];\n const lut = bezier2D_arcLengthLUT(P0, P1, P2, P3, LUT_STEPS);\n segs.push({ P0, P1, P2, P3, lut, len: lut.ds[lut.ds.length - 1] });\n cx = P3[0]; cy = P3[1];\n };\n // Straight line as a cubic with controls at 1/3 and 2/3 — this makes\n // `B(t) = P0 + t·(P3−P0)` EXACTLY, so arc length is linear in t and sampling\n // is precise (degenerate `P1=P0,P2=P3` controls would reparametrise it).\n const pushLine = (x: number, y: number): void => {\n push(\n [cx + (x - cx) / 3, cy + (y - cy) / 3],\n [cx + 2 * (x - cx) / 3, cy + 2 * (y - cy) / 3],\n [x, y],\n );\n };\n\n while (i < tokens.length) {\n let cmd = tokens[i];\n if (CMD_RE.test(cmd)) i++;\n else cmd = prevCmd === 'M' ? 'L' : prevCmd === 'm' ? 'l' : prevCmd; // implicit repeat\n const rel = cmd >= 'a';\n const U = cmd.toUpperCase();\n\n if (U === 'Z') { pushLine(sx, sy); cx = sx; cy = sy; prevCmd = cmd; continue; }\n if (U === 'M') {\n const x = num() + (rel ? cx : 0), y = num() + (rel ? cy : 0);\n cx = x; cy = y; sx = x; sy = y; prevCmd = cmd; continue;\n }\n if (U === 'L') {\n pushLine(num() + (rel ? cx : 0), num() + (rel ? cy : 0));\n } else if (U === 'H') {\n pushLine(num() + (rel ? cx : 0), cy);\n } else if (U === 'V') {\n pushLine(cx, num() + (rel ? cy : 0));\n } else if (U === 'C') {\n const p1: Pt = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];\n const p2: Pt = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];\n const p3: Pt = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];\n pcx = p2[0]; pcy = p2[1];\n push(p1, p2, p3);\n } else if (U === 'S') {\n const smooth = (prevCmd.toUpperCase() === 'C' || prevCmd.toUpperCase() === 'S');\n const p1: Pt = smooth ? [2 * cx - pcx, 2 * cy - pcy] : [cx, cy];\n const p2: Pt = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];\n const p3: Pt = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];\n pcx = p2[0]; pcy = p2[1];\n push(p1, p2, p3);\n } else if (U === 'Q') {\n const qc: Pt = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];\n const p3: Pt = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];\n pqx = qc[0]; pqy = qc[1];\n const { P1, P2 } = quadToCubic([cx, cy], qc, p3);\n push(P1, P2, p3);\n } else if (U === 'T') {\n const smooth = (prevCmd.toUpperCase() === 'Q' || prevCmd.toUpperCase() === 'T');\n const qc: Pt = smooth ? [2 * cx - pqx, 2 * cy - pqy] : [cx, cy];\n const p3: Pt = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];\n pqx = qc[0]; pqy = qc[1];\n const { P1, P2 } = quadToCubic([cx, cy], qc, p3);\n push(P1, P2, p3);\n } else if (U === 'A') {\n // Arc — skip rx ry rot large sweep, use endpoint as a straight line.\n i += 5;\n pushLine(num() + (rel ? cx : 0), num() + (rel ? cy : 0));\n } else { i++; continue; } // unknown — skip a token defensively\n\n prevCmd = cmd;\n }\n\n return segs.length ? segs : null;\n}\n\nfunction clamp(v: number, lo: number, hi: number): number {\n return v < lo ? lo : v > hi ? hi : v;\n}\n\nexport function createPathSampler(d: string): PathSampler | null {\n const segs = parseCubics(d);\n if (!segs) return null;\n\n // Cumulative start distance per segment; cum[segs.length] === total length.\n const cum = new Float64Array(segs.length + 1);\n for (let k = 0; k < segs.length; k++) cum[k + 1] = cum[k] + segs[k].len;\n const totalLength = cum[segs.length];\n\n // A path is CLOSED when it returns to its start (an explicit `Z`, or coincident\n // first/last points). Open paths get straight-line extrapolation past either end\n // (below); closed paths loop back on themselves, so there's no tip to run off.\n const start = segs[0].P0, end = segs[segs.length - 1].P3;\n const closed = Math.hypot(end[0] - start[0], end[1] - start[1]) < 1e-3;\n\n // Sample strictly within [0, totalLength].\n const sampleOn = (dist: number): PathPoint => {\n let k = 0;\n while (k < segs.length - 1 && dist > cum[k + 1]) k++;\n const seg = segs[k];\n const local = dist - cum[k];\n const t = seg.len > 0 ? bezier2D_tForDistance(seg.lut, local) : 0;\n const [x, y] = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);\n const [dx, dy] = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);\n return { x, y, angle: Math.atan2(dy, dx) };\n };\n\n return {\n totalLength,\n closed,\n sampleAtDistance(dist: number): PathPoint {\n // A CLOSED path loops: a distance outside [0, totalLength] wraps around\n // (modulo the length) rather than piling up at the seam. Without this a\n // negative startOffset collapses every pre-start glyph onto the path start\n // (e.g. text on a circle with startOffset < 0 stacking its first word).\n if (closed && totalLength > 0 && (dist < 0 || dist > totalLength)) {\n return sampleOn(((dist % totalLength) + totalLength) % totalLength);\n }\n // Past an end of an OPEN path: continue in a straight line along that\n // end's tangent, so along-path motion keeps going instead of piling up\n // at the tip. (The caller only asks for distances a glyph actually\n // reaches — startOffset + text length — so this never runs off forever.)\n if (!closed && (dist < 0 || dist > totalLength)) {\n const edge = dist < 0 ? 0 : totalLength;\n const p = sampleOn(edge);\n const over = dist - edge;\n return { x: p.x + Math.cos(p.angle) * over, y: p.y + Math.sin(p.angle) * over, angle: p.angle };\n }\n return sampleOn(clamp(dist, 0, totalLength));\n },\n };\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\nimport type { PxAnimatable, PxNode, PxTextPathEffect } from '../PxAnimatorTypes';\nimport type { ApplyContext } from './types';\nimport { createPathSampler } from './pathSampler';\nimport { genId } from './util';\n\n\nconst EXTEND_MARGIN_FRAC = 0.15; // slack (× path length) to absorb sampling/measure error\n\n\n/** {min,max} over a `PxAnimatable<number>`'s keyframe values (or its single static\n * value; {0,0} when absent). The tangent extension must cover the FULL animation\n * range: the MOST-NEGATIVE startOffset drives the START extension, and the LARGEST\n * startOffset(+textLength) drives the END — using only one value (e.g. the max)\n * misses the other end when startOffset is animated. */\nfunction numRange(v: PxAnimatable<number> | undefined): { min: number; max: number } {\n if (typeof v === 'number') return { min: v, max: v };\n if (v && typeof v === 'object') {\n const o = v as { value?: number; keyframes?: Array<{ value?: number }> };\n if (typeof o.value === 'number') return { min: o.value, max: o.value };\n if (Array.isArray(o.keyframes) && o.keyframes.length) {\n const vals = o.keyframes.map(k => Number(k.value) || 0);\n return { min: Math.min(...vals), max: Math.max(...vals) };\n }\n }\n return { min: 0, max: 0 };\n}\n\n/** Generous upper bound on the text's advance width: char-count × largest font\n * (~1em/char). Over-estimating is safe — the extension is an invisible tail of the\n * reference `<path>`, so extra length just goes unused. */\nfunction estimateTextAdvance(node: PxNode): number {\n let chars = 0, maxFont = 16;\n const walk = (el: PxNode): void => {\n const fs = parseFloat(String((el as any).fontSize ?? '')) || 0;\n if (fs) maxFont = Math.max(maxFont, fs);\n const t = (el as any).text ?? (el as any).textContent;\n if (typeof t === 'string') chars += t.length;\n if (el.children) for (const c of el.children) walk(c);\n };\n walk(node);\n return chars * maxFont;\n}\n\nconst r3 = (n: number): number => Math.round(n * 1000) / 1000;\n\n/** Inputs for {@link extendedPathForBrowser}. `advance` = the text run-width used to\n * size the end extension (caller-measured; the player estimates it from the node,\n * the editor from its text model — browser fonts have no glyph metrics available). */\nexport interface ExtendPathOpts {\n pathOverflow?: string;\n startOffset?: PxAnimatable<number>;\n textLength?: PxAnimatable<number>;\n advance?: number;\n}\n\n/** Result of {@link extendedPathForBrowser}: the (possibly) extended `d`, plus\n * `startShift` — the length of the prepended START lead-in. Because that lead-in\n * moves the `<textPath>` origin back by `startShift`, EVERY `startOffset` (all\n * keyframes) MUST be shifted by `+startShift` so the text lands where it would on\n * the un-extended path (`extend` only adds a tail, it must never move the text). */\nexport interface ExtendedPath {\n d: string;\n startShift: number;\n}\n\n/** Shift a `PxAnimatable<number>` by a constant (all keyframes). No-op for `0`. */\nexport function shiftAnimatable(v: PxAnimatable<number> | undefined, by: number): PxAnimatable<number> | undefined {\n if (!by || v === undefined || v === null) return v;\n if (typeof v === 'number') return v + by;\n const o = v as { value?: number; keyframes?: Array<{ value?: number }> };\n if (typeof o.value === 'number') return { ...o, value: o.value + by };\n if (Array.isArray(o.keyframes)) return { ...o, keyframes: o.keyframes.map(k => ({ ...k, value: (Number(k.value) || 0) + by })) };\n return v;\n}\n\n/** For `pathOverflow:'extend'` (browser-font): extend an OPEN path along its endpoint\n * tangents so the browser lays overflow glyphs onto the straight extension (matching\n * glyph-mode's tangent behavior) instead of dropping them. `'clip'`/closed paths are\n * returned unchanged (browser clips natively). Shared by the player's browser-font\n * applier and the editor's live/heavy `<textPath>` def mint (single source of truth).\n * Returns the extended `d` AND `startShift` — see {@link ExtendedPath}. */\nexport function extendedPathForBrowser(pathD: string, opts: ExtendPathOpts): ExtendedPath {\n if (opts.pathOverflow === 'clip') return { d: pathD, startShift: 0 };\n const sampler = createPathSampler(pathD);\n if (!sampler || sampler.closed || sampler.totalLength <= 0) return { d: pathD, startShift: 0 };\n\n const L = sampler.totalLength;\n const margin = EXTEND_MARGIN_FRAC * L;\n const so = numRange(opts.startOffset);\n const runWidth = numRange(opts.textLength).max || (opts.advance ?? 0);\n // START: how far the EARLIEST (most-negative) startOffset reaches before the path\n // start. END: how far the LATEST run (max startOffset + run width) reaches past the\n // path end. Only add the slack `margin` when actually extending, so a non-negative\n // startOffset that fits leaves the corresponding end alone (no phantom shift).\n const startOverflow = Math.max(0, -so.min);\n const endOverflow = Math.max(0, so.max + runWidth - L);\n const startExt = startOverflow > 0 ? startOverflow + margin : 0;\n const endExt = endOverflow > 0 ? endOverflow + margin : 0;\n if (endExt <= 0 && startExt <= 0) return { d: pathD, startShift: 0 };\n\n const s = sampler.sampleAtDistance(0);\n const e = sampler.sampleAtDistance(L);\n let d = pathD;\n if (startExt > 0) {\n const sx = s.x - Math.cos(s.angle) * startExt, sy = s.y - Math.sin(s.angle) * startExt;\n // Prepend a lead-in: M(extended start) L(original start) + the original path\n // minus its own leading `M x y` (we've re-stated the start via the `L`).\n const rest = pathD.replace(/^\\s*[Mm]\\s*-?[\\d.]+[\\s,]+-?[\\d.]+/, '');\n d = 'M' + r3(sx) + ',' + r3(sy) + 'L' + r3(s.x) + ',' + r3(s.y) + rest;\n }\n if (endExt > 0) {\n const ex = e.x + Math.cos(e.angle) * endExt, ey = e.y + Math.sin(e.angle) * endExt;\n d += 'L' + r3(ex) + ',' + r3(ey);\n }\n // The `<textPath>` distance origin moved back by exactly the start lead-in length.\n return { d, startShift: startExt };\n}\n\n\n/**\n * `effects.textPath` materialiser (browser-font / non-glyph path).\n *\n * The path geometry is carried INLINE on the effect as `path` (an SVG `d`). SVG's\n * native rendering requires a `<textPath href=\"#…\">` wrapper referencing a `<path>`\n * def, so this applier mints that `<path>` def from the inline geometry, wraps the\n * text node's children in the `<textPath>`, and forwards the textPath SVG attrs\n * (`lengthAdjust`, `method`, `spacing`, `startOffset`, `textLength`).\n *\n * `startOffset` / `textLength` accept the full `PxAnimatable<number>` shape: a static\n * number is set as an attribute; the `{keyframes}` form is forwarded to\n * `<textPath>.animate.<attr>`; `{value}` is unwrapped to the static shape.\n *\n * `pathOverflow:'extend'` tangent-extends the minted `<path>` (see\n * {@link extendedPathForBrowser}) so the browser lays overflow glyphs onto the straight\n * extension; `'clip'` mints the geometry as-is and native `<textPath>` drops overflow.\n */\nexport function applyTextPathEffect(\n node: PxNode,\n fx: PxTextPathEffect | undefined,\n ctx: ApplyContext,\n): PxNode {\n if (!fx || typeof fx.path !== 'string' || !fx.path) return node;\n\n const pathId = genId(ctx, 'tpath');\n const { d, startShift } = extendedPathForBrowser(fx.path, {\n pathOverflow: fx.pathOverflow, startOffset: fx.startOffset,\n textLength: fx.textLength, advance: estimateTextAdvance(node),\n });\n ctx.defs.push({ type: 'path', id: pathId, d });\n\n const textPath: PxNode = {\n type: 'textPath',\n href: '#' + pathId,\n children: node.children ?? [],\n };\n if (fx.lengthAdjust !== undefined) textPath.lengthAdjust = fx.lengthAdjust;\n if (fx.method !== undefined) textPath.method = fx.method;\n if (fx.spacing !== undefined) textPath.spacing = fx.spacing;\n // Compensate the start lead-in: shift startOffset (all keyframes) by `startShift`\n // so `extend` doesn't move the text vs the un-extended path.\n applyAnimatableNumber(textPath, 'startOffset', shiftAnimatable(fx.startOffset, startShift));\n applyAnimatableNumber(textPath, 'textLength', fx.textLength);\n\n node.children = [textPath];\n return node;\n}\n\n\n/** Routes a `PxAnimatable<number>` onto a node:\n * - bare `number` / `{value:number}` → `node[attrName] = String(value)`\n * - `{keyframes:[…]}` → `node.animate[attrName] = { keyframes }`\n * Mirrors the pattern in `trimPathEffect.applyAttr`. */\nfunction applyAnimatableNumber(node: PxNode, attrName: string, raw: PxAnimatable<number> | undefined): void {\n if (raw === undefined || raw === null) return;\n\n if (typeof raw === 'number') {\n node[attrName] = String(raw);\n return;\n }\n if (typeof raw === 'object' && raw !== null) {\n const obj = raw as { value?: number; keyframes?: Array<unknown>; loop?: unknown };\n if (Array.isArray(obj.keyframes)) {\n const prevAnimate = node.animate && typeof node.animate === 'object' && !Array.isArray(node.animate) ? node.animate : undefined;\n const animate: Record<string, any> = { ...(prevAnimate || {}) };\n const block: { keyframes: Array<unknown>, loop?: unknown } = { keyframes: obj.keyframes };\n if (obj.loop !== undefined) block.loop = obj.loop;\n animate[attrName] = block;\n node.animate = animate;\n return;\n }\n if (typeof obj.value === 'number') {\n node[attrName] = String(obj.value);\n return;\n }\n }\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\n/**\n * Element-creation factory — abstracts WHAT an \"element\" is so the same\n * geometry/layout code (e.g. the glyph text materialiser) can emit plain wire\n * nodes here, or the editor's React / px elements when called from the editor.\n *\n * The signature intentionally mirrors the editor's `createPxElement(type,\n * props, children, fixReactKeysIfNeeded?)` so the editor's own factory drops in\n * unchanged.\n */\nexport type PxCreateElement<E = any> = (\n type: string,\n props: { [k: string]: any },\n children?: Array<E> | E | null,\n fixReactKeysIfNeeded?: boolean,\n) => E;\n\n\n/**\n * Default factory → a plain wire node `{ type, ...props, children? }`.\n * Drops `undefined` props and empty `children` so output matches the shape the\n * effects pipeline (and `JSON.stringify`) expects.\n */\nexport const jsonElementFactory: PxCreateElement<any> = (type, props, children) => {\n const node: { [k: string]: any } = { type };\n for (const k in props) if (props[k] !== undefined) node[k] = props[k];\n const arr = Array.isArray(children) ? children.filter(c => c != null) : (children != null ? [children] : []);\n if (arr.length) node.children = arr;\n return node;\n};\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\n/**\n * Bakes an affine transform into an SVG path-`d` string so per-glyph outlines\n * (in em units) can be placed at their pen position and merged into a single\n * `<path>`. Parses the absolute `M`/`L`/`C`/`Q`/`Z` commands opentype's\n * `toPathData` emits — glyph outlines never use relative or arc commands.\n *\n * Matrix order matches SVG: `x' = a·x + c·y + e`, `y' = b·x + d·y + f`.\n * For horizontal text it's just scale+translate `[s,0,0,s,tx,ty]`; the full\n * 6-tuple leaves room for rotation (along-path, later).\n */\nexport type Affine = [a: number, b: number, c: number, d: number, e: number, f: number];\n\n\nfunction fmt(v: number, decimals: number): string {\n // Match opentype's `floatToString`: integers stay bare, else fixed decimals.\n return Math.round(v) === v ? '' + Math.round(v) : v.toFixed(decimals);\n}\n\n/** Packs numbers the way opentype does: a space separates a value from the\n * previous one only when it doesn't already start with a `-`. */\nfunction pack(nums: Array<number>, decimals: number): string {\n let s = '';\n for (let i = 0; i < nums.length; i++) {\n const str = fmt(nums[i], decimals);\n if (i > 0 && str.charCodeAt(0) !== 45 /* '-' */) s += ' ';\n s += str;\n }\n return s;\n}\n\nfunction apply(m: Affine, x: number, y: number): [number, number] {\n return [m[0] * x + m[2] * y + m[4], m[1] * x + m[3] * y + m[5]];\n}\n\nconst TOKEN_RE = /([MLCQZ])|(-?\\d*\\.?\\d+(?:e[-+]?\\d+)?)/gi;\n\n/**\n * Applies `m` to every coordinate in `d` (absolute M/L/C/Q/Z) and re-emits.\n * Unknown tokens are skipped defensively; the input is always opentype output.\n */\nexport function transformPathData(d: string, m: Affine, decimals: number = 2): string {\n const tokens: Array<string> = [];\n let match: RegExpExecArray | null;\n TOKEN_RE.lastIndex = 0;\n while ((match = TOKEN_RE.exec(d)) !== null) tokens.push(match[0]);\n\n let out = '';\n let i = 0;\n const num = (): number => parseFloat(tokens[i++]);\n\n while (i < tokens.length) {\n const cmd = tokens[i++];\n if (cmd === 'M' || cmd === 'L') {\n const [x, y] = apply(m, num(), num());\n out += cmd + pack([x, y], decimals);\n } else if (cmd === 'C') {\n const [x1, y1] = apply(m, num(), num());\n const [x2, y2] = apply(m, num(), num());\n const [x, y] = apply(m, num(), num());\n out += 'C' + pack([x1, y1, x2, y2, x, y], decimals);\n } else if (cmd === 'Q') {\n const [x1, y1] = apply(m, num(), num());\n const [x, y] = apply(m, num(), num());\n out += 'Q' + pack([x1, y1, x, y], decimals);\n } else if (cmd === 'Z' || cmd === 'z') {\n out += 'Z';\n }\n // else: stray number without a command — skip (never happens for glyph data).\n }\n return out;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\n/**\n * Glyph text materialiser — turns a `<text>`/`<tspan>` subtree into `<path>`\n * outlines from `definitions.glyphs`, so the text renders with no external font.\n *\n * - HORIZONTAL ({@link materialiseGlyphTextHorizontal}) — left-to-right by\n * advance width; honours font-size, text-anchor, letter/word-spacing,\n * per-tspan x/y/dx/dy, fill/stroke, nested tspans.\n * - ALONG-PATH ({@link materialiseGlyphTextAlongPath}) — each glyph placed and\n * rotated to the referenced path's tangent. Static `startOffset` → glyphs\n * bake+merge; animated `startOffset` → per-glyph `<path>` with sampled\n * `animate.transform`. Text-level `x`/`dx` add distance ALONG the path (≈\n * startOffset) and `dy` shifts PERPENDICULAR — matching native `<textPath>`\n * (see {@link alongPathNodeOffsets}); `y` and per-tspan positioning are ignored\n * (a single run).\n *\n * Element creation goes through an injected {@link PxCreateElement} factory, so\n * the SAME layout produces plain wire nodes here (the effects pipeline) or the\n * editor's React/px elements when the editor calls it — see\n * {@link materialiseGlyphText}.\n *\n * v1 scope (see svga.text.design.md): keyframe-interval easing is linear;\n * kerning/ligatures, per-tspan opacity, text-level animated fill are out of scope.\n */\n\nimport { TEXT_ATTR, TEXT_CONTENT_ATTR, type PxAnimatable, type PxGlyphFont, type PxNode, type PxTextEffect } from '../PxAnimatorTypes';\nimport { jsonElementFactory, type PxCreateElement } from './elementFactory';\nimport { transformPathData, type Affine } from './glyphPathBake';\nimport { createPathSampler, type PathSampler } from './pathSampler';\nimport { unwrapAutoOrientRotations } from '../PxMotionPath';\nimport { ReadKind, readAnimatable, TransformPart } from './transformParts';\nimport type { ApplyContext } from './types';\n\n\nconst DEFAULT_FONT_SIZE = 16;\n\n/** Text/tspan attribute keys that don't belong on the materialised `<g>`. */\nconst TEXT_ATTR_KEYS: ReadonlyArray<string> = [\n 'fontFamily', 'fontSize', 'fontWeight', 'fontStyle', 'textAnchor',\n 'letterSpacing', 'wordSpacing', 'textDecoration', 'textTransform',\n 'whiteSpace', 'x', 'y', 'dx', 'dy', 'lengthAdjust',\n 'fill', 'stroke', 'strokeWidth', 'effects',\n TEXT_ATTR, TEXT_CONTENT_ATTR, 'xml:space',\n];\n\n/** Inputs for a glyph materialisation, decoupled from the effects `ApplyContext`\n * so the editor can call the materialiser directly. */\nexport interface GlyphMaterialiseOpts<E = any> {\n /** Embedded glyph fonts, keyed by `font-family`. */\n glyphs: Record<string, PxGlyphFont>;\n /** Element factory — defaults to plain wire nodes ({@link jsonElementFactory}). */\n create?: PxCreateElement<E>;\n /** Optional diagnostics sink. */\n warnings?: Array<string>;\n}\n\n// fill/stroke/strokeWidth are OPAQUE pass-throughs — copied verbatim onto the\n// emitted element. The wire uses strings (hex); the editor threads its own\n// colour VALUES through unchanged (the factory maps them back to shape paint).\ninterface Paint { fill?: any; stroke?: any; strokeWidth?: any; }\ninterface Style extends Paint { fontFamily?: string; fontSize: number; letterSpacing: number; wordSpacing: number; }\n/** A glyph ready to emit: its em outline + the affine placing it in the doc. */\ninterface Placement { glyphD: string; m: Affine; paint: Paint; }\n/** Minimal keyframe shape (avoids `PxKeyframe`'s non-generic type). Input\n * `startOffset` kfs carry a number `value`; emitted kfs carry transform parts. */\ninterface TransformKeyframe<V = any> { time?: number; value: V; }\n\n\nfunction parseLen(v: unknown): number | undefined {\n if (typeof v === 'number') return v;\n if (typeof v === 'string') { const n = parseFloat(v); return isNaN(n) ? undefined : n; }\n return undefined;\n}\n\nfunction str(v: unknown): string | undefined {\n return typeof v === 'string' ? v : undefined;\n}\n\nfunction resolveStyle(node: PxNode, parent: Style): Style {\n return {\n fontFamily: str(node.fontFamily) ?? parent.fontFamily,\n fontSize: parseLen(node.fontSize) ?? parent.fontSize,\n fill: node.fill ?? parent.fill,\n stroke: node.stroke ?? parent.stroke,\n strokeWidth: node.strokeWidth ?? parent.strokeWidth,\n letterSpacing: parseLen(node.letterSpacing) ?? parent.letterSpacing,\n wordSpacing: parseLen(node.wordSpacing) ?? parent.wordSpacing,\n };\n}\n\nfunction rootStyleOf(node: PxNode): Style {\n return {\n fontFamily: str(node.fontFamily),\n fontSize: parseLen(node.fontSize) ?? DEFAULT_FONT_SIZE,\n fill: node.fill,\n stroke: node.stroke,\n strokeWidth: node.strokeWidth,\n letterSpacing: parseLen(node.letterSpacing) ?? 0,\n wordSpacing: parseLen(node.wordSpacing) ?? 0,\n };\n}\n\nfunction paintOf(s: Style): Paint {\n const p: Paint = {};\n if (s.fill !== undefined) p.fill = s.fill;\n if (s.stroke !== undefined) p.stroke = s.stroke;\n if (s.strokeWidth !== undefined) p.strokeWidth = s.strokeWidth;\n return p;\n}\n\nfunction glyphFontFor(s: Style, glyphs: Record<string, PxGlyphFont>, soleFont: PxGlyphFont | undefined, warnings?: Array<string>): PxGlyphFont | undefined {\n const gf = s.fontFamily ? glyphs[s.fontFamily] : soleFont;\n if (!gf) warnings?.push('textGlyphs: no glyphs for font \"' + (s.fontFamily ?? '') + '\"');\n return gf;\n}\n\nfunction soleFontOf(glyphs: Record<string, PxGlyphFont>): PxGlyphFont | undefined {\n const names = Object.keys(glyphs);\n return names.length === 1 ? glyphs[names[0]] : undefined;\n}\n\n\n/** Default advance (in em units) for a MISSING glyph with no known width, so its\n * placeholder box gets a plausible letter-cell instead of collapsing to nothing. */\nconst MISSING_GLYPH_ADVANCE_EM = 0.6;\n\n/**\n * A HOLLOW FRAME outline (em/glyph units, baseline at y=0 rising to y=-ascent) for a\n * MISSING glyph — so a font that can't supply a char renders a visible □ instead of\n * silently disappearing. Outer rect + a reversed inner rect → a plain nonzero `fill`\n * (the SAME paint a real glyph uses) leaves the middle empty, i.e. a thin outline (a\n * solid block reads as too brutal). Empty string for degenerate sizes.\n */\nfunction missingGlyphBoxEm(advanceEm: number, ascentEm: number): string {\n if (advanceEm <= 0 || ascentEm <= 0) return '';\n const inset = 0.08;\n const x0 = advanceEm * inset, x1 = advanceEm * (1 - inset);\n const y1 = -ascentEm * (1 - inset); // box top (baseline at 0)\n const bw = x1 - x0, bh = -y1;\n const t = Math.max(1, Math.min(bw, bh) * 0.12); // frame border thickness\n const outer = 'M' + x0 + ' 0L' + x1 + ' 0L' + x1 + ' ' + y1 + 'L' + x0 + ' ' + y1 + 'Z';\n if (bw <= 2 * t || bh <= 2 * t) return outer; // too small for a hole → solid\n const ix0 = x0 + t, ix1 = x1 - t, iyb = -t, iyt = y1 + t;\n // Inner rect wound OPPOSITE the outer → nonzero fill carves a hole (the outline).\n return outer + 'M' + ix0 + ' ' + iyb + 'L' + ix0 + ' ' + iyt + 'L' + ix1 + ' ' + iyt + 'L' + ix1 + ' ' + iyb + 'Z';\n}\n\n\n// ── HORIZONTAL ──────────────────────────────────────────────────────────────\n\nexport function materialiseGlyphTextHorizontal<E = any>(node: PxNode, opts: GlyphMaterialiseOpts<E>): E {\n const { glyphs, create = jsonElementFactory as PxCreateElement<E>, warnings } = opts;\n const soleFont = soleFontOf(glyphs);\n\n const pen = { x: parseLen(node.x) ?? 0, y: parseLen(node.y) ?? 0 };\n const placements: Array<Placement & { line: number; x: number; y: number; scale: number }> = [];\n const lines: Array<{ start: number; end: number }> = [{ start: pen.x, end: pen.x }];\n let line = 0;\n\n const renderChars = (content: string, s: Style): void => {\n const gf = glyphFontFor(s, glyphs, soleFont, warnings);\n const upm = gf?.unitsPerEm || 1000;\n const scale = s.fontSize / upm;\n const ascentEm = gf?.ascent ?? 0.9 * upm;\n const paint = paintOf(s);\n for (let i = 0; i < content.length; i++) {\n const ch = content.charAt(i);\n const g = gf?.glyphs[ch];\n if (g && g.d) {\n placements.push({ glyphD: g.d, m: [scale, 0, 0, scale, pen.x, pen.y], paint, line, x: pen.x, y: pen.y, scale });\n pen.x += g.width * scale;\n } else if (/\\S/.test(ch)) {\n // Missing glyph (font absent, or the char has no outline) → a visible □\n // placeholder box so the text doesn't just silently vanish.\n const advEm = (g && g.width > 0) ? g.width : MISSING_GLYPH_ADVANCE_EM * upm;\n placements.push({ glyphD: missingGlyphBoxEm(advEm, ascentEm), m: [scale, 0, 0, scale, pen.x, pen.y], paint, line, x: pen.x, y: pen.y, scale });\n pen.x += advEm * scale;\n } else {\n pen.x += (g ? g.width : 0) * scale; // whitespace: advance only\n }\n pen.x += s.letterSpacing + (ch === ' ' ? s.wordSpacing : 0);\n lines[line].end = pen.x;\n }\n };\n\n const walk = (el: PxNode, parentStyle: Style): void => {\n const s = resolveStyle(el, parentStyle);\n const x = parseLen(el.x);\n const y = parseLen(el.y);\n if (x !== undefined) { pen.x = x; line = lines.length; lines.push({ start: pen.x, end: pen.x }); }\n if (y !== undefined) pen.y = y;\n pen.x += parseLen(el.dx) ?? 0;\n pen.y += parseLen(el.dy) ?? 0;\n const content = str(el[TEXT_ATTR]) ?? str(el[TEXT_CONTENT_ATTR]);\n // Render a node's OWN text only when it has no element children. In the glyph\n // text model text lives on leaf spans; a container that ALSO carries folded\n // text — a single-span line collapsed onto its line-`<tspan>` — would\n // otherwise render its run twice (the fold AND the child span).\n if (content && !el.children?.length) renderChars(content, s);\n if (el.children) for (const ch of el.children) walk(ch, s);\n };\n\n const rootStyle = rootStyleOf(node);\n if (node.children) for (const ch of node.children) walk(ch, rootStyle);\n const rootContent = str(node[TEXT_ATTR]) ?? str(node[TEXT_CONTENT_ATTR]);\n if (rootContent && !node.children?.length) renderChars(rootContent, rootStyle);\n\n // text-anchor: shift each line by its own advance width, then rebuild `m`.\n const anchor = str(node.textAnchor);\n if (anchor === 'middle' || anchor === 'end') {\n for (const p of placements) {\n const w = lines[p.line].end - lines[p.line].start;\n const shift = anchor === 'middle' ? -w / 2 : -w;\n p.m = [p.scale, 0, 0, p.scale, p.x + shift, p.y];\n }\n }\n\n return toGroup(node, buildPaths(placements, create, warnings), create);\n}\n\n\n/** Per-CHARACTER advance box (local, pre-transform coords). `x,y` = the char's baseline start,\n * `width` = its advance, `ascent`/`fontSize` size its bbox. */\nexport interface GlyphCharBox {\n x: number; y: number; width: number; ascent: number; fontSize: number;\n /** Along-path only: baseline END point (leading edge of the next char). Absent for\n * horizontal, where the end is `x + width` on the same baseline. */\n endX?: number; endY?: number;\n /** Along-path only: char rotation in DEGREES (path tangent; 0 = horizontal). */\n rotation?: number;\n}\n\n/** Optional along-path geometry for {@link layoutGlyphTextChars}: when given, chars are\n * placed + rotated along `pathD` (mirrors {@link materialiseGlyphTextAlongPath}) at the\n * STATIC / frame-0 startOffset, so the editor caret follows the path. */\nexport interface GlyphCharBoxAlongPath { pathD?: string; startOffset?: PxAnimatable<number>; textLength?: PxAnimatable<number>; pathOverflow?: string; }\n\n/** Per-character layout boxes for a glyph text, in reading/DOM order INCLUDING spaces\n * (a space has no glyph but advances the pen) AND one zero-width filler box per EMPTY\n * line — the editor's edit canvas renders a zero-width filler char for an empty line\n * (so the caret has something to measure), and DOM char indices must stay aligned.\n * HORIZONTAL by default — mirrors `materialiseGlyphTextHorizontal`'s pen-walk exactly\n * (same x/y/dx/dy, spacing and text-anchor). When `opts.alongPath` is given, mirrors\n * `materialiseGlyphTextAlongPath` (each char placed + rotated to the path tangent). So\n * an editor caret built from these lands on the rendered glyphs. Empty for a text with\n * no glyph font / unparsable path. */\nexport function layoutGlyphTextChars(node: PxNode, opts: Pick<GlyphMaterialiseOpts, 'glyphs' | 'warnings'> & { alongPath?: GlyphCharBoxAlongPath }): Array<GlyphCharBox> {\n if (opts.alongPath?.pathD) return layoutGlyphTextCharsAlongPath(node, opts.alongPath.pathD, opts);\n const { glyphs, warnings } = opts;\n const soleFont = soleFontOf(glyphs);\n\n const pen = { x: parseLen(node.x) ?? 0, y: parseLen(node.y) ?? 0 };\n const boxes: Array<GlyphCharBox & { line: number }> = [];\n const lines: Array<{ start: number; end: number }> = [{ start: pen.x, end: pen.x }];\n let line = 0;\n\n const renderChars = (content: string, s: Style): void => {\n const gf = glyphFontFor(s, glyphs, soleFont, warnings);\n const upm = gf?.unitsPerEm || 1000;\n const scale = s.fontSize / upm;\n const ascent = (gf?.ascent ?? 0.9 * upm) * scale;\n for (let i = 0; i < content.length; i++) {\n const ch = content.charAt(i);\n const g = gf?.glyphs[ch];\n const advance = (g ? g.width : 0) * scale + s.letterSpacing + (ch === ' ' ? s.wordSpacing : 0);\n boxes.push({ x: pen.x, y: pen.y, width: advance, ascent, fontSize: s.fontSize, line });\n pen.x += advance;\n lines[line].end = pen.x;\n }\n };\n\n const walk = (el: PxNode, parentStyle: Style): void => {\n const s = resolveStyle(el, parentStyle);\n const x = parseLen(el.x);\n const y = parseLen(el.y);\n if (x !== undefined) { pen.x = x; line = lines.length; lines.push({ start: pen.x, end: pen.x }); }\n if (y !== undefined) pen.y = y;\n pen.x += parseLen(el.dx) ?? 0;\n pen.y += parseLen(el.dy) ?? 0;\n const content = str(el[TEXT_ATTR]) ?? str(el[TEXT_CONTENT_ATTR]);\n if (content && !el.children?.length) renderChars(content, s);\n if (el.children) for (const ch of el.children) walk(ch, s);\n };\n\n const rootStyle = rootStyleOf(node);\n if (node.children) for (const ch of node.children) {\n const before = boxes.length;\n walk(ch, rootStyle);\n // An EMPTY line (a line-tspan whose subtree yields no chars) still occupies ONE\n // DOM slot on the edit canvas — the zero-width filler the editor renders so the\n // caret has something to measure. Mirror it: one zero-width box at the line's\n // pen position, sized by the line's own resolved font (ascent for caret height,\n // and its hit quad extends the element bbox to include the empty line).\n if (boxes.length === before) {\n const s = resolveStyle(ch, rootStyle);\n const gf = glyphFontFor(s, glyphs, soleFont); // no warning — an empty line has nothing to render\n const upm = gf?.unitsPerEm || 1000;\n boxes.push({ x: pen.x, y: pen.y, width: 0, ascent: (gf?.ascent ?? 0.9 * upm) * (s.fontSize / upm), fontSize: s.fontSize, line });\n }\n }\n const rootContent = str(node[TEXT_ATTR]) ?? str(node[TEXT_CONTENT_ATTR]);\n if (rootContent && !node.children?.length) renderChars(rootContent, rootStyle);\n\n // text-anchor: shift each line's chars by its own advance width (matches the placement shift).\n const anchor = str(node.textAnchor);\n if (anchor === 'middle' || anchor === 'end') {\n for (const b of boxes) {\n const w = lines[b.line].end - lines[b.line].start;\n b.x += anchor === 'middle' ? -w / 2 : -w;\n }\n }\n return boxes.map(({ line: _l, ...b }) => b);\n}\n\n/** Along-path variant of {@link layoutGlyphTextChars}: one box per DOM char (spaces\n * included), placed + rotated along `pathD` at the static / frame-0 startOffset.\n * Mirrors `collectAlongPathCells` + `materialiseGlyphTextAlongPath`, but records EVERY\n * char (the materialiser's cells skip glyph-less chars). `pStart`=char leading edge on\n * the path, `end`=trailing edge, `rotation`=tangent at the char midpoint. */\nfunction layoutGlyphTextCharsAlongPath(node: PxNode, pathD: string, opts: Pick<GlyphMaterialiseOpts, 'glyphs' | 'warnings'> & { alongPath?: GlyphCharBoxAlongPath }): Array<GlyphCharBox> {\n const { glyphs, warnings, alongPath } = opts;\n const sampler = createPathSampler(pathD);\n if (!sampler) { warnings?.push('textGlyphs: unparsable along-path geometry (caret)'); return []; }\n const soleFont = soleFontOf(glyphs);\n\n // Reading-order pass over leaf text (positioning attrs ignored — along-path is a\n // single run), recording each char's [advStart, advEnd], its glyph advance (WITHOUT\n // spacing) for the rotation midpoint, and bbox metrics.\n const chars: Array<{ advStart: number; advEnd: number; glyphW: number; ascent: number; fontSize: number }> = [];\n let adv = 0;\n const walk = (el: PxNode, parentStyle: Style): void => {\n const s = resolveStyle(el, parentStyle);\n const content = str(el[TEXT_ATTR]) ?? str(el[TEXT_CONTENT_ATTR]);\n if (content && !el.children?.length) {\n const gf = glyphFontFor(s, glyphs, soleFont, warnings);\n const upm = gf?.unitsPerEm || 1000;\n const scale = s.fontSize / upm;\n const ascent = (gf?.ascent ?? 0.9 * upm) * scale;\n for (let i = 0; i < content.length; i++) {\n const ch = content.charAt(i);\n const g = gf?.glyphs[ch];\n const glyphW = (g ? g.width : 0) * scale;\n const advance = glyphW + s.letterSpacing + (ch === ' ' ? s.wordSpacing : 0);\n chars.push({ advStart: adv, advEnd: adv + advance, glyphW, ascent, fontSize: s.fontSize });\n adv += advance;\n }\n }\n if (el.children) for (const ch of el.children) walk(ch, s);\n };\n walk(node, rootStyleOf(node));\n\n const width = adv;\n // textLength (lengthAdjust=spacing): scale positions so the run spans textLength.\n // Static / frame-0 read — the caret is a static-frame layout (like startOffset below).\n const tlr = readAnimatable<number>(alongPath?.textLength);\n const tlv = tlr.kind === ReadKind.Animated ? (Number(tlr.keyframes[0]?.value) || 0)\n : tlr.kind === ReadKind.Static ? (Number(tlr.value) || 0) : 0;\n const k = (tlv > 0 && width > 0) ? tlv / width : 1;\n // startOffset base — static or frame-0 keyframe (matches the materialiser's static place).\n // x/dx add along-path distance; dy shifts perpendicular (both mirror the materialiser).\n const so = readAnimatable<number>(alongPath?.startOffset);\n const { along: alongOffset, perp } = alongPathNodeOffsets(node);\n const base = alongOffset + (so.kind === ReadKind.Animated ? (Number(so.keyframes[0]?.value) || 0)\n : so.kind === ReadKind.Static ? (Number(so.value) || 0) : 0);\n\n // Shift a sampled point perpendicular to the path (left normal) by `perp`.\n const withPerp = (p: { x: number; y: number; angle: number }) => ({\n x: p.x - perp * Math.sin(p.angle), y: p.y + perp * Math.cos(p.angle), angle: p.angle,\n });\n\n return chars.map(c => {\n const dStart = base + c.advStart * k;\n const dEnd = base + c.advEnd * k;\n const p0 = withPerp(sampler.sampleAtDistance(dStart));\n const p1 = withPerp(sampler.sampleAtDistance(dEnd));\n // Caret rotation = tangent at the GLYPH's own midpoint (advStart + glyphW/2), which\n // DISREGARDS the char's letter/word spacing. This keeps the synthetic caret aligned\n // with the baked glyph outline (which is placed at its glyph centre), so letter\n // spacing doesn't add extra tilt to the caret.\n const glyphMid = sampler.sampleAtDistance(base + (c.advStart + c.glyphW / 2) * k);\n return {\n x: p0.x, y: p0.y,\n width: c.advEnd - c.advStart,\n ascent: c.ascent, fontSize: c.fontSize,\n endX: p1.x, endY: p1.y,\n rotation: glyphMid.angle * 180 / Math.PI,\n };\n });\n}\n\n\n// ── ALONG-PATH ──────────────────────────────────────────────────────────────\n\n/** One glyph in path order: its outline + geometry, and `midBase` = the arc-\n * distance from the text start (startOffset 0) to the glyph's advance midpoint. */\ninterface AlongCell { glyphD: string; widthEm: number; scale: number; paint: Paint; midBase: number; }\n\n/** Walks the tspans in reading order, accumulating advance (whitespace included)\n * so each rendered glyph gets its `midBase`. Positioning attrs are ignored —\n * along-path text is a single run. */\nfunction collectAlongPathCells(node: PxNode, glyphs: Record<string, PxGlyphFont>, soleFont: PxGlyphFont | undefined, warnings?: Array<string>): { cells: Array<AlongCell>; width: number } {\n const cells: Array<AlongCell> = [];\n let adv = 0;\n const walk = (el: PxNode, parentStyle: Style): void => {\n const s = resolveStyle(el, parentStyle);\n const content = str(el[TEXT_ATTR]) ?? str(el[TEXT_CONTENT_ATTR]);\n // Only leaf text (no children) — a single-span line folds its text onto the\n // line-`<tspan>` AND keeps the child span; rendering both would duplicate it.\n if (content && !el.children?.length) {\n const gf = glyphFontFor(s, glyphs, soleFont, warnings);\n if (gf) {\n const scale = s.fontSize / gf.unitsPerEm;\n const ascentEm = gf.ascent ?? 0.9 * gf.unitsPerEm;\n const paint = paintOf(s);\n for (let i = 0; i < content.length; i++) {\n const ch = content.charAt(i);\n const g = gf.glyphs[ch];\n if (g && g.d) {\n const glyphAdv = g.width * scale;\n cells.push({ glyphD: g.d, widthEm: g.width, scale, paint, midBase: adv + glyphAdv / 2 });\n adv += glyphAdv;\n } else if (/\\S/.test(ch)) {\n // Missing glyph → a visible □ placeholder box (see missingGlyphBoxEm).\n const wEm = (g && g.width > 0) ? g.width : MISSING_GLYPH_ADVANCE_EM * gf.unitsPerEm;\n const boxAdv = wEm * scale;\n cells.push({ glyphD: missingGlyphBoxEm(wEm, ascentEm), widthEm: wEm, scale, paint, midBase: adv + boxAdv / 2 });\n adv += boxAdv;\n } else {\n adv += (g ? g.width : 0) * scale; // whitespace: advance only\n }\n adv += s.letterSpacing + (ch === ' ' ? s.wordSpacing : 0);\n }\n }\n }\n if (el.children) for (const ch of el.children) walk(ch, s);\n };\n walk(node, rootStyleOf(node));\n return { cells, width: adv };\n}\n\n/** Affine placing a glyph so its mid-advance baseline sits at path-distance\n * `dist`, rotated to the tangent (scale baked in). `perp` shifts the glyph\n * PERPENDICULAR to the path (SVG `dy` on text-on-a-path), along the left normal\n * (−sinθ, cosθ) — in path/user units, NOT scaled by the glyph size. */\nfunction alongAffine(sampler: PathSampler, dist: number, scale: number, widthEm: number, perp = 0): Affine {\n const { x, y, angle } = sampler.sampleAtDistance(dist);\n const cos = Math.cos(angle), sin = Math.sin(angle), hw = widthEm / 2;\n return [scale * cos, scale * sin, -scale * sin, scale * cos, x - scale * cos * hw - perp * sin, y - scale * sin * hw + perp * cos];\n}\n\n/** Text-on-a-path offsets from the `<text>`/`<tspan>` x/dx/dy attributes (horizontal\n * writing mode; see the SVG \"text on a path\" layout rules):\n * • `x` and `dx` shift ALONG the path (both add to the startpoint distance),\n * • `dy` shifts PERPENDICULAR to the path,\n * • `y` is IGNORED (the path, not `y`, sets the cross-axis position).\n * Matches the browser's native `<textPath>` so our baked glyphs line up with it. */\nfunction alongPathNodeOffsets(node: PxNode): { along: number; perp: number } {\n return {\n along: (parseLen(node.x) ?? 0) + (parseLen(node.dx) ?? 0),\n perp: parseLen(node.dy) ?? 0,\n };\n}\n\nexport function materialiseGlyphTextAlongPath<E = any>(\n node: PxNode,\n pathD: string | undefined,\n startOffset: PxAnimatable<number> | undefined,\n opts: GlyphMaterialiseOpts<E>,\n textLength?: PxAnimatable<number>,\n pathOverflow?: string,\n): E | null {\n const { glyphs, create = jsonElementFactory as PxCreateElement<E>, warnings } = opts;\n const sampler = pathD ? createPathSampler(pathD) : null;\n if (!sampler) { warnings?.push('textGlyphs: unparsable along-path geometry'); return null; }\n\n const soleFont = soleFontOf(glyphs);\n const { cells, width } = collectAlongPathCells(node, glyphs, soleFont, warnings);\n if (!cells.length) return toGroup(node, [], create);\n\n // x/dx → extra distance ALONG the path (added to startOffset); dy → perpendicular.\n const { along: alongOffset, perp } = alongPathNodeOffsets(node);\n\n // Both drivers as piecewise-linear tracks. textLength (lengthAdjust=spacing) scales\n // each glyph's position along the path so the run spans `textLength(t)` (glyph\n // outlines keep their natural size): distance(t) = startOffset(t) + k(t)·midBase.\n const soTrack = numTrackOf(startOffset);\n const tlTrack = numTrackOf(textLength);\n const kOf = (tl: number): number => (tl > 0 && width > 0) ? tl / width : 1;\n\n // pathOverflow 'clip' (open path): a glyph whose mid-advance point falls past an\n // end disappears (native <textPath> semantics), vs 'extend' (default) where the\n // sampler continues along the tangent. See svga.text.path-overflow.plan.md.\n const isClip = pathOverflow === 'clip' && !sampler.closed;\n\n if (soTrack.animated || tlTrack.animated) {\n // startOffset and/or textLength animate → each glyph slides along the path: its\n // own <path> with sampled translate+rotate keyframes (no merge). Per merged-\n // timeline interval both tracks are linear, so the glyph distance is linear too.\n const times = mergeTrackTimes(soTrack.times, tlTrack.times);\n const distOf = (c: AlongCell, t: number): number => alongOffset + soTrack.at(t) + kOf(tlTrack.at(t)) * c.midBase;\n const loop = soTrack.animated ? soTrack.loop : tlTrack.loop;\n return toGroup(node, buildAnimatedAlongPath(cells, sampler, distOf, times, loop, create, isClip, perp), create);\n }\n\n // Static (or single-keyframe): place + bake; glyphs sharing paint still merge.\n const k = kOf(tlTrack.at(0));\n const base = alongOffset + soTrack.at(0);\n const placeCells = isClip\n ? cells.filter(c => { const d = base + c.midBase * k; return d >= 0 && d <= sampler.totalLength; })\n : cells;\n const placements: Array<Placement> = placeCells.map(c => ({\n glyphD: c.glyphD, paint: c.paint,\n m: alongAffine(sampler, base + c.midBase * k, c.scale, c.widthEm, perp),\n }));\n return toGroup(node, buildPaths(placements, create, warnings), create);\n}\n\n/** A `PxAnimatable<number>` as a clamped piecewise-LINEAR sampler: constant for\n * static / absent / single-keyframe, keyframe-interpolated when animated — the same\n * linear-per-interval interpretation the along-path baking has always used. */\ninterface NumTrack { animated: boolean; times: Array<number>; loop?: unknown; at(t: number): number; }\n\nfunction numTrackOf(raw: PxAnimatable<number> | undefined): NumTrack {\n const r = readAnimatable<number>(raw);\n if (r.kind === ReadKind.Animated && r.keyframes.length >= 2) {\n const kfs = [...r.keyframes].sort((k1, k2) => (Number(k1.time) || 0) - (Number(k2.time) || 0));\n const times = kfs.map(kf => Number(kf.time) || 0);\n const vals = kfs.map(kf => Number(kf.value) || 0);\n return {\n animated: true, times, loop: r.loop,\n at(t: number): number {\n if (t <= times[0]) return vals[0];\n for (let i = 1; i < times.length; i++) {\n if (t <= times[i]) {\n const span = times[i] - times[i - 1];\n const f = span > 0 ? (t - times[i - 1]) / span : 1;\n return vals[i - 1] + f * (vals[i] - vals[i - 1]);\n }\n }\n return vals[vals.length - 1];\n },\n };\n }\n const v = r.kind === ReadKind.Animated ? (Number(r.keyframes[0]?.value) || 0)\n : r.kind === ReadKind.Static ? (Number(r.value) || 0) : 0;\n return { animated: false, times: [], at: () => v };\n}\n\n/** Sorted union of two keyframe-time lists (deduped) — the merged animation timeline. */\nfunction mergeTrackTimes(a: Array<number>, b: Array<number>): Array<number> {\n const all = [...a, ...b].sort((t1, t2) => t1 - t2);\n const out: Array<number> = [];\n for (const t of all) if (!out.length || t !== out[out.length - 1]) out.push(t);\n return out;\n}\n\n\n// Sampling density for a glyph's motion-path keyframes: aim for ~≤ this many\n// steps across the whole path so linear interpolation follows the curve.\nconst ALONG_PATH_MAX_STEPS = 48;\nconst ALONG_PATH_MAX_STEPS_PER_SEGMENT = 64;\n\nfunction roundN(v: number, n: number): number {\n const f = 10 ** n;\n return Math.round(v * f) / f;\n}\n\n/** Builds a separate glyph element per glyph, its outline baked centred at the\n * origin (mid-advance baseline) so `animate.transform` translate+rotate places\n * it along the path over time. `distOf` gives the glyph's along-path distance at a\n * time (startOffset(t) + textLength-scale(t)·midBase + x/dx — both drivers merged\n * into `times`); each interval is sub-sampled so the glyph tracks a curved path.\n * Interval interp is linear (per-keyframe easing shaping isn't reproduced — a v1\n * limitation). */\nfunction buildAnimatedAlongPath<E>(\n cells: Array<AlongCell>,\n sampler: PathSampler,\n distOf: (c: AlongCell, t: number) => number,\n times: Array<number>,\n loop: unknown,\n create: PxCreateElement<E>,\n isClip: boolean,\n perp = 0,\n): Array<E> {\n const step = Math.max(sampler.totalLength / ALONG_PATH_MAX_STEPS, 0.5);\n const onPath = (dist: number): boolean => dist >= 0 && dist <= sampler.totalLength;\n\n const out: Array<E> = [];\n for (const c of cells) {\n const centred: Affine = [c.scale, 0, 0, c.scale, -c.scale * (c.widthEm / 2), 0];\n const d = transformPathData(c.glyphD, centred);\n\n const sampleKf = (dist: number, time: number): TransformKeyframe => {\n const { x, y, angle } = sampler.sampleAtDistance(dist);\n const cos = Math.cos(angle), sin = Math.sin(angle);\n // dy shifts perpendicular to the path (left normal), in path units.\n return {\n time,\n value: {\n [TransformPart.Translate]: [roundN(x - perp * sin, 3), roundN(y + perp * cos, 3)],\n [TransformPart.Rotate]: roundN(angle * 180 / Math.PI, 3),\n },\n };\n };\n\n const kfs: Array<TransformKeyframe> = [];\n // Clip: opacity 1 while the glyph's centre is on the path, 0 off — the\n // sampling is dense (`step`), so the linear fade across one step reads as a\n // near-sharp pop (a robust stand-in for the hard native-<textPath> drop).\n const opKfs: Array<TransformKeyframe<number>> = [];\n const pushKf = (dist: number, time: number): void => {\n kfs.push(sampleKf(dist, time));\n if (isClip) opKfs.push({ time, value: onPath(dist) ? 1 : 0 });\n };\n\n pushKf(distOf(c, times[0]), times[0]);\n for (let k = 1; k < times.length; k++) {\n const t0 = times[k - 1], t1 = times[k];\n const d0 = distOf(c, t0), d1 = distOf(c, t1);\n const n = Math.min(ALONG_PATH_MAX_STEPS_PER_SEGMENT, Math.max(1, Math.ceil(Math.abs(d1 - d0) / step)));\n for (let s = 1; s <= n; s++) {\n const f = s / n;\n const t = t0 + f * (t1 - t0);\n pushKf(distOf(c, t), t);\n }\n }\n\n // Tangent angles come from atan2 and wrap at ±180° — crossing that seam (e.g.\n // the bottom of a circle) would otherwise lerp the ~358° long way between two\n // samples and visibly flip the glyph. Same fix as motion-path auto-orient.\n unwrapAutoOrientRotations(kfs);\n\n const transform: { keyframes: Array<TransformKeyframe>; loop?: unknown } = { keyframes: kfs };\n if (loop !== undefined) transform.loop = loop;\n const animate: { [k: string]: any } = { transform };\n // Only add an opacity track when it actually toggles (a glyph fully on-path\n // the whole time needs none).\n if (isClip && opKfs.some(k => k.value === 0)) {\n const op: { keyframes: Array<TransformKeyframe<number>>; loop?: unknown } = { keyframes: opKfs };\n if (loop !== undefined) op.loop = loop;\n animate.opacity = op;\n }\n\n out.push(create('path', { d, ...paintProps(c.paint), animate }, []));\n }\n return out;\n}\n\n\n// ── shared emit ───────────────────────────────────────────────────────────────\n\nfunction paintProps(paint: Paint): { [k: string]: any } {\n const p: { [k: string]: any } = {};\n if (paint.fill !== undefined) p.fill = paint.fill;\n if (paint.stroke !== undefined) p.stroke = paint.stroke;\n if (paint.strokeWidth !== undefined) p.strokeWidth = paint.strokeWidth;\n return p;\n}\n\n/** Merges placements sharing paint into baked `<path>` elements. */\nfunction buildPaths<E>(placements: Array<Placement>, create: PxCreateElement<E>, warnings?: Array<string>): Array<E> {\n if (!placements.length) { warnings?.push('textGlyphs: nothing to render'); return []; }\n\n const byPaint = new Map<string, { paint: Paint; d: string }>();\n for (const p of placements) {\n // Stable key across any paint value type (hex string, [r,g,b], gradient object).\n const key = JSON.stringify([p.paint.fill ?? null, p.paint.stroke ?? null, p.paint.strokeWidth ?? null]);\n const baked = transformPathData(p.glyphD, p.m);\n const entry = byPaint.get(key);\n if (entry) entry.d += baked;\n else byPaint.set(key, { paint: p.paint, d: baked });\n }\n\n const out: Array<E> = [];\n for (const { paint, d } of byPaint.values()) out.push(create('path', { d, ...paintProps(paint) }, []));\n return out;\n}\n\n/** Builds the `<g>` that replaces the `<text>`: keeps its transform / id /\n * animate / opacity, drops text-specific attributes, holds the glyph elements. */\nfunction toGroup<E>(node: PxNode, children: Array<E>, create: PxCreateElement<E>): E {\n const gProps: { [k: string]: any } = {};\n for (const k of Object.keys(node)) {\n if (k === 'type' || k === 'children' || TEXT_ATTR_KEYS.indexOf(k) !== -1) continue;\n gProps[k] = (node as { [k: string]: any })[k];\n }\n if (gProps.style && typeof gProps.style === 'object') {\n const style = { ...(gProps.style as Record<string, unknown>) };\n delete style['white-space'];\n if (Object.keys(style).length) gProps.style = style; else delete gProps.style;\n }\n return create('g', gProps, children);\n}\n\n\n// ── editor-facing convenience + pipeline adapters ──────────────────────────────\n\n/** Single entry the EDITOR calls: materialises a glyph `<text>` node into the\n * factory's element type, choosing along-path when `alongPath` is given. */\nexport function materialiseGlyphText<E = any>(\n node: PxNode,\n opts: GlyphMaterialiseOpts<E> & { alongPath?: { pathD?: string; startOffset?: PxAnimatable<number>; textLength?: PxAnimatable<number>; pathOverflow?: string } },\n): E | null {\n if (opts.alongPath) return materialiseGlyphTextAlongPath(node, opts.alongPath.pathD, opts.alongPath.startOffset, opts, opts.alongPath.textLength, opts.alongPath.pathOverflow);\n return materialiseGlyphTextHorizontal(node, opts);\n}\n\n/** Pipeline adapter (plain wire nodes) — `effects.text.useGlyphs`, horizontal. */\nexport function applyTextGlyphsEffect(node: PxNode, fx: PxTextEffect | undefined, ctx: ApplyContext): PxNode {\n if (!fx?.useGlyphs) return node;\n if (!ctx.glyphs) { ctx.warnings.push('textGlyphs: no definitions.glyphs — left as native <text>'); return node; }\n return materialiseGlyphTextHorizontal<PxNode>(node, { glyphs: ctx.glyphs, warnings: ctx.warnings });\n}\n\n/** Pipeline adapter (plain wire nodes) — glyph text along a referenced path. */\nexport function applyTextGlyphsAlongPath(node: PxNode, ctx: ApplyContext, pathD: string | undefined, startOffset: PxAnimatable<number> | undefined, textLength?: PxAnimatable<number>, pathOverflow?: string): PxNode | null {\n if (!ctx.glyphs) { ctx.warnings.push('textGlyphs: no definitions.glyphs'); return null; }\n return materialiseGlyphTextAlongPath<PxNode>(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength, pathOverflow);\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\nimport type { PxAnimatable, PxBezierPath, PxKeyframe, PxLoop, PxNode, Vec2, _PxTrimPathEffect } from '../PxAnimatorTypes';\nimport { bezier2D_arcLengthLUT, bezierToSvgPath, clamp } from '../PxAnimatorUtil';\nimport { parseSvgPathToBezier } from '../PxDefinitions';\nimport { ReadKind, readAnimatable, type ReadPart } from './transformParts';\nimport type { ApplyContext } from './types';\n\n\n/**\n * Applies a `trimPath` effect: collects every descendant shape leaf, slices each\n * leaf's `d` into sub-paths, measures each in px, and converts the parametric\n * `offset` + `range` to per-sub-path `stroke-dasharray` / `stroke-dashoffset` (and\n * `opacity` for empty-range hide).\n *\n * - `trimAllAsOne` chains every sub-path's length end-to-end so the\n * window slides across siblings (a flag of TRUE keeps a single trim window,\n * chaining the sub-paths' `totalLength`).\n * - Animated `offset` becomes `animate.strokeDashoffset.keyframes`;\n * animated `range` becomes `animate.strokeDasharray.keyframes`.\n * - The dasharray emits a repeated pattern so any dashoffset shift lands on a\n * valid dash segment.\n * - Empty-range moments are hidden with `stroke-opacity` 0 (STROKE only — the\n * fill stays visible).\n *\n * COLLAPSE: when the trim host is itself a single shape leaf with exactly ONE\n * sub-path, the trim materialises directly onto that leaf's own `<path>` (no\n * `<g>` split). Multi-subpath (or group/descendant) trims still expand to\n * `<g>` + one bare `<path>` per sub-path.\n */\nexport function applyTrimPathEffect(\n node: PxNode,\n trimPath: _PxTrimPathEffect | undefined,\n isCombinedShape: boolean | undefined,\n ctx: ApplyContext,\n): PxNode {\n if (!trimPath) return node;\n\n const trimAllAsOne = !!trimPath.trimAllAsOne;\n\n // Pass 1a — collect leaves with subpath lengths (no chain offset yet).\n const leafEntries: Array<LeafEntry> = [];\n const measure = (n: PxNode): void => {\n if (Array.isArray(n.children) && n.children.length > 0) {\n for (const ch of n.children) measure(ch);\n return;\n }\n const d = typeof n.d === 'string' ? n.d : shapeToPathD(n);\n if (d === undefined) return;\n const subpaths = parseSvgPathToBezier(d);\n if (!subpaths.length) return;\n const entry: LeafEntry = { leaf: n, subpaths: [] };\n for (const sp of subpaths) {\n const lengthPx = pxBezierPathLength(sp);\n entry.subpaths.push({ subpath: sp, lengthPx, startOffsetPx: 0 });\n }\n leafEntries.push(entry);\n };\n measure(node);\n\n if (!leafEntries.length) return node;\n\n // Pass 1b — assign chain offsets.\n // `trimAllAsOne=true`: walk leaves in REVERSE doc order so the chain\n // starts at the visually-topmost leaf. Within each leaf, subpaths keep their\n // `d`-attribute order — without the reverse, a multi-leaf group emits the\n // leaves' dashoffsets SWAPPED, which renders the visible trim window on the\n // wrong subpath.\n // `trimAllAsOne=false`: each subpath gets its own independent chain\n // (offset 0), so the leaf iteration order doesn't matter.\n let acc = 0;\n const iterOrder = trimAllAsOne ? [...leafEntries].reverse() : leafEntries;\n for (const entry of iterOrder) {\n for (const sp of entry.subpaths) {\n if (!trimAllAsOne) acc = 0;\n sp.startOffsetPx = acc;\n acc += sp.lengthPx;\n }\n }\n\n const chainLengthPx = acc;\n if (trimAllAsOne && chainLengthPx < 0.001) return node;\n\n // Offset / range readers. Range is post-processed for cross-overs so the\n // dasharray emitter never sees `range[0] > range[1]`.\n //\n // Defaults: `offset = 0` and `range = [0, 1]`. Treating absent\n // inputs as those statics (rather than skipping the emit) keeps the\n // `+ SMALL_PADDING_PX` shift active — that 1-px buffer is what stops\n // `stroke-linecap=\"round\"` from painting a round dot at the zero-length\n // first dash. Missing-emit means no `stroke-dashoffset`, no shift, and\n // the dot reappears.\n const offsetReadRaw = readAnimatable<number>(trimPath.offset);\n const offsetRead: ReadPart<number> = offsetReadRaw.kind === ReadKind.Absent\n ? { kind: ReadKind.Static, value: 0 }\n : offsetReadRaw;\n const rangeReadRaw = readRangeWithCrossings(trimPath.range);\n const rangeRead: ReadPart<Vec2> = rangeReadRaw.kind === ReadKind.Absent\n ? { kind: ReadKind.Static, value: [0, 1] }\n : rangeReadRaw;\n\n const offsetValues = readScalarValues(offsetRead);\n const minOffset = offsetValues.length ? Math.min(...offsetValues) : 0;\n const maxOffset = offsetValues.length ? Math.max(...offsetValues) : 0;\n const minMaxOffset: [number, number] = [minOffset, maxOffset];\n\n // COLLAPSE: the trim host is a single shape leaf with exactly one sub-path\n // → no `<g>` split. The trim stroke attrs go directly on the leaf's own\n // `<path>` (its `fill` / `stroke` / `transform` / `id` stay put).\n if (leafEntries.length === 1 && leafEntries[0].leaf === node && leafEntries[0].subpaths.length === 1) {\n const entry = leafEntries[0];\n const sp = entry.subpaths[0];\n const pathLengthPx = trimAllAsOne ? chainLengthPx : sp.lengthPx;\n if (pathLengthPx < 0.001) return node;\n const startOffsetPct = trimAllAsOne ? sp.startOffsetPx / pathLengthPx : 0;\n return collapseLeafWithTrim(entry.leaf, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead);\n }\n\n // Pass 2 — walk the tree and replace each measured leaf with a <g>\n // containing one bare <path> per sub-path.\n const replacements = new Map<PxNode, PxNode>();\n for (const entry of leafEntries) {\n const newChildren: Array<PxNode> = [];\n for (const sp of entry.subpaths) {\n const pathLengthPx = trimAllAsOne ? chainLengthPx : sp.lengthPx;\n if (pathLengthPx < 0.001) continue;\n const startOffsetPct = trimAllAsOne ? sp.startOffsetPx / pathLengthPx : 0;\n newChildren.push(...buildSubpathNodes(entry.leaf, sp.subpath, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead, ctx));\n }\n replacements.set(entry.leaf, wrapLeafAsGroup(entry.leaf, newChildren));\n }\n\n const swap = (n: PxNode): PxNode => {\n const r = replacements.get(n);\n if (r) return r;\n if (Array.isArray(n.children) && n.children.length > 0) {\n return { ...n, children: n.children.map(swap) };\n }\n return n;\n };\n return swap(node);\n}\n\n\n// ============================================================================\n// Leaf -> sub-path table\n// ============================================================================\n\ninterface LeafEntry {\n leaf: PxNode;\n subpaths: Array<{ subpath: PxBezierPath; lengthPx: number; startOffsetPx: number }>;\n}\n\n/** Wraps a leaf as a `<g>` with new sub-path children. Outer attrs of the leaf\n * move onto the wrapper (so its `id` / style anchors are preserved); `d`,\n * `strokeDasharray`, `strokeDashoffset`, and `effects` are stripped. */\nfunction wrapLeafAsGroup(leaf: PxNode, children: Array<PxNode>): PxNode {\n const wrapper: PxNode = { ...leaf, type: 'g', children };\n delete wrapper.d;\n delete wrapper.strokeDasharray;\n delete wrapper.strokeDashoffset;\n delete wrapper.effects;\n return wrapper;\n}\n\n\n// ============================================================================\n// Sub-path node builder\n// ============================================================================\n\nfunction buildSubpathNodes(\n leaf: PxNode,\n subpath: PxBezierPath,\n pathLengthPx: number,\n startOffsetPct: number,\n minMaxOffset: [number, number],\n offsetRead: ReadPart<number>,\n rangeRead: ReadPart<Vec2>,\n ctx: ApplyContext,\n): Array<PxNode> {\n const offsetToDashOffset = makeOffsetToDashOffset(startOffsetPct, pathLengthPx, minMaxOffset);\n const rangeToDasharray = makeRangeToDasharray(pathLengthPx, minMaxOffset);\n\n const dashOffsetAttr = computeAnimAttr(offsetRead, offsetToDashOffset);\n const dashArrayAttr = computeAnimAttr(rangeRead, rangeToDasharray);\n const strokeOpacityAttr = computeOpacityFromRange(rangeRead);\n\n const dStr = bezierToSvgPath(subpath);\n\n // Bare sub-path under the trim wrapper — fill / stroke / stroke-width are\n // inherited from the wrapper <g>. The empty-range hide uses `stroke-opacity`\n // (STROKE only), so the fill stays visible without a fill-only twin.\n const base = makeBareSubpath(dStr);\n applyAttr(base, 'strokeDasharray', dashArrayAttr);\n applyAttr(base, 'strokeDashoffset', dashOffsetAttr);\n applyAttr(base, 'strokeOpacity', strokeOpacityAttr);\n\n return [base];\n}\n\n/** Collapsed single-subpath form: the trim host stays a single `<path>` (its own\n * `fill` / `stroke` / `transform` / `id` preserved); the trim stroke attrs are\n * applied directly. */\nfunction collapseLeafWithTrim(\n leaf: PxNode,\n pathLengthPx: number,\n startOffsetPct: number,\n minMaxOffset: [number, number],\n offsetRead: ReadPart<number>,\n rangeRead: ReadPart<Vec2>,\n): PxNode {\n const offsetToDashOffset = makeOffsetToDashOffset(startOffsetPct, pathLengthPx, minMaxOffset);\n const rangeToDasharray = makeRangeToDasharray(pathLengthPx, minMaxOffset);\n\n const node: PxNode = { ...leaf };\n delete node.effects;\n applyAttr(node, 'strokeDasharray', computeAnimAttr(rangeRead, rangeToDasharray));\n applyAttr(node, 'strokeDashoffset', computeAnimAttr(offsetRead, offsetToDashOffset));\n applyAttr(node, 'strokeOpacity', computeOpacityFromRange(rangeRead));\n return node;\n}\n\n/** Fresh `<path>` carrying only the sub-path geometry. Presentation attrs\n * (`fill`, `stroke`, `stroke-width`, `transform`, `id`, …) stay on the wrapper\n * `<g>` and are inherited — bare `<path>`s under a single attrs-bearing `<g>`. */\nfunction makeBareSubpath(dStr: string): PxNode {\n return { type: 'path', d: dStr };\n}\n\n\n// ============================================================================\n// Math\n// ============================================================================\n\nconst SMALL_PADDING_PX = 1;\n\n/** Produces a px dashoffset from a parametric offset. */\nfunction makeOffsetToDashOffset(\n startOffsetPct: number,\n pathLengthPx: number,\n minMaxOffset: [number, number],\n): (offsetVal: number) => number {\n const [minIdx] = getOffsetIndexRange(minMaxOffset);\n return offsetVal => pathLengthPx * (-offsetVal - minIdx + startOffsetPct) + SMALL_PADDING_PX;\n}\n\n/** Produces a px dash pattern of the form `[0, gap, dash, gap, dash, ..., gap]`\n * repeated so the offset can wrap. */\nfunction makeRangeToDasharray(\n pathLengthPx: number,\n minMaxOffset: [number, number],\n): (rangeVal: Vec2) => Array<number> {\n const [minIdx, maxIdx] = getOffsetIndexRange(minMaxOffset);\n const repeats = maxIdx - minIdx + 1;\n return (rangeVal: Vec2) => {\n const a = clamp(rangeVal[0], 0, 1);\n const b = clamp(rangeVal[1], 0, 1);\n const minR = Math.min(a, b);\n const maxR = Math.max(a, b);\n const out: Array<number> = [0];\n let gap = SMALL_PADDING_PX;\n for (let i = 0; i < repeats; i++) {\n out.push(gap + minR * pathLengthPx); // GAP\n out.push((maxR - minR) * pathLengthPx); // DASH\n gap = (1 - maxR) * pathLengthPx;\n }\n out.push(gap + SMALL_PADDING_PX); // closing GAP\n return out;\n };\n}\n\n/** Floor/ceil of the negated min/max offset → integer dash-repeat index range. */\nfunction getOffsetIndexRange(minMaxOffset: [number, number]): [number, number] {\n return [\n Math.floor(Math.min(-minMaxOffset[0], -minMaxOffset[1])),\n Math.ceil(Math.max(-minMaxOffset[0], -minMaxOffset[1])),\n ];\n}\n\n\n// ============================================================================\n// Animatable plumbing\n// ============================================================================\n\ntype AnimAttrResult<TOut> =\n | { kind: ReadKind.Static; value: TOut }\n | { kind: ReadKind.Animated; keyframes: Array<PxKeyframe>; loop?: PxLoop | boolean }\n | undefined;\n\nfunction readScalarValues(r: ReadPart<number>): Array<number> {\n if (r.kind === ReadKind.Absent) return [];\n if (r.kind === ReadKind.Static) return [r.value];\n const out: Array<number> = [];\n for (const kf of r.keyframes) {\n const v = kf.value ?? kf.v;\n if (typeof v === 'number') out.push(v);\n }\n return out;\n}\n\nfunction computeAnimAttr<TIn, TOut>(read: ReadPart<TIn>, map: (v: TIn) => TOut): AnimAttrResult<TOut> {\n if (read.kind === ReadKind.Absent) return undefined;\n if (read.kind === ReadKind.Static) return { kind: ReadKind.Static, value: map(read.value) };\n return {\n kind: ReadKind.Animated,\n keyframes: read.keyframes.map(kf => ({\n time: kf.time ?? kf.t ?? 0,\n value: map((kf.value ?? kf.v) as TIn),\n easing: kf.easing ?? kf.e,\n })),\n loop: read.loop,\n };\n}\n\nfunction applyAttr<T>(node: PxNode, attrName: string, attr: AnimAttrResult<T>): void {\n if (!attr) return;\n if (attr.kind === ReadKind.Static) {\n node[attrName] = attr.value;\n return;\n }\n const prevAnimate = node.animate && typeof node.animate === 'object' && !Array.isArray(node.animate) ? node.animate : undefined;\n const animate: Record<string, any> = { ...(prevAnimate || {}) };\n const block: { keyframes: Array<PxKeyframe>, loop?: PxLoop | boolean } = { keyframes: attr.keyframes };\n if (attr.loop !== undefined) block.loop = attr.loop;\n animate[attrName] = block;\n node.animate = animate;\n // ALSO write the first kf's value as a STATIC attribute. The animator only\n // pushes the animated value to the DOM on its first rAF tick — if a caller\n // snapshots the DOM in the window between `play()` and that first tick\n // (e.g. visual-tests live-mode sample at t=0), the element renders with\n // DEFAULT stroke styling (no dash, full opacity), which would expose the\n // entire stroked path even when the t=0 kf says it should be hidden /\n // mostly-dashed. Mirroring the SVG convention of \"static baseline +\n // animation\" makes the pre-tick DOM render match the kf-at-time-0 value.\n const firstKf = attr.keyframes[0];\n if (firstKf && (firstKf.value ?? (firstKf as any).v) !== undefined) {\n node[attrName] = firstKf.value ?? (firstKf as any).v;\n }\n}\n\n/** Width (ms) of the opacity transition emitted at each hide↔show boundary\n * (one SVGA frame = 10 ms at the 100 fps SVGA grid). */\nconst OPACITY_STEP_MS = 10;\n\n/** Empty-range opacity (hide when `startEnd[0] === startEnd[1]`).\n * Static: single 0 if hide always; undefined otherwise.\n * Animated: step-jump kfs at each hide↔show transition (~one SVGA frame\n * wide so the renderer doesn't briefly show the stroke between an empty\n * range and the first non-empty kf at wall-clock t≈0). */\nfunction computeOpacityFromRange(rangeRead: ReadPart<Vec2>): AnimAttrResult<number> {\n const hide = (v: Vec2): boolean => v[0] === v[1];\n\n if (rangeRead.kind === ReadKind.Absent) return undefined;\n if (rangeRead.kind === ReadKind.Static) return hide(rangeRead.value) ? { kind: ReadKind.Static, value: 0 } : undefined;\n\n const kfs = rangeRead.keyframes;\n let anyHide = false;\n let allHide = true;\n for (const kf of kfs) {\n if (hide((kf.value ?? kf.v) as Vec2)) anyHide = true;\n else allHide = false;\n }\n if (!anyHide) return undefined;\n if (allHide) return { kind: ReadKind.Static, value: 0 };\n\n // Prev/next-aware emitter — only inserts kfs at the transitions to keep the\n // wire compact.\n const out: Array<PxKeyframe> = [];\n for (let i = 0; i < kfs.length; i++) {\n const kf = kfs[i];\n const prevKf = i > 0 ? kfs[i - 1] : undefined;\n const nextKf = i < kfs.length - 1 ? kfs[i + 1] : undefined;\n const t = kf.time ?? kf.t ?? 0;\n const thisHide = hide((kf.value ?? kf.v) as Vec2);\n const prevHide = prevKf ? thisHide && hide((prevKf.value ?? prevKf.v) as Vec2) : thisHide;\n const nextHide = nextKf ? thisHide && hide((nextKf.value ?? nextKf.v) as Vec2) : thisHide;\n\n if (prevHide && !nextHide) {\n out.push({ time: t, value: 0 });\n out.push({ time: t + OPACITY_STEP_MS, value: 1 });\n } else if (!prevHide && nextHide) {\n out.push({ time: t - OPACITY_STEP_MS, value: 1 });\n out.push({ time: t, value: 0 });\n }\n }\n if (out.length <= 1) return undefined;\n return { kind: ReadKind.Animated, keyframes: out };\n}\n\n\n// ============================================================================\n// Range cross-over\n// ============================================================================\n\ninterface SimpleKf { time: number; value: Vec2; easing?: any; }\n\n/** Reads `range` and, when the kf sequence has `value[0] > value[1]` anywhere,\n * inserts crossing-point keyframes (bisection-located) and swaps any\n * remaining reversed kfs so every emitted range satisfies `range[0] ≤ range[1]`. */\nfunction readRangeWithCrossings(raw: PxAnimatable<Vec2> | undefined): ReadPart<Vec2> {\n const r = readAnimatable<Vec2>(raw);\n if (r.kind !== ReadKind.Animated) return r;\n\n const kfs: Array<SimpleKf> = r.keyframes.map(kf => ({\n time: kf.time ?? kf.t ?? 0,\n value: (kf.value ?? kf.v) as Vec2,\n easing: kf.easing ?? kf.e,\n }));\n\n const hasReverse = kfs.some(kf => kf.value[0] > kf.value[1]);\n if (!hasReverse) {\n return {\n kind: ReadKind.Animated,\n keyframes: kfs.map(kf => ({ time: kf.time, value: kf.value, easing: kf.easing })),\n };\n }\n\n const crossingTimes: Array<number> = [];\n for (let i = 1; i < kfs.length; i++) {\n const prev = kfs[i - 1];\n const cur = kfs[i];\n const dPrev = prev.value[1] - prev.value[0];\n const dCur = cur.value[1] - cur.value[0];\n if (dPrev * dCur < 0) {\n const t = bisectionForRangeCrossing(prev, cur);\n if (t !== null && t > prev.time && t < cur.time) {\n crossingTimes.push(Math.round(t));\n }\n }\n }\n const uniqueTs = Array.from(new Set(crossingTimes)).sort((a, b) => a - b);\n\n const out: Array<SimpleKf> = [];\n let j = 0;\n for (const kf of kfs) {\n while (j < uniqueTs.length && uniqueTs[j] < kf.time) {\n const t = uniqueTs[j++];\n const v = interpolateRangeAt(kfs, t);\n const m = (v[0] + v[1]) / 2;\n out.push({ time: t, value: [m, m] });\n }\n const v: Vec2 = kf.value[0] > kf.value[1] ? [kf.value[1], kf.value[0]] : kf.value;\n out.push({ time: kf.time, value: v, easing: kf.easing });\n }\n while (j < uniqueTs.length) {\n const t = uniqueTs[j++];\n const v = interpolateRangeAt(kfs, t);\n const m = (v[0] + v[1]) / 2;\n out.push({ time: t, value: [m, m] });\n }\n\n return { kind: ReadKind.Animated, keyframes: out };\n}\n\nfunction bisectionForRangeCrossing(prev: SimpleKf, cur: SimpleKf): number | null {\n const f = (t: number): number => {\n const a = (t - prev.time) / (cur.time - prev.time);\n const v0 = prev.value[0] + (cur.value[0] - prev.value[0]) * a;\n const v1 = prev.value[1] + (cur.value[1] - prev.value[1]) * a;\n return v1 - v0;\n };\n let lo = prev.time, hi = cur.time;\n let fLo = f(lo);\n if (fLo === 0) return lo;\n const fHi = f(hi);\n if (fHi === 0) return hi;\n if (fLo * fHi > 0) return null;\n for (let i = 0; i < 100; i++) {\n const mid = (lo + hi) / 2;\n const fMid = f(mid);\n if (fMid === 0 || Math.abs(hi - lo) < 0.0001) return mid;\n if (fLo * fMid < 0) { hi = mid; }\n else { lo = mid; fLo = fMid; }\n }\n return (lo + hi) / 2;\n}\n\nfunction interpolateRangeAt(kfs: Array<SimpleKf>, t: number): Vec2 {\n if (t <= kfs[0].time) return kfs[0].value;\n if (t >= kfs[kfs.length - 1].time) return kfs[kfs.length - 1].value;\n for (let i = 1; i < kfs.length; i++) {\n if (t <= kfs[i].time) {\n const prev = kfs[i - 1];\n const cur = kfs[i];\n const a = (t - prev.time) / (cur.time - prev.time);\n return [\n prev.value[0] + (cur.value[0] - prev.value[0]) * a,\n prev.value[1] + (cur.value[1] - prev.value[1]) * a,\n ];\n }\n }\n return kfs[kfs.length - 1].value;\n}\n\n\n// ============================================================================\n// Geometry helpers\n// ============================================================================\n\n/** Total arc length of a `PxBezierPath` (sum of per-segment LUT lengths). */\nfunction pxBezierPathLength(path: PxBezierPath): number {\n const v = path.v;\n if (!v || v.length < 2) return 0;\n let total = 0;\n for (let i = 0; i < v.length - 1; i++) {\n total += segmentLength(path, i, i + 1);\n }\n if (path.c && v.length > 1) {\n total += segmentLength(path, v.length - 1, 0);\n }\n return total;\n}\n\nfunction segmentLength(path: PxBezierPath, from: number, to: number): number {\n const v = path.v;\n const p0 = v[from] as [number, number];\n const p3 = v[to] as [number, number];\n const p1 = (path.o?.[from] ?? p0) as [number, number];\n const p2 = (path.i?.[to] ?? p3) as [number, number];\n const lut = bezier2D_arcLengthLUT(p0, p1, p2, p3);\n return lut.ds[lut.ds.length - 1];\n}\n\n/**\n * Cubic-bezier control-point ratio for a quarter arc — the standard circle\n * approximation (max radial error ≈ 0.02%, far below stroke-dash precision).\n */\nconst ARC_KAPPA = 0.5522847498307936;\n\n/**\n * A primitive shape -> outline path `d`, for shapes that carry no `d` of their own.\n * Returns undefined for unsupported types.\n *\n * Start point and winding MATCH the shape's own SVG parameterisation, because the\n * measured length feeds a `stroke-dasharray` that the browser then walks along that\n * very parameterisation — a mismatched start would put the visible trim window in\n * the wrong place.\n *\n * - `<rect>` from `(x+w, y)`, clockwise. Emits the explicit closing-line\n * vertex (`L x0,y0`) before `z`.\n * - `<ellipse>`/`<circle>` from `(cx+rx, cy)` clockwise as four cubic quarters — the\n * SVG-spec equivalent path, which the UA also uses for dashing.\n */\nfunction shapeToPathD(node: PxNode): string | undefined {\n if (node.type === 'rect') {\n const x = Number(node.x ?? 0), y = Number(node.y ?? 0);\n const w = Number(node.width ?? 0), h = Number(node.height ?? 0);\n return 'M' + (x + w) + ',' + y +\n 'L' + (x + w) + ',' + (y + h) +\n 'L' + x + ',' + (y + h) +\n 'L' + x + ',' + y +\n 'L' + (x + w) + ',' + y + 'z';\n }\n\n if (node.type === 'ellipse' || node.type === 'circle') {\n const cx = Number(node.cx ?? 0), cy = Number(node.cy ?? 0);\n const rx = node.type === 'circle' ? Number(node.r ?? 0) : Number(node.rx ?? 0);\n const ry = node.type === 'circle' ? Number(node.r ?? 0) : Number(node.ry ?? 0);\n if (!(rx > 0) || !(ry > 0)) return undefined;\n const kx = rx * ARC_KAPPA, ky = ry * ARC_KAPPA;\n const c = (x1: number, y1: number, x2: number, y2: number, x: number, y: number) =>\n 'C' + x1 + ',' + y1 + ' ' + x2 + ',' + y2 + ' ' + x + ',' + y;\n return 'M' + (cx + rx) + ',' + cy +\n c(cx + rx, cy + ky, cx + kx, cy + ry, cx, cy + ry) +\n c(cx - kx, cy + ry, cx - rx, cy + ky, cx - rx, cy) +\n c(cx - rx, cy - ky, cx - kx, cy - ry, cx, cy - ry) +\n c(cx + kx, cy - ry, cx + rx, cy - ky, cx + rx, cy) + 'z';\n }\n\n return undefined;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\n/**\n * Lightweight, dependency-free applier for \"player-effects\" SVGA JSON.\n *\n * Input: the JSON produced by `SvgaJsonWithPlayerEffectsSerialisationUtil`, where\n * structure-creating effects are left UN-applied on `node.effects`. This module\n * reads those effects and MATERIALISES them into a plain node tree (extra `<g>`\n * wrappers, copies, mask defs) that renders identically to the heavy editor path.\n *\n * Design goals (intentional): minimal, transparent, no merging/optimisation. It\n * is fine to emit more nodes than strictly necessary — the only contract is \"same\n * result on screen\". Each effect lives in its own file; this module only wires\n * them into the recursion. Nothing here imports outside `effects/`, so the whole\n * folder can move into the Player codebase verbatim.\n */\n\nimport { identifyContentRefTargets, splitForContentRef } from './contentRefSplit';\nimport { applyFillGradientEffect, applyStrokeGradientEffect } from './gradientEffect';\nimport { applyClipPathEffect } from './clipPathEffect';\nimport { applyMaskedByEffect, collectMaskAncestorChains } from './maskedByEffect';\nimport { applyRefAndTransformationEffect, applyRefHref } from './refEffect';\nimport { applyRepeaterEffect } from './repeaterEffect';\nimport { applyAllRetimeEffects } from './retimeEffect';\nimport { applyTextPathEffect } from './textPathEffect';\nimport { applyTextGlyphsAlongPath, applyTextGlyphsEffect } from './textGlyphsEffect';\nimport { applyTrimPathEffect } from './trimPathEffect';\nimport { getAnimatorConfig, getDefs, PxAnimatorEngine, PxAnimatorMode } from '../PxAnimatorTypes';\nimport type { PxNode } from '../PxAnimatorTypes';\nimport type { ApplyContext, ApplyResult } from './types';\nimport { clone, genId, indexById, spliceDefs } from './util';\n\nexport type { PxNode } from '../PxAnimatorTypes';\nexport type { ApplyResult } from './types';\n\n\n/**\n * Applies all player-effects in `root` and returns a materialised copy plus any\n * generated <defs> nodes, warnings and errors. `root` is not mutated.\n *\n * Two passes:\n * 1. `applyPlayerEffects_exceptRetime` — materialises every effect except retime.\n * 2. `applyPlayerEffects_retime` — applies retime, cloning the NOW-materialised\n * subtrees so retimed `<use>`s see the same wrappers/animations the heavy\n * editor path would produce.\n *\n * Pre-pass identifies every element that is the target of a `<use>` with\n * `ref:{type:'content'}` and allocates a fresh \"inner\" id for it; pass 1 then\n * splits those sources into outer-translate + inner-content layers so the use\n * can target the inner layer.\n */\nexport function applyPlayerEffects(root: PxNode): ApplyResult {\n const ctx: ApplyContext = {\n defs: [], warnings: [], errors: [],\n idMap: new Map(), nextId: 0,\n contentRefInnerIds: new Map(),\n maskAncestorChains: new Map(),\n // Resolved engine: `frames` ONLY when explicitly set; auto/webapi/unset →\n // webapi (we're not 100% sure it's frames, and CSS/WAAPI need the inline form).\n engine: getAnimatorConfig(root)?.mode === PxAnimatorMode.frames\n ? PxAnimatorEngine.frames\n : PxAnimatorEngine.webapi,\n glyphs: getDefs(root)?.glyphs,\n };\n\n const working = clone(root);\n indexById(working, ctx.idMap);\n identifyContentRefTargets(working, ctx, () => genId(ctx, 'inner'));\n collectMaskAncestorChains(working, ctx);\n\n const afterPass1 = applyPlayerEffects_exceptRetime(working, ctx);\n const out = applyPlayerEffects_retime(afterPass1, ctx);\n spliceDefs(out, ctx.defs);\n\n return { root: out, defs: ctx.defs, warnings: ctx.warnings, errors: ctx.errors };\n}\n\n/**\n * Pass 1 — materialise every effect except retime. Retime is preserved on the\n * original (now wrapped-inner) node so pass 2 can find and apply it.\n *\n * After wrapping, the outer-most wrapper for a node with `originalId` is written\n * back into `ctx.idMap` so retime's clone target picks up the FULL materialised\n * subtree, not the bare un-wrapped original.\n *\n * If the node is a content-ref target, `splitForContentRef` re-shapes the\n * materialised result into outer-translate + inner-rest layers — the outer keeps\n * the original id, the inner gets the pre-allocated inner id so the `<use>` can\n * target it.\n */\nfunction applyPlayerEffects_exceptRetime(node: PxNode, ctx: ApplyContext): PxNode {\n if (node.children) node.children = node.children.map(child => applyPlayerEffects_exceptRetime(child, ctx));\n\n const fx = node.effects;\n const originalId = typeof node.id === 'string' ? node.id : undefined;\n const innerIdForContentRef = originalId ? ctx.contentRefInnerIds.get(originalId) : undefined;\n\n if (!fx && !innerIdForContentRef) return node;\n\n const { transformation, repeater, maskedBy, clipPath, trimPath, clone: cloneFx, fillGradient, strokeGradient, textPath, text } = fx ?? {};\n const isCombinedShape = fx?.isCombinedShape;\n if (fx) delete node.effects;\n\n let n = node;\n // Glyph text: replace the <text>/<tspan> subtree with baked <path> outlines\n // BEFORE any wrapper. Along-path glyphs place+rotate each glyph to the\n // referenced path's tangent; plain glyphs lay out horizontally.\n let consumedByGlyphs = false;\n if (text?.useGlyphs) {\n if (textPath) {\n // Path geometry is INLINE (`textPath.path`) — no `<path>` def lookup.\n const pathD = typeof textPath.path === 'string' ? textPath.path : undefined;\n // textLength passes through as a full PxAnimatable — static stretches the\n // run; animated re-spaces the glyphs over time (same per-glyph sampled\n // keyframe machinery as animated startOffset).\n const glyphed = applyTextGlyphsAlongPath(n, ctx, pathD, textPath.startOffset, textPath.textLength, textPath.pathOverflow);\n if (glyphed) { n = glyphed; consumedByGlyphs = true; } // native textPath NOT applied\n } else {\n n = applyTextGlyphsEffect(n, text, ctx);\n consumedByGlyphs = true;\n }\n }\n // textPath wraps the host's own children in a `<textPath>` — must run BEFORE any\n // structural wrapper (trim/repeater/mask) so the wrapping happens on the un-cloned\n // content first. Skipped when glyphs consumed it.\n if (!consumedByGlyphs) n = applyTextPathEffect(n, textPath, ctx);\n // Paint-gradient defs are minted FIRST, before any structural wrapper —\n // the gradient effect sits on the innermost element (alongside its `fill`\n // / `stroke` body attrs), so it must materialise before trim/repeater/\n // mask wrap around it. `<linearGradient>` defs themselves don't get\n // wrapped — they live in `ctx.defs` independent of the structure walk.\n n = applyFillGradientEffect(n, fillGradient, ctx);\n n = applyStrokeGradientEffect(n, strokeGradient, ctx);\n n = applyTrimPathEffect(n, trimPath, isCombinedShape, ctx); // innermost shape\n n = applyRepeaterEffect(n, repeater, ctx);\n n = applyMaskedByEffect(n, maskedBy, transformation, ctx); // mask sits on inner element\n n = applyClipPathEffect(n, clipPath, ctx); // clip-path ref on the element\n\n if (innerIdForContentRef) {\n // This node is the SOURCE of a content-ref `<use>` → split into\n // outer-translate + inner-rest + bare element so the use can target the\n // inner layer. But it may ALSO be a content-ref CONSUMER itself (a\n // `<use>` that both references content and is referenced — the nested\n // case): rewrite its OWN ref href first so the split moves a resolved\n // body inward, not the dangling editor-side content id.\n applyRefHref(n, cloneFx, ctx);\n n = splitForContentRef(n, transformation, originalId!, innerIdForContentRef, ctx);\n } else {\n n = applyRefAndTransformationEffect(n, cloneFx, transformation, ctx);\n }\n\n // Hand off the retime slice to pass 2 (keeps it nested under `clone`). The\n // ref part (type/baseId) was consumed above.\n if (cloneFx?.retime) node.effects = { clone: { retime: cloneFx.retime } };\n if (originalId) ctx.idMap.set(originalId, n); // outer wrapper is the clone target\n return n;\n}\n\n/** Pass 2 — apply retime to every `<use>` that carries it. Follows the\n * materialised `<use>.href` (not the editor-side `retime.baseId`). */\nfunction applyPlayerEffects_retime(node: PxNode, ctx: ApplyContext): PxNode {\n applyAllRetimeEffects(node, ctx);\n return node;\n}\n\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n/**\n * Single-call materialisation pipeline.\n *\n * Runs the full sequence of document-level transformations that turn the\n * wire-format `PxAnimatedSvgDocument` into a flat tree any renderer can\n * consume. The player itself calls this from `createAnimatorImpl`; the same\n * function is exported for the Editor (or any external caller) so the\n * Editor's flat-export path is GUARANTEED to be byte-identical to what the\n * player sees internally — no parallel pipeline to drift.\n *\n * 1. `applyPlayerEffects` — `node.effects` (ref / transformation / repeater /\n * maskedBy / trimPath / retime) materialised into wrappers, defs, clones.\n * 2. `materialiseInternalLoopsInTree` — every `propAnim.loop` expanded into\n * repeated keyframes filling the duration.\n * 3. `materialiseMotionPathsInTree` — `transform` kfs with tangents +\n * `autoOrient` flattened into sampled `{translate, rotate}` kfs. Only\n * for `engine === webapi` — frames-mode keeps the parametric form and\n * evaluates per frame for max spatial fidelity.\n * 4. `materialiseAnimatedUseInstances` — `<use>` referencing an animated\n * subtree replaced with a `<g>` carrying a deep clone (fresh ids).\n * Only for `engine === webapi` — frames-mode updates source attrs\n * per frame, which propagate through `<use>` shadow trees natively.\n *\n * Immutable: input doc is never mutated. Steps that didn't apply (the engine\n * gating or \"nothing to do\" early-outs) return the input by reference.\n */\n\nimport { applyPlayerEffects } from './effects/PlayerEffectsUtil';\nimport { DEFAULT_DURATION_MS } from './PxAnimatorUtil';\nimport { materialiseInternalLoopsInTree } from './PxDefinitions';\nimport { materialiseMotionPathsInTree } from './PxMotionPath';\nimport type { MotionPathMaterialisationOptions } from './PxMotionPath';\nimport { getAnimatorConfig, PxAnimatorEngine } from './PxAnimatorTypes';\nimport type { PxAnimatedSvgDocument, PxNode } from './PxAnimatorTypes';\nimport { materialiseAnimatedUseInstances } from './PxAnimatorUseMaterialiser';\n\n\n/** Options accepted by {@link materialiseAllInTree}. Mostly forwarded to the\n * per-stage materialisers; ordering is fixed (see module doc). */\nexport interface MaterialiseAllOptions {\n /** Knobs forwarded to `materialiseMotionPathsInTree`. Only consulted for\n * `engine === webapi` — frames-mode skips that stage entirely. */\n motionPath?: MotionPathMaterialisationOptions;\n}\n\n\nexport function materialiseAllInTree(\n doc: PxAnimatedSvgDocument,\n engine: PxAnimatorEngine,\n opts?: MaterialiseAllOptions,\n): PxAnimatedSvgDocument {\n // 1. Effects → structural materialisation. Always runs; returns a fresh root.\n let root = applyPlayerEffects(doc).root as PxAnimatedSvgDocument;\n\n // 2. Loops → flat repeated keyframes. Always runs (both engines need flat\n // kfs covering the duration; per-binding expansion in\n // `normalizeKeyframes` becomes a no-op once the loop field is consumed).\n const duration = getAnimatorConfig(root)?.duration ?? DEFAULT_DURATION_MS;\n root = materialiseInternalLoopsInTree(root, duration);\n\n if (engine === PxAnimatorEngine.webapi) {\n // 3. Motion-along-path → sampled `{translate, rotate}` kfs. WAAPI can't\n // evaluate parametric tangents; frames-mode does that per frame so\n // we skip this for frames.\n root = materialiseMotionPathsInTree(root, opts?.motionPath);\n\n // 4. <use> referencing animated subtrees → <g> wrapping a fresh clone.\n // WAAPI / CSS animations don't reliably propagate through SVG <use>\n // shadow trees in Chrome / Safari; frames-mode updates source\n // attributes per frame and the shadow tree picks those up natively.\n root = materialiseAnimatedUseInstances(root);\n\n // 5. Prune <defs> `<g>`/`<symbol>` entries that step 4 orphaned — i.e. no\n // `<use>` references them any more (the animated uses that did got\n // inlined into `<g>`+clones). webapi-only: frames keeps `<use href>`,\n // so nothing is orphaned there.\n root = pruneUnreferencedDefs(root);\n }\n\n return root;\n}\n\n\n/**\n * Removes orphaned `<defs>` entries: direct `<defs>` children of type `<g>` /\n * `<symbol>` whose `id` is no longer targeted by ANY `<use href>` in the tree.\n * Runs after step 4 (`materialiseAnimatedUseInstances`), which inlines animated\n * `<use>`s and thereby leaves their former defs targets unreferenced.\n *\n * Loops to a fixpoint so chains collapse fully: pruning an entry can drop the\n * `<use>`s inside it, which in turn orphans the entries THOSE referenced. The\n * loop also drops a `<defs>` node once pruning has emptied it.\n *\n * Scope is intentionally limited to `<g>`/`<symbol>` (the `<use>`-target element\n * types) so `url(#…)`-referenced defs (gradients / masks / clipPaths / filters)\n * are never touched. Mutates `root` in place — safe, as it's a freshly\n * materialised tree owned by {@link materialiseAllInTree}.\n */\nfunction pruneUnreferencedDefs(root: PxAnimatedSvgDocument): PxAnimatedSvgDocument {\n const stripHash = (h: string): string => (h.startsWith('#') ? h.slice(1) : h);\n const walk = (n: PxNode, fn: (n: PxNode) => void): void => { fn(n); n.children?.forEach(c => walk(c, fn)); };\n\n let changed = true;\n while (changed) {\n changed = false;\n const referenced = new Set<string>();\n walk(root, n => {\n if (n.type === 'use' && typeof n.href === 'string') referenced.add(stripHash(n.href));\n });\n walk(root, n => {\n if (!n.children) return;\n let kept = n.children;\n // (a) inside <defs>: drop <g>/<symbol> entries no <use> targets any more\n if (n.type === 'defs') {\n kept = kept.filter(c =>\n !((c.type === 'g' || c.type === 'symbol') && typeof c.id === 'string' && !referenced.has(c.id)));\n }\n // (b) anywhere: drop a now-empty <defs> child\n kept = kept.filter(c => !(c.type === 'defs' && (!c.children || c.children.length === 0)));\n if (kept.length !== n.children.length) { n.children = kept; changed = true; }\n });\n }\n return root;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { getAnimatorConfig, PxAnimatorEngine, type PxAnimatedSvgDocument, type PxAnimatorAPI, type PxAnimatorCallbacksConfig } from './PxAnimatorTypes';\nimport { camelCaseToKebabWordIfNeeded, clamp, DEFAULT_DURATION_MS, STYLE_ATTR_NAMES } from './PxAnimatorUtil';\nimport { calcAnimationValues, getNormalisedBindings } from './PxDefinitions';\n\n\n// Frame scheduling — resolved LAZILY from globalThis on every call so test\n// harnesses that install fake timers (and hosts that polyfill rAF late) are\n// honoured. Falls back to a ~60fps setTimeout when rAF is unavailable.\nfunction requestFrame(cb: () => void): number {\n const g: any = globalThis as any;\n if (typeof g.requestAnimationFrame === 'function') return g.requestAnimationFrame(cb);\n return g.setTimeout(cb, 16) as unknown as number;\n}\n\nfunction cancelFrame(handle: number): void {\n const g: any = globalThis as any;\n if (typeof g.cancelAnimationFrame === 'function') { g.cancelAnimationFrame(handle); return; }\n g.clearTimeout(handle);\n}\n\n/**\n * Platform adapter interface for abstracting platform-specific operations.\n */\nexport interface PxPlatformAdapter {\n\n /** Check if the root element is still connected/mounted */\n isConnected(): boolean;\n\n /** Set an attribute on an element by id */\n setAttribute(id: string, attrName: string, value: string): void;\n}\n\n/**\n * Creates an animator instance that uses a frame loop for animations.\n * This is the abstract/platform-agnostic version.\n *\n * @param adapter Platform adapter for DOM/environment operations.\n * @param callbacks Optional lifecycle callbacks.\n * @returns A PxAnimatorAPI instance.\n */\nexport function createBasicFrameLoopAnimator(\n doc: PxAnimatedSvgDocument,\n adapter: PxPlatformAdapter,\n callbacks?: PxAnimatorCallbacksConfig\n): PxAnimatorAPI {\n\n const config = getAnimatorConfig(doc) || {};\n\n const bindings = getNormalisedBindings(doc, PxAnimatorEngine.frames);\n\n // iterations: either number or Infinity\n const _iterations = config.iterations;\n let iterations: number = 1;\n if (typeof _iterations === 'number') iterations = _iterations || 1;\n if (_iterations === 'infinite') iterations = Infinity;\n if (iterations < 1) iterations = 1;\n\n const duration = +(config.duration || DEFAULT_DURATION_MS); // per-iteration duration (ms), cannot be 0!\n const totalDuration = duration && iterations ?\n duration * (iterations === Infinity ? Infinity : iterations) :\n (duration ? (iterations ?? 1) * duration : 0);\n\n // direction handling\n const direction = config.direction || 'normal'; // 'normal' | 'reverse' | 'alternate' | 'alternate-reverse'\n\n // fill handling — mirrors the Web Animations API `fill` semantics as closely\n // as a frame-writer can. Default 'forwards' (hold final state) matches the\n // webapi engine and the config doc.\n const fill = config.fill ?? 'forwards';\n const fillsForwards = fill === 'forwards' || fill === 'both';\n const fillsBackwards = fill === 'backwards' || fill === 'both';\n\n ////////////////////////////////////////////////////////////////\n\n let timerId: number | null = null;\n let playing = false;\n\n // Accumulated logical time before the current run (ms). A positive\n // config.delay means \"wait before starting\" → the animation starts at\n // NEGATIVE logical time and reaches 0 after `delay` ms (same convention as\n // the Web Animations API). A negative config.delay means \"seek into the\n // animation\" → positive start time.\n let timeBeforeLastStartMs = -(config.delay || 0);\n let lastStartedTs = 0; // timestamp when last started/resumed\n let playbackRate = 1;\n\n let finishCalled = false; // ensures onFinish called once\n\n // Frame rate throttling\n const frameRate = config.frameRate;\n const minFrameIntervalMs = frameRate && frameRate > 0 ? 1000 / frameRate : 0;\n let lastRenderTs = 0; // timestamp of last render\n\n // Raw logical time — may be negative during the delay phase; not clamped\n // to the [0, totalDuration] range at the top end either. Internal use only.\n const getRawAnimTime = () => {\n // compute effective elapsed time (ms), taking playbackRate into account\n const runningElapsed = lastStartedTs ? (Date.now() - lastStartedTs) * playbackRate : 0;\n return timeBeforeLastStartMs + runningElapsed;\n };\n\n const getAnimCurrentTime = () => {\n let time = getRawAnimTime();\n\n // clamp to [0, totalDuration]\n if (Number.isFinite(totalDuration) && time > (totalDuration as number)) time = totalDuration as number;\n if (time < 0) time = 0;\n return time;\n };\n\n\n ////////////////////////////////////////////////////////////////\n\n\n // separate render function that uses a given currentTime (ms)\n function renderFrame(currentTimeMs: number) {\n\n function getEffectiveProgress() {\n // If no duration or duration === 0, set iteration/progress accordingly\n const safeDuration = duration > 0 ? duration : 1; // avoid division by zero\n\n let rawProgress = 0;\n let iteration = 0;\n if (duration > 0) {\n\n // rawProgress is normalized progress within the current iteration:\n // - first iteration: [0 .. 1]\n // - following iterations: (0 .. 1]\n //\n // iteration is the zero-based iteration index\n //\n // Examples (safeDuration = 3):\n // currentTimeMs = 0 → rawProgress = 0 , iteration = 0\n // currentTimeMs = 3 → rawProgress = 1 , iteration = 0\n // currentTimeMs = 3.0001 → rawProgress = 0.0001 , iteration = 1\n\n currentTimeMs = clamp(currentTimeMs, 0, iterations * safeDuration);\n\n iteration = Math.max(0, Math.ceil(currentTimeMs / safeDuration) - 1);\n iteration = Math.min(iteration, iterations - 1);\n\n // Time elapsed since the start of the current iteration\n const iterationTime = currentTimeMs - iteration * safeDuration;\n\n // Normalized progress (preserves fractional overflow after boundaries)\n rawProgress = clamp(iterationTime / safeDuration, 0, 1);\n } else {\n rawProgress = currentTimeMs; // We shouldn't be here\n }\n\n\n // compute per-iteration directional progress\n // start with baseProgress = rawProgress in [0,1)\n\n let baseProgress = rawProgress;\n // apply direction rules:\n // - normal: as is\n // - reverse: progress = 1 - baseProgress\n // - alternate: reverse on odd iterations\n // - alternate-reverse: reverse on even iterations\n const dir = direction || 'normal';\n let effectiveProgress = baseProgress;\n if (dir === 'reverse') {\n effectiveProgress = 1 - baseProgress;\n } else if (dir === 'alternate') {\n if (iteration % 2 === 1) effectiveProgress = 1 - baseProgress;\n } else if (dir === 'alternate-reverse') {\n // alternate-reverse: start reversed on iteration 0\n if (iteration % 2 === 0) effectiveProgress = 1 - baseProgress;\n } // else 'normal' -> keep\n return effectiveProgress;\n }\n let effectiveProgress = getEffectiveProgress(); // else 'normal' -> keep\n\n ////////////////////////////////////////////////////////////////\n\n // FIXME - pre-calc defs, then use\n\n for (const binding of bindings || []) {\n const animDef = binding.animate;\n if (!animDef || typeof animDef !== 'object' || Array.isArray(animDef)) {\n console.warn('Empty or unresolved binding', binding);\n continue;\n }\n\n // Calculate interpolated values for this binding's animation\n const computedValues = calcAnimationValues(animDef, effectiveProgress * duration);\n\n // Apply each computed attribute\n for (const [attrName, value] of Object.entries(computedValues)) {\n adapter.setAttribute(binding.id, attrName, value);\n }\n }\n }\n\n\n ////////////////////////////////////////////////////////////////\n\n const tick = () => {\n\n // if root element provided and detached, stop\n if (!adapter.isConnected()) {\n // stop animation loop (we'll let external code call play/resume)\n // do not call onFinish here. It's a detach situation.\n pauseAnim();\n return;\n }\n\n const currentTime = getAnimCurrentTime();\n\n // Delay phase (raw time < 0): the animation hasn't started yet.\n // With fill 'backwards'/'both' hold the first frame; otherwise leave\n // the element's static attributes untouched — mirrors WAAPI fill.\n // Checked BEFORE throttling so boundary states can't be skipped.\n const rawTime = getRawAnimTime();\n if (rawTime < 0 && playbackRate > 0) {\n if (fillsBackwards) renderFrame(0);\n return;\n }\n\n // Detect reverse playback reaching the start (natural end for rate < 0)\n // — mirrors WAAPI, where reverse playback fires `finish` at time 0.\n // pauseAnim runs FIRST (its trailing render must not clobber the\n // boundary frame rendered below).\n if (playbackRate < 0 && rawTime <= 0) {\n pauseAnim();\n renderFrame(0);\n if (!finishCalled) {\n finishCalled = true;\n callbacks?.onFinish?.();\n }\n return;\n }\n\n // Detect finished (natural end, forward playback)\n if (playbackRate > 0 && totalDuration && Number.isFinite(totalDuration) && currentTime >= (totalDuration as number)) {\n pauseAnim();\n // Render the end state — final frame when filling forwards, first\n // frame otherwise (closest frame-writer approximation of WAAPI\n // fill:'none'/'backwards', which reverts to the pre-animation state).\n renderFrame(fillsForwards ? (totalDuration as number) : 0);\n // call onFinish once\n if (!finishCalled) {\n finishCalled = true;\n callbacks?.onFinish?.();\n }\n return;\n }\n\n // Frame rate throttling: skip render if not enough time has passed.\n // Applies only to normal in-flight frames — boundary states above are\n // always rendered, so a throttled tick can never swallow the finish.\n if (minFrameIntervalMs > 0) {\n const now = Date.now();\n if (lastRenderTs && (now - lastRenderTs) < minFrameIntervalMs) {\n // Not enough time elapsed, skip this frame but continue the loop\n return;\n }\n lastRenderTs = now;\n }\n\n // Otherwise render normal frame\n renderFrame(currentTime);\n };\n\n\n ////////////////////////////////////////////////////////////////\n\n\n if (config.delay) {\n if (config.delay < 0) {\n // Negative delay = seek into the animation; render the seeked frame.\n renderFrame(getAnimCurrentTime());\n } else if (fillsBackwards) {\n // Positive delay = wait before start; hold the first frame only\n // when filling backwards (WAAPI convention).\n renderFrame(0);\n }\n }\n\n ////////////////////////////////////////////////////////////////\n\n const _isPlaying = () => {\n if (!playing) return false;\n if (!adapter.isConnected()) { return false; }\n if (playbackRate < 0) {\n // Reverse playback finishes when it reaches the start.\n return getRawAnimTime() > 0;\n }\n if (Number.isFinite(totalDuration) && getAnimCurrentTime() >= (totalDuration as number)) return false;\n return true;\n };\n\n const loopAnim = (isFirst?: boolean) => {\n if (timerId !== null) {\n cancelFrame(timerId);\n timerId = null;\n }\n\n if (!(isFirst || _isPlaying())) {\n // finished or not playing\n return;\n }\n\n timerId = requestFrame(() => {\n timerId = null;\n tick();\n loopAnim();\n });\n };\n\n const startAnim = () => {\n if (playing) return;\n\n // If the animation has already reached its natural end (for the current\n // playback direction), rewind to the opposite end before resuming —\n // mirrors the Web Animations API, where calling play() on a finished\n // animation auto-rewinds. Without this, resuming from the boundary\n // would re-finish on the first tick and leave the animation stuck.\n if (playbackRate >= 0) {\n if (Number.isFinite(totalDuration) && timeBeforeLastStartMs >= (totalDuration as number)) {\n timeBeforeLastStartMs = 0;\n }\n } else {\n // Reverse playback starting at (or before) the start: seek to the end.\n if (timeBeforeLastStartMs <= 0) {\n if (!Number.isFinite(totalDuration)) {\n // Cannot rewind to an infinite end (WAAPI throws here) —\n // warn and stay stopped instead of \"finishing\" instantly.\n console.warn('play: cannot start reverse playback of an infinite animation from time 0');\n return;\n }\n timeBeforeLastStartMs = totalDuration as number;\n }\n }\n\n // starting playback opens a new finish episode (mirrors WAAPI, where\n // play() always re-arms the finished promise / finish event)\n finishCalled = false;\n\n playing = true;\n lastStartedTs = Date.now();\n loopAnim(true);\n };\n\n const pauseAnim = () => {\n if (!playing) return;\n // Capture the RAW logical time — during the delay phase it is negative\n // and must stay negative, otherwise pausing would silently swallow the\n // remaining delay. Clamp only the top end.\n let raw = getRawAnimTime();\n if (Number.isFinite(totalDuration) && raw > (totalDuration as number)) raw = totalDuration as number;\n timeBeforeLastStartMs = raw;\n lastStartedTs = 0;\n playing = false;\n\n if (timerId !== null) {\n cancelFrame(timerId);\n timerId = null;\n }\n // Render a frame at the paused time to keep the DOM consistent —\n // except during the delay phase, where rendering would violate the\n // fill semantics (only 'backwards'/'both' show frame 0 before start).\n if (raw >= 0) {\n renderFrame(raw);\n } else if (fillsBackwards) {\n renderFrame(0);\n }\n };\n\n const cancelAnim = () => {\n pauseAnim();\n\n timeBeforeLastStartMs = 0;\n lastStartedTs = 0;\n playing = false;\n finishCalled = false;\n\n renderFrame(timeBeforeLastStartMs);\n\n callbacks?.onCancel?.();\n };\n\n const finishAnim = (callOnFinish = true) => {\n // jump to the end\n if (Number.isFinite(totalDuration)) {\n timeBeforeLastStartMs = totalDuration as number;\n } else {\n // infinity animations: set to current time (no-op)\n timeBeforeLastStartMs = getAnimCurrentTime();\n }\n lastStartedTs = 0;\n playing = false;\n // cancel any pending frame — pause/destroy early-return when not\n // playing, so a frame left queued here would never be cleaned up\n if (timerId !== null) {\n cancelFrame(timerId);\n timerId = null;\n }\n // Render the end state honouring `fill` (same rule as the natural\n // finish in `tick()`, and same as WAAPI where fill:'none' reverts even\n // after an explicit finish()).\n renderFrame(fillsForwards ? timeBeforeLastStartMs : 0);\n\n if (callOnFinish && !finishCalled) {\n finishCalled = true;\n callbacks?.onFinish?.();\n }\n };\n\n ////////////////////////////////////////////////////////////////\n\n const api: PxAnimatorAPI = {\n\n \"isReady\": () => true,\n\n \"getRootElement\": () => null,\n\n \"isPlaying\": (): boolean => { return _isPlaying(); },\n\n \"play\": () => {\n startAnim();\n callbacks?.onPlay?.();\n },\n \"pause\": () => {\n pauseAnim();\n callbacks?.onPause?.();\n },\n \"cancel\": () => {\n cancelAnim();\n // onCancel already called in cancelAnim\n },\n \"finish\": () => {\n finishAnim(true);\n },\n\n \"setPlaybackRate\": (rate: number) => {\n if (!isFinite(rate) || rate === 0) {\n console.warn('setPlaybackRate: rate must be finite and non-zero');\n return;\n }\n // Preserve the RAW logical time when changing rate — during the\n // delay phase it is negative and clamping it to 0 would skip the\n // remaining delay. Clamp only the top end.\n let current = getRawAnimTime();\n if (Number.isFinite(totalDuration) && current > (totalDuration as number)) current = totalDuration as number;\n // a direction change opens a new finish episode\n if ((rate < 0) !== (playbackRate < 0)) finishCalled = false;\n playbackRate = rate;\n timeBeforeLastStartMs = current;\n if (playing) lastStartedTs = Date.now();\n },\n\n \"getCurrentTime\": (): number | null => { return getAnimCurrentTime(); },\n\n \"setCurrentTime\": (newTime: number) => {\n // clamp newTime\n if (newTime < 0) newTime = 0;\n if (Number.isFinite(totalDuration) && newTime > (totalDuration as number)) newTime = totalDuration as number;\n\n timeBeforeLastStartMs = newTime;\n if (playing) lastStartedTs = Date.now();\n // seeking re-arms the finish notification (mirrors WAAPI)\n if (!Number.isFinite(totalDuration) || newTime < (totalDuration as number)) finishCalled = false;\n // render immediately to reflect the change\n renderFrame(getAnimCurrentTime());\n },\n\n \"destroy\": () => {\n api.cancel();\n callbacks?.onRemove?.();\n }\n };\n\n ////////////////////////////////////////////////////////////////\n\n return api;\n}\n\n\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\n/**\n * \"Equal-in-effect\" comparator for SVGA node trees.\n *\n * Two trees can render identically while differing structurally — extra `<g>`\n * wrappers, different ids, `<use>` clones vs inline copies, a transform expressed\n * as a baked string vs a parts record. This module reduces a tree to what is\n * actually painted: every drawable leaf, with its CUMULATIVE transform matrix\n * (resolved at a given time) and key visual attributes. Comparing those leaf\n * sets ignores representation and catches genuine visual differences.\n *\n * It is a deterministic function applied identically to both trees, so equal\n * inputs (in effect) yield equal output regardless of how each was encoded.\n *\n * Dependency-free on purpose (mirrors the applier's isolation). Scope: the node\n * types and transform forms the player-effects / heavy serialisers emit. Colour\n * animation is not interpolated — leaves are compared at keyframe instants where\n * sampled values are exact.\n */\n\ntype Mat = [number, number, number, number, number, number];\n\ninterface VmNode {\n type?: string;\n children?: Array<VmNode>;\n [attr: string]: any;\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// MATRIX MATH (2x3 affine, SVG order: [a b c d e f])\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst IDENTITY: Mat = [1, 0, 0, 1, 0, 0];\n\nfunction mul(m: Mat, n: Mat): Mat {\n return [\n m[0] * n[0] + m[2] * n[1],\n m[1] * n[0] + m[3] * n[1],\n m[0] * n[2] + m[2] * n[3],\n m[1] * n[2] + m[3] * n[3],\n m[0] * n[4] + m[2] * n[5] + m[4],\n m[1] * n[4] + m[3] * n[5] + m[5],\n ];\n}\n\nconst translateM = (x: number, y: number): Mat => [1, 0, 0, 1, x, y];\nconst scaleM = (sx: number, sy: number): Mat => [sx, 0, 0, sy, 0, 0];\nfunction rotateM(deg: number): Mat {\n const r = (deg * Math.PI) / 180;\n return [Math.cos(r), Math.sin(r), -Math.sin(r), Math.cos(r), 0, 0];\n}\nconst skewXM = (deg: number): Mat => [1, 0, Math.tan((deg * Math.PI) / 180), 1, 0, 0];\nconst skewYM = (deg: number): Mat => [1, Math.tan((deg * Math.PI) / 180), 0, 1, 0, 0];\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// TRANSFORM EVALUATION\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Parses an SVG transform string (\"translate(..)rotate(..)…\") into a matrix. */\nfunction parseTransformString(s: string): Mat {\n let m = IDENTITY;\n const re = /(translate|rotate|scale|matrix|skewX|skewY)\\(([^)]*)\\)/g;\n let hit: RegExpExecArray | null;\n while ((hit = re.exec(s))) {\n const fn = hit[1];\n const a = hit[2].split(/[\\s,]+/).filter(Boolean).map(Number);\n if (fn === 'translate') m = mul(m, translateM(a[0] || 0, a[1] || 0));\n else if (fn === 'scale') m = mul(m, scaleM(a[0], a.length > 1 ? a[1] : a[0]));\n else if (fn === 'rotate') m = mul(m, rotateM(a[0]));\n else if (fn === 'skewX') m = mul(m, skewXM(a[0]));\n else if (fn === 'skewY') m = mul(m, skewYM(a[0]));\n else if (fn === 'matrix') m = mul(m, [a[0], a[1], a[2], a[3], a[4], a[5]]);\n }\n return m;\n}\n\ninterface Parts { translate?: [number, number]; rotate?: number; scale?: [number, number]; origin?: [number, number]; }\n\n/** Composes a `PxTransformParts` record (player canonical order, origin-pivoted). */\nfunction partsToMatrix(p: Parts): Mat {\n let m = IDENTITY;\n if (p.translate) m = mul(m, translateM(p.translate[0], p.translate[1]));\n const pivot = p.origin && (p.rotate !== undefined || p.scale);\n if (pivot) m = mul(m, translateM(p.origin![0], p.origin![1]));\n if (p.rotate !== undefined) m = mul(m, rotateM(p.rotate));\n if (p.scale) m = mul(m, scaleM(p.scale[0], p.scale[1]));\n if (pivot) m = mul(m, translateM(-p.origin![0], -p.origin![1]));\n return m;\n}\n\nfunction lerp(a: number, b: number, f: number): number { return a + (b - a) * f; }\n\n/** Linear-interpolates a parts record between keyframes at time `t` (ms). */\nfunction interpParts(kfs: Array<any>, t: number): Parts {\n if (!kfs.length) return {};\n if (t <= (kfs[0].time ?? 0)) return kfs[0].value || {};\n if (t >= (kfs[kfs.length - 1].time ?? 0)) return kfs[kfs.length - 1].value || {};\n\n let i = 0;\n while (i < kfs.length - 1 && (kfs[i + 1].time ?? 0) < t) i++;\n const a = kfs[i], b = kfs[i + 1];\n const f = (t - (a.time ?? 0)) / ((b.time ?? 0) - (a.time ?? 0) || 1);\n const va: Parts = a.value || {}, vb: Parts = b.value || {};\n\n const out: Parts = {};\n if (va.translate && vb.translate) out.translate = [lerp(va.translate[0], vb.translate[0], f), lerp(va.translate[1], vb.translate[1], f)];\n else out.translate = va.translate || vb.translate;\n if (va.rotate !== undefined && vb.rotate !== undefined) out.rotate = lerp(va.rotate, vb.rotate, f);\n else out.rotate = va.rotate ?? vb.rotate;\n if (va.scale && vb.scale) out.scale = [lerp(va.scale[0], vb.scale[0], f), lerp(va.scale[1], vb.scale[1], f)];\n else out.scale = va.scale || vb.scale;\n out.origin = va.origin || vb.origin;\n return out;\n}\n\n/** Resolves any transform-slot form (string | {value} | {keyframes}) to a matrix at `t`. */\nfunction evalTransformValue(v: any, t: number): Mat {\n if (v === undefined || v === null) return IDENTITY;\n if (typeof v === 'string') return parseTransformString(v);\n if (v.keyframes) return partsToMatrix(interpParts(v.keyframes, t));\n if (v.value) return partsToMatrix(v.value);\n return IDENTITY;\n}\n\n/** The node's own transform at `t`: animated slot wins over the static baseline. */\nfunction nodeMatrix(node: VmNode, t: number): Mat {\n if (node.animate && node.animate.transform) return evalTransformValue(node.animate.transform, t);\n if (node.transform !== undefined) return evalTransformValue(node.transform, t);\n return IDENTITY;\n}\n\n/** Linear-interpolates a scalar animation (e.g. opacity); falls back to static / default. */\nfunction evalScalar(animated: any, staticVal: any, fallback: number, t: number): number {\n if (animated && animated.keyframes && animated.keyframes.length) {\n const kfs = animated.keyframes;\n if (t <= (kfs[0].time ?? 0)) return kfs[0].value;\n if (t >= (kfs[kfs.length - 1].time ?? 0)) return kfs[kfs.length - 1].value;\n let i = 0;\n while (i < kfs.length - 1 && (kfs[i + 1].time ?? 0) < t) i++;\n const a = kfs[i], b = kfs[i + 1];\n const f = (t - (a.time ?? 0)) / ((b.time ?? 0) - (a.time ?? 0) || 1);\n return lerp(a.value, b.value, f);\n }\n return staticVal !== undefined ? Number(staticVal) : fallback;\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// FLATTEN → multiset of painted primitives\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst CONTAINER_TYPES = new Set(['svg', 'g', 'symbol']);\nconst SKIP_TYPES = new Set(['defs', 'mask', 'clipPath', 'title']);\n\nfunction buildIdMap(node: VmNode, map: Map<string, VmNode>): void {\n if (typeof node.id === 'string') map.set(node.id, node);\n node.children?.forEach(c => buildIdMap(c, map));\n}\n\nfunction num(v: any): number { return v === undefined || v === null ? 0 : Number(v); }\n\n// 2-decimal rounding (sub-pixel). The heavy path bakes matrices into strings\n// rounded to ~4 decimals; comparing at 2 decimals avoids straddling a rounding\n// boundary against the applier's full-precision values, while staying visually exact.\nfunction round(n: number): number { return Math.round(n * 100) / 100 + 0; }\n\nfunction geomKey(node: VmNode): string {\n switch (node.type) {\n case 'rect': return num(node.width) + ',' + num(node.height) + ',' + num(node.x) + ',' + num(node.y);\n case 'ellipse': return num(node.rx) + ',' + num(node.ry) + ',' + num(node.cx) + ',' + num(node.cy);\n case 'circle': return num(node.r) + ',' + num(node.cx) + ',' + num(node.cy);\n case 'path': return String(node.d ?? '');\n default: return '';\n }\n}\n\nfunction describePrimitive(node: VmNode, m: Mat, t: number): string {\n const fill = node.fill ?? '';\n const stroke = node.stroke ?? '';\n const sw = node['stroke-width'] ?? node.strokeWidth ?? '';\n const opacity = round(evalScalar(node.animate?.opacity, node.opacity, 1, t));\n const masked = node.mask ? 1 : 0;\n const mat = m.map(round).join(',');\n return node.type + '|' + geomKey(node) + '|[' + mat + ']|f:' + fill + '|s:' + stroke + '|sw:' + (num(sw) || '') + '|o:' + opacity + '|m:' + masked;\n}\n\nfunction flatten(node: VmNode, parent: Mat, t: number, idMap: Map<string, VmNode>, out: Array<string>): void {\n const type = node.type || '';\n if (SKIP_TYPES.has(type)) return;\n\n const m = mul(parent, nodeMatrix(node, t));\n\n if (type === 'use') {\n const targetId = typeof node.href === 'string' ? node.href.replace(/^#/, '') : '';\n const target = idMap.get(targetId);\n const useM = mul(m, translateM(num(node.x), num(node.y)));\n if (target) flatten(target, useM, t, idMap, out);\n else out.push('UNRESOLVED_USE:#' + targetId);\n return;\n }\n\n if (CONTAINER_TYPES.has(type)) {\n node.children?.forEach(c => flatten(c, m, t, idMap, out));\n return;\n }\n\n out.push(describePrimitive(node, m, t));\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// PUBLIC: sample times + visual model + comparison\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Every keyframe `time` found anywhere in the tree, plus 0. */\nexport function collectSampleTimes(node: VmNode, into: Set<number>): void {\n into.add(0);\n const scanAnim = (anim: any) => {\n if (!anim || typeof anim !== 'object') return;\n for (const key of Object.keys(anim)) {\n const kfs = anim[key]?.keyframes;\n if (Array.isArray(kfs)) kfs.forEach(kf => into.add(kf.time ?? 0));\n }\n };\n scanAnim(node.animate);\n if (node.transform && typeof node.transform === 'object' && (node.transform as any).keyframes) {\n (node.transform as any).keyframes.forEach((kf: any) => into.add(kf.time ?? 0));\n }\n node.children?.forEach(c => collectSampleTimes(c, into));\n}\n\n/** Sorted, painted-primitive multiset for the tree at time `t`. */\nexport function visualModelAt(root: VmNode, t: number): Array<string> {\n const idMap = new Map<string, VmNode>();\n buildIdMap(root, idMap);\n const out: Array<string> = [];\n flatten(root, IDENTITY, t, idMap, out);\n return out.sort();\n}\n\nexport interface EffectDiff {\n time: number;\n onlyInA: Array<string>;\n onlyInB: Array<string>;\n}\n\n/**\n * Compares two trees \"in effect\" across all keyframe instants found in either.\n * Returns one entry per time where the painted-primitive multisets differ.\n */\nexport function diffInEffect(a: VmNode, b: VmNode): Array<EffectDiff> {\n const times = new Set<number>();\n collectSampleTimes(a, times);\n collectSampleTimes(b, times);\n\n const diffs: Array<EffectDiff> = [];\n for (const t of Array.from(times).sort((x, y) => x - y)) {\n const ma = visualModelAt(a, t);\n const mb = visualModelAt(b, t);\n const onlyInA = subtractMultiset(ma, mb);\n const onlyInB = subtractMultiset(mb, ma);\n if (onlyInA.length || onlyInB.length) diffs.push({ time: t, onlyInA, onlyInB });\n }\n return diffs;\n}\n\n/** Items in `a` not matched one-for-one in `b` (multiset difference). */\nfunction subtractMultiset(a: Array<string>, b: Array<string>): Array<string> {\n const counts = new Map<string, number>();\n for (const x of b) counts.set(x, (counts.get(x) || 0) + 1);\n const extra: Array<string> = [];\n for (const x of a) {\n const c = counts.get(x) || 0;\n if (c > 0) counts.set(x, c - 1);\n else extra.push(x);\n }\n return extra;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { getDefs, getNormalizedProps, resolveStyle, sanitiseAttributeValue, camelCaseToKebabWordIfNeeded, CSS_ONLY_STYLE_PROPS, DISALLOWED_SVG_TAGS_LOWER, TEXT_ATTR, TEXT_CONTENT_ATTR, type PxAnimatedSvgDocument, type PxDefs, type PxNode } from '@pixodesk/svg-animator-core';\n\n// Re-export from the historical home so the package surface is unchanged.\nexport { getNormalizedProps };\n\n\nconst SVG_NS = 'http://www.w3.org/2000/svg';\n\nfunction createElement(\n tagName: string,\n normalisedProps: { [k: string]: string },\n style: Record<string, string | number> | undefined,\n children: Array<Element> | undefined,\n textContent?: string\n): SVGElement | null {\n if (DISALLOWED_SVG_TAGS_LOWER.has(tagName.toLowerCase())) {\n console.warn('SVG tag blocked (dangerous): ', tagName);\n return null;\n }\n\n const element = document.createElementNS(SVG_NS, tagName);\n\n for (const propName in normalisedProps) {\n // `sanitiseAttributeValue` returns `undefined` to mean \"do not emit\"\n // (whitelist miss, blocked dangerous value, …). Browsers coerce\n // `undefined` to the literal string `\"undefined\"` at `setAttribute`,\n // which is exactly the bug we keep hitting — skip instead.\n const sanitised = sanitiseAttributeValue(propName, normalisedProps[propName]);\n if (sanitised === undefined) continue;\n // CSS-only properties (mix-blend-mode, isolation) aren't SVG presentation\n // attributes — the browser ignores them via setAttribute, so route them\n // through `element.style` (camelCase key) instead.\n if (CSS_ONLY_STYLE_PROPS.has(propName)) {\n (element as unknown as { style: Record<string, string> }).style[propName] = String(sanitised);\n continue;\n }\n element.setAttribute(camelCaseToKebabWordIfNeeded(propName), sanitised);\n }\n\n // Apply style properties directly (avoids kebab-case issues)\n if (style) {\n for (const styleProp in style) {\n (element as any).style[styleProp] = String(style[styleProp]);\n }\n }\n\n if (children) {\n for (const child of children) {\n element.appendChild(child);\n }\n }\n\n if (textContent) element.textContent = textContent;\n\n return element;\n}\n\n\n/**\n * Renders a PxNode tree to DOM elements.\n */\nexport function renderNode(node: PxNode, defs?: PxDefs): Element | null {\n if (!node) return null;\n\n const { type, children, style, ...props } = node;\n\n // feFunc elements (feFuncR/G/B/A) carry their SVG `type` attribute\n // (identity/table/…) under `funcType`, because the lightweight-JSON `type`\n // key is reserved for the node tag (and `type` is an INTERNAL_ATTR that\n // `getNormalizedProps` drops). Pull it out and re-apply it onto the created\n // element below, so a feComponentTransfer can actually invert.\n const feFuncType = (props as { funcType?: string }).funcType;\n if (feFuncType !== undefined) delete (props as { funcType?: string }).funcType;\n\n // Extract defs from root svg node\n const nodeDefs = getDefs(node as PxAnimatedSvgDocument) || defs;\n\n // Resolve style reference\n const resolvedStyle = resolveStyle(style, nodeDefs);\n\n // Process children\n let childElements: Array<Element> | undefined;\n if (children) {\n for (const ch of children) {\n const child = renderNode(ch, nodeDefs);\n if (child) {\n if (!childElements) childElements = [];\n childElements.push(child);\n }\n }\n }\n\n const element = createElement(\n type || 'g',\n getNormalizedProps(props),\n resolvedStyle,\n childElements,\n props[TEXT_ATTR] || props[TEXT_CONTENT_ATTR]\n );\n\n // `type` is an INTERNAL_ATTR (reserved for the node tag), so the feFunc transfer\n // function relayed via `funcType` must be applied to the real attribute here.\n if (element && feFuncType !== undefined) element.setAttribute('type', feFuncType);\n\n return element;\n}","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport type { PxTrigger } from '@pixodesk/svg-animator-core';\nimport type { PxAnimatorAPI } from './PxAnimatorWebTypes';\n\n\n/**\n * Sets up event-based triggers for an animation.\n *\n * This function attaches event listeners to the animation's root element based on the\n * provided configuration, allowing animations to be started by user interactions\n * or visibility changes.\n *\n * ### Trigger Options (startOn):\n * - 'load': Starts after the page loads.\n * - 'mouseOver': Starts on mouse enter.\n * - 'click': Toggles play/end action on click.\n * - 'scrollIntoView': Starts when the element scrolls into the viewport.\n * - 'programmatic': No automatic start. Must be controlled via the API.\n *\n * ### End Action Options (outAction):\n * Defines behavior when the trigger condition ends (e.g., mouse leave).\n * - 'continue': Animation continues playing.\n * - 'pause': Pauses the animation.\n * - 'reset': Cancels the animation, resetting it to the start.\n * - 'reverse': Reverses the animation playback.\n *\n * @param {!PxAnimatorAPI} api The animator API instance to control.\n * @param {!PxTrigger} config The trigger configuration object.\n * @returns {!PxAnimatorAPI} The same animator API instance, for chaining.\n */\nexport function setupAnimationTriggers(\n api: PxAnimatorAPI,\n config: PxTrigger\n): PxAnimatorAPI {\n // Threshold default 0 — \"any pixel visible starts it\". Keep in sync with the editor\n // model's default (TSvgSvgAnimationAttr.scrollIntoViewThreshold), which OMITS the\n // value on the wire when it equals this default.\n const { startOn, outAction = 'continue', scrollIntoViewThreshold = 0 } = config;\n\n const root = api.getRootElement();\n\n if (!root) {\n console.warn('setupAnimationTriggers: No root element found for animation.');\n return api;\n }\n\n // Tracks whether the LAST out-action put the animation into reverse, so the\n // next trigger start can restore forward playback without clobbering a\n // custom playback rate the user may have set through the API.\n let reversed = false;\n\n /** Ensures forward playback and starts or resumes the animation. */\n const start = () => {\n if (reversed) {\n reversed = false;\n api.setPlaybackRate(1);\n }\n api.play();\n };\n\n /** Handles what to do when the element leaves the active trigger condition. */\n const handleEndAction = () => {\n switch (outAction) {\n case 'pause':\n api.pause();\n break;\n case 'reset':\n api.cancel();\n break;\n case 'reverse':\n // Play the animation backwards from its current position.\n reversed = true;\n api.setPlaybackRate(-1);\n api.play();\n break;\n case 'continue':\n default:\n // Do nothing\n break;\n }\n };\n\n // ---- Setup event-based start logic ----\n switch (startOn) {\n case 'load': {\n const startHandler = () => start();\n if (document.readyState === 'complete') {\n startHandler();\n } else {\n window.addEventListener('load', startHandler, { once: true });\n }\n break;\n }\n\n case 'mouseOver': {\n const mouseOverHandler = () => start();\n const mouseOutHandler = () => handleEndAction();\n\n root.addEventListener('mouseenter', mouseOverHandler);\n root.addEventListener('mouseleave', mouseOutHandler);\n break;\n }\n\n case 'click': {\n const clickHandler = () => {\n if (api.isPlaying()) {\n handleEndAction();\n } else {\n start();\n }\n };\n root.addEventListener('click', clickHandler);\n break;\n }\n\n case 'scrollIntoView': {\n const observer = new IntersectionObserver(\n entries => {\n entries.forEach(entry => {\n // If the element is at least partially visible\n if (entry.isIntersecting && entry.intersectionRatio >= scrollIntoViewThreshold) {\n start();\n } else {\n // Element scrolled off screen -> trigger handleEndAction\n handleEndAction();\n }\n });\n },\n { threshold: scrollIntoViewThreshold }\n );\n observer.observe(root);\n break;\n }\n\n case 'programmatic':\n // No auto-start; external code must call play()\n break;\n }\n\n return api;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { camelCaseToKebabWordIfNeeded, createBasicFrameLoopAnimator, getAnimatorConfig, STYLE_ATTR_NAMES, type PxAnimatedSvgDocument, type PxAnimatorCallbacksConfig, type PxPlatformAdapter } from '@pixodesk/svg-animator-core';\nimport { setupAnimationTriggers } from './PxAnimatorTriggers';\nimport type { PxAnimatorAPI } from './PxAnimatorWebTypes';\n\n// Re-export the platform-neutral pieces from their historical home so the\n// package surface is unchanged by the core extraction.\nexport { createBasicFrameLoopAnimator };\nexport type { PxPlatformAdapter };\n\nexport function getSelector(id: string) {\n // return `[data-px-id=\"${id}\"]`; FIXME\n return '#' + id;\n}\n\n\n////////////////////////////////////////////////////////////////\n// Browser DOM implementation\n////////////////////////////////////////////////////////////////\n\n\n\n/**\n * Creates an animator instance that uses a requestAnimationFrame loop for animations.\n * This is the browser DOM-specific version.\n *\n * @param {PxAnimatorCallbacksConfig=} callbacks Optional lifecycle callbacks.\n * @param {Element=} rootElement Optional pre-rendered root element.\n * @returns {PxAnimatorAPI} A PxAnimatorAPI instance.\n */\nexport function createFrameLoopAnimator(\n doc: PxAnimatedSvgDocument,\n adapter?: PxPlatformAdapter,\n callbacks?: PxAnimatorCallbacksConfig,\n rootElement?: Element | null\n): PxAnimatorAPI {\n\n const config = getAnimatorConfig(doc) || {};\n\n // Use provided root element or try to find by selector\n if (!rootElement) {\n if (doc.id) {\n const rootSelector = getSelector(doc.id);\n rootElement = document.querySelector(rootSelector);\n if (!rootElement) console.warn(\"createFrameLoopAnimator: No root element found for selector: \", rootSelector);\n } else {\n console.warn(\"createFrameLoopAnimator: No root element provided\");\n }\n }\n\n const basicApi = createBasicFrameLoopAnimator(\n doc,\n adapter || createDomAdapter(rootElement),\n callbacks\n );\n\n // Specialise the platform-neutral API to the DOM: the root is an Element.\n const api: PxAnimatorAPI = {\n ...basicApi,\n \"getRootElement\": () => rootElement || null\n };\n if (config.trigger) setupAnimationTriggers(api, config.trigger);\n return api;\n}\n\nexport function createDomAdapter(rootElement?: Element | null) {\n // Track warnings to avoid spamming console\n const warnedSelectors = new Set<string>();\n\n const adapter: PxPlatformAdapter = {\n isConnected: () => {\n if (!rootElement) return true; // No root element means we're always \"connected\"\n return rootElement.isConnected;\n },\n setAttribute: (id, attrName, value) => {\n\n attrName = camelCaseToKebabWordIfNeeded(attrName);\n\n const selector = getSelector(id);\n\n // Query elements by selector within root (or document if no root)\n const elements = rootElement?.querySelectorAll(selector) || document.querySelectorAll(selector);\n\n if (elements.length === 0 && !warnedSelectors.has(selector)) {\n warnedSelectors.add(selector);\n console.warn('setAttribute: No elements found for selector \"' + selector + '\"');\n }\n\n for (let i = 0; i < elements.length; i++) {\n const element = elements[i];\n // `<pattern>` ignores the plain `transform` ATTRIBUTE (it transforms via\n // `patternTransform`). The WAAPI engine drives the same animation through\n // CSS `transform`, which browsers do apply to patterns — remap here so the\n // frames engine animates everything WAAPI animates.\n const effectiveAttrName = attrName === 'transform' && element.tagName === 'pattern'\n ? 'patternTransform'\n : attrName;\n element.setAttribute(effectiveAttrName, value);\n if (STYLE_ATTR_NAMES.has(attrName)) {\n (element as HTMLElement).style[attrName as any] = value;\n }\n }\n },\n };\n return adapter;\n}","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { bezierToSvgPath, clamp, COLOUR_ATTR_NAMES, composeTransformParts, cubicBezier, getAnimatorConfig, getNormalisedBindings, interpolateValue, kebabToCamelCaseWord, PxAnimatorEngine, splitEasing, toRGBA, TRANSFORM_FN_NAMES, type PxAnimatedSvgDocument, type PxAnimationDefinition, type PxAnimatorCallbacksConfig, type PxAnimatorConfig, type PxBezierPath, type PxKeyframe } from '@pixodesk/svg-animator-core';\nimport { getSelector } from './PxAnimatorFrameLoop';\nimport { setupAnimationTriggers } from './PxAnimatorTriggers';\nimport type { PxAnimatorAPI } from './PxAnimatorWebTypes';\n\n\n/**\n * Converts a single PxKeyframe into a Web Animations API Keyframe object.\n *\n * Handles three categories of CSS property:\n * - **Colour attributes** (e.g. fill, stroke): array values are converted to an rgba() string.\n * - **Transform functions** (e.g. translate, rotate, scale): values are formatted as a\n * CSS transform function string and mapped to the transform property.\n * - **All other properties**: the value is coerced to a string as-is.\n *\n * If the resulting (cssKey, cssValue) pair is not supported by the browser (CSS.supports returns\n * false), cssKey is added to unsupportedSet so the caller can decide whether to fall back to the\n * frame-loop animator.\n */\nfunction createCssKf(kf: PxKeyframe, t: number, propName: string, unsupportedSet: Set<string>) {\n let value = kf.v ?? kf.value;\n const e = kf.e ?? kf.easing; // e is on the source keyframe: applied from this KF to the next (matches WAAPI easing convention)\n\n const cssKf: Keyframe = {\n offset: t,\n easing: e && Array.isArray(e) ? \"cubic-bezier(\" + e.join(',') + \")\" : undefined\n };\n\n let cssValue: any;\n let cssKey = propName;\n\n if (COLOUR_ATTR_NAMES.has(propName) && Array.isArray(value)) {\n cssValue = toRGBA(value);\n } else if (propName === 'transform' && value !== null && typeof value === 'object' && !Array.isArray(value)) {\n // Unified transform: keyframe value is a parts record (PxTransformParts).\n // Compose all present parts into one CSS transform string.\n cssValue = composeTransformParts(value, { withUnits: true });\n cssKey = 'transform';\n } else if (TRANSFORM_FN_NAMES.has(propName)) {\n if (Array.isArray(value)) {\n if (propName === 'translate') value = value.map(v => v + 'px');\n value = value.join(',');\n }\n if (propName === 'rotate') value = value + 'deg';\n cssValue = propName + '(' + value + ')';\n cssKey = 'transform';\n } else if (propName === 'd') {\n // Animated path. The value is a { paths: PxBezierPath[] } record (same shape the CSS/frame\n // builder consumes). Without this branch it stringified to \"[object Object]\", an invalid\n // `d`, which empties the <path> — the shape vanished in forced WAAPI while svg-css (which\n // emits `d: path(...)`) rendered it. Emit the CSS `d` presentation-attr syntax `path(\"…\")`\n // via the same bezierToSvgPath used by the CSS path, so WAAPI animates it identically.\n const paths: Array<PxBezierPath> = (value && typeof value === 'object' && Array.isArray(value.paths))\n ? value.paths : [];\n // forceCurves: CSS/WAAPI only interpolates `path()` values with IDENTICAL command\n // sequences — uniform all-`C` output keeps every keyframe structurally equal\n // (mixed L/C, e.g. round-corner radius 0 vs >0, would go DISCRETE → 50% flip).\n cssValue = 'path(\"' + paths.map(bz => bezierToSvgPath(bz, true)).join('') + '\")';\n } else {\n cssValue = '' + value;\n }\n\n if (!CSS.supports(cssKey, cssValue)) unsupportedSet.add(cssKey);\n\n cssKey = kebabToCamelCaseWord(cssKey);\n cssKf[cssKey] = cssValue;\n return cssKf;\n}\n\n/**\n * Clips keyframes to the [0, duration] range.\n * If a keyframe pair straddles a boundary (t=0 or t=duration), inserts an interpolated\n * keyframe at the boundary with the correct value and split easing, so WAAPI sees\n * exact start/end values rather than out-of-range ones.\n */\nfunction clipKeyframesToDuration(\n propName: string,\n keyframes: PxKeyframe[],\n duration: number\n): PxKeyframe[] {\n const result: PxKeyframe[] = [];\n\n for (let i = 0; i < keyframes.length; i++) {\n const kf = keyframes[i];\n const t = kf.t ?? 0;\n\n if (t < 0) {\n // If the next keyframe is in range, interpolate value at t=0\n const next = keyframes[i + 1];\n if (next && (next.t ?? 0) >= 0) {\n const nextT = next.t ?? 0;\n const localFrac = (0 - t) / (nextT - t);\n const easedFrac = kf.e ? cubicBezier(kf.e as [number, number, number, number])(localFrac) : localFrac;\n const { right: rightEasing } = splitEasing(kf.e as any, localFrac);\n result.push({ t: 0, v: interpolateValue(propName, kf.v, next.v, easedFrac), e: rightEasing });\n }\n continue;\n }\n\n if (t > duration) {\n // If the previous keyframe was in range, interpolate value at t=duration\n const prev = keyframes[i - 1];\n if (prev && (prev.t ?? 0) <= duration) {\n const prevT = prev.t ?? 0;\n const localFrac = (duration - prevT) / (t - prevT);\n const easedFrac = prev.e ? cubicBezier(prev.e as [number, number, number, number])(localFrac) : localFrac;\n const { left: leftEasing } = splitEasing(prev.e as any, localFrac);\n if (result.length > 0) result[result.length - 1] = { ...result[result.length - 1], e: leftEasing };\n result.push({ t: duration, v: interpolateValue(propName, prev.v, kf.v, easedFrac), e: undefined });\n }\n break;\n }\n\n result.push(kf);\n }\n\n return result;\n}\n\n/**\n * Converts a PxAnimationDefinition into a map of Web Animations API Keyframe arrays, one per\n * animated property.\n *\n * For each property in the definition the function:\n * 1. Clips keyframes to [0, duration], interpolating boundary values when a pair straddles an edge.\n * 2. Normalises keyframe time values to the [0, 1] offset range (time / duration).\n * 3. Delegates CSS value conversion to createCssKf.\n * 4. Ensures the keyframe sequence always starts at offset: 0 and ends at offset: 1 — a\n * requirement of the Web Animations API for correct looping behaviour. If the first keyframe\n * starts after 0 or the last keyframe ends before 1, a copy of that keyframe is inserted at the\n * boundary with the adjusted offset.\n */\nexport function convertToWebApiKeyframes(\n animDef: PxAnimationDefinition,\n unsupportedSet: Set<string>,\n config: PxAnimatorConfig\n): Map<string, Keyframe[]> {\n const result = new Map<string, Keyframe[]>();\n\n for (const [propName, propAnim] of Object.entries(animDef)) {\n const duration = config.duration || 1;\n const clippedKeyframes = clipKeyframesToDuration(propName, propAnim.kfs || propAnim.keyframes || [], duration);\n const cssKeyframes: Keyframe[] = [];\n\n for (let i = 0; i < clippedKeyframes.length; i++) {\n const kf = clippedKeyframes[i];\n\n const t = clamp((kf.t ?? 0) / duration, 0, 1);\n const cssKf: Keyframe = createCssKf(kf, t, propName, unsupportedSet);\n\n // Keyframes need to start with offset:0 to work correctly with loops\n if (i === 0 && (cssKf.offset || 0) > 0) {\n cssKeyframes.push({ ...cssKf, offset: 0 });\n }\n\n cssKeyframes.push(cssKf);\n }\n\n // Keyframes need to end with offset:1 to work correctly with loops\n if (cssKeyframes.length > 0 && (cssKeyframes[cssKeyframes.length - 1].offset || 0) < 1) {\n cssKeyframes.push({\n ...cssKeyframes[cssKeyframes.length - 1],\n offset: 1\n });\n }\n\n if (cssKeyframes.length > 0) {\n result.set(propName, cssKeyframes);\n }\n }\n\n return result;\n}\n\n/**\n * Creates an animator instance that uses the native Web Animations API.\n *\n * This is the preferred, more performant animator. It will return null if the\n * animation configuration contains properties not supported by the browser's\n * Web Animations API implementation, unless forceEvenIfHasUnsupportedAttrs is true.\n *\n * @param callbacks Optional lifecycle callbacks.\n * @param rootElement Root element.\n * @param forceEvenIfHasUnsupportedAttrs If true, an animator will be created even if some CSS properties are not supported.\n * @returns An PxAnimatorAPI instance, or null if unsupported features are used and not forced.\n */\nexport function createWebApiAnimator(\n doc: PxAnimatedSvgDocument,\n callbacks?: PxAnimatorCallbacksConfig,\n rootElement?: Element | null,\n forceEvenIfHasUnsupportedAttrs?: boolean\n): PxAnimatorAPI | null {\n\n const config = getAnimatorConfig(doc) || {};\n\n // Use provided root element or try to find by selector\n if (!rootElement) {\n if (doc.id) {\n const rootSelector = getSelector(doc.id);\n rootElement = document.querySelector(rootSelector);\n if (!rootElement) console.warn(\"createFrameLoopAnimator: No root element found for selector: \", rootSelector);\n } else {\n console.warn(\"createFrameLoopAnimator: No root element provided\");\n }\n }\n\n // WAAPI bindings: motion-along-path is materialised into plain `{ translate,\n // rotate }` transform kfs inside `normalizeAnimationDefinition` (gated on\n // `engine === 'webapi'`). The WAAPI keyframe builder then sees a vanilla\n // unified-transform animation — no DOM-style mutation, no offset-path.\n const bindings = getNormalisedBindings(doc, PxAnimatorEngine.webapi);\n\n const animations: Array<Animation> = [];\n\n const _iterations = config.iterations;\n let iterations: number | undefined;\n if (typeof _iterations === 'number') iterations = _iterations;\n if (_iterations === 'infinite') iterations = Infinity;\n\n const unsupportedSet = new Set<string>();\n\n // A document commonly produces many Animation objects (one per element ×\n // animated property), but the public callbacks describe the document\n // timeline as a whole — guard so each fires once per finish/remove episode.\n // `finishNotified` re-arms on play/cancel/seek.\n let finishNotified = false;\n let removeCalled = false;\n\n ////////////////////////////////////////////////////////////////\n\n // Warn if no bindings defined\n if (!bindings?.length) {\n console.warn('createWebApiAnimator: No animation bindings defined');\n }\n\n for (const binding of bindings || []) {\n const animDef = binding.animate;\n if (!animDef || typeof animDef !== 'object' || Array.isArray(animDef)) {\n console.warn('createWebApiAnimator: Empty or unresolved binding', binding);\n continue;\n }\n\n const selector = getSelector(binding.id);\n\n // Use CSS selector to find elements\n const elements = rootElement?.querySelectorAll(selector) || document.querySelectorAll(selector);\n\n if (elements.length === 0) {\n console.warn('createWebApiAnimator: No elements found for selector \"' + selector + '\"');\n }\n\n // Convert animation definition to Web API keyframes\n const keyframesMap = convertToWebApiKeyframes(animDef, unsupportedSet, config);\n\n\n // Delay handling:\n // - Positive delay (e.g., 500): Wait before starting → use delay option\n // - Negative delay (e.g., -500): Start mid-animation → use currentTime to seek\n // (Web Animations API doesn't reliably support negative delay values)\n // WAAPI `currentTime` spans ALL iterations, so a finite timeline clamps\n // the seek to duration × iterations (seeking to exactly the end must\n // land on the final frame, not wrap to 0); an infinite timeline wraps\n // within one iteration instead.\n const positiveDelay = config.delay && config.delay > 0 ? config.delay : undefined;\n let seekPosition: number | undefined;\n if (config.delay && config.delay < 0 && config.duration) {\n const rawSeek = -config.delay;\n seekPosition = iterations === Infinity\n ? rawSeek % config.duration\n : Math.min(rawSeek, config.duration * (iterations ?? 1));\n }\n\n const effectOptions: KeyframeEffectOptions = {\n duration: config.duration,\n delay: positiveDelay,\n // Default to 'forwards' so elements hold their final state after the\n // animation ends — consistent with Lottie and other animation runtimes.\n // Without this, seeking to the last frame reverts elements to their\n // pre-animation state (the Web Animations API \"after\" phase with fill:'none').\n fill: config.fill ?? 'forwards',\n direction: config.direction,\n iterations: iterations\n };\n\n for (let i = 0; i < elements.length; i++) {\n const element = elements[i];\n\n for (const [, keyframes] of keyframesMap) {\n if (keyframes.length > 0) {\n try {\n const effect = new KeyframeEffect(element, keyframes, effectOptions);\n const anim = new Animation(effect, document.timeline);\n\n if (callbacks?.onFinish) anim.onfinish = () => {\n if (finishNotified) return;\n finishNotified = true;\n callbacks.onFinish?.();\n };\n if (callbacks?.onRemove) anim.onremove = () => {\n if (removeCalled) return;\n removeCalled = true;\n callbacks.onRemove?.();\n };\n\n // Seek forward for negative delay (e.g., delay=-500 → seek to 500ms).\n // `!== undefined` — a seek of exactly 0 is still a seek.\n if (seekPosition !== undefined) {\n anim.currentTime = seekPosition;\n }\n\n animations.push(anim);\n } catch (e) {\n console.warn(e);\n }\n }\n }\n }\n }\n\n ////////////////////////////////////////////////////////////////\n\n if (!forceEvenIfHasUnsupportedAttrs && unsupportedSet.size) {\n console.warn('Unsupported CSS attrs: ' + [...unsupportedSet].join(', '));\n return null;\n }\n\n ////////////////////////////////////////////////////////////////\n\n const api: PxAnimatorAPI = {\n\n \"isReady\": () => true,\n\n \"getRootElement\": () => rootElement || null,\n\n \"isPlaying\": (): boolean => { return animations[0]?.playState === 'running'; },\n\n \"play\": () => {\n finishNotified = false; // re-arm finish notification\n animations.forEach(a => a.play());\n callbacks?.onPlay?.();\n },\n \"pause\": () => {\n animations.forEach(a => a.pause());\n callbacks?.onPause?.();\n },\n \"cancel\": () => {\n finishNotified = false; // re-arm finish notification\n animations.forEach(a => a.cancel());\n callbacks?.onCancel?.();\n },\n \"finish\": () => {\n for (const a of animations) {\n try {\n if (a.effect?.getTiming().iterations === Infinity) {\n a.effect.updateTiming({ iterations: 1 });\n a.finish();\n a.effect.updateTiming({ iterations: Infinity });\n } else {\n a.finish();\n }\n } catch (e) {\n a.cancel();\n }\n }\n // Natural finish also reaches onFinish via the native `anim.onfinish`\n // handler wired at construction time.\n },\n\n \"setPlaybackRate\": (rate: number) => {\n animations.forEach(a => (a.playbackRate = rate));\n return api;\n },\n \"getCurrentTime\": (): number | null => {\n const res = animations[0]?.currentTime ?? null;\n return res !== null ? +res : null;\n },\n \"setCurrentTime\": (time: number) => {\n finishNotified = false; // re-arm finish notification\n animations.forEach(a => {\n a.currentTime = time;\n });\n },\n\n \"destroy\": () => {\n api.cancel();\n animations.splice(0, animations.length);\n if (!removeCalled) {\n removeCalled = true;\n callbacks?.onRemove?.();\n }\n }\n };\n\n ////////////////////////////////////////////////////////////////\n\n if (config.trigger) {\n setupAnimationTriggers(api, config.trigger);\n }\n\n return api;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { generateNewIds, getAnimatorConfig, isPxElementFileFormat, materialiseAllInTree, PX_ANIM_ATTR_NAME, PX_ANIM_SRC_ATTR_NAME, PxAnimatorEngine, PxAnimatorMode, validateNodeEffects, type PxAnimatedSvgDocument, type PxAnimatorCallbacksConfig, type PxPlatformAdapter } from '@pixodesk/svg-animator-core';\nimport { renderNode } from './PxAnimatorDOM';\nimport { createFrameLoopAnimator } from './PxAnimatorFrameLoop';\nimport { setupAnimationTriggers } from './PxAnimatorTriggers';\nimport type { PxAnimatorAPI } from './PxAnimatorWebTypes';\nimport { createWebApiAnimator } from './PxAnimatorWebApi';\n\n// Re-export so the package surface keeps `generateNewIds` at its historical home.\nexport { generateNewIds };\n\n\n/**\n * Creates an animator instance from a normalized player config.\n * This is the internal implementation that both engines use.\n */\nfunction createAnimatorFromConfig(\n doc: PxAnimatedSvgDocument,\n adapter?: PxPlatformAdapter,\n callbacks?: PxAnimatorCallbacksConfig,\n rootElement?: Element | null\n): PxAnimatorAPI {\n\n const animatorConfig = getAnimatorConfig(doc) || {};\n\n // `resetOnFinish`: after a NATURAL finish, snap the document back to its start\n // state — the same mechanics as the trigger `reset` out-action (`api.cancel()`\n // clears the animation state so the base attributes show). Composed centrally so\n // BOTH engines get it; the caller's own `onFinish` still fires first. `apiRef` is\n // assigned right after creation — finish always happens asynchronously later.\n let apiRef: PxAnimatorAPI | undefined;\n let effectiveCallbacks = callbacks;\n if (animatorConfig.resetOnFinish) {\n effectiveCallbacks = {\n ...callbacks,\n onFinish: () => {\n callbacks?.onFinish?.();\n apiRef?.cancel();\n },\n };\n }\n\n let res: PxAnimatorAPI;\n if (animatorConfig.mode === PxAnimatorMode.frames) {\n // Forcing frames, even if webapi could be used.\n res = createFrameLoopAnimator(doc, adapter, effectiveCallbacks, rootElement);\n } else {\n // Try webapi first; fall back to frames if it returns null (unsupported\n // attrs) unless the user explicitly forced webapi.\n res = (\n createWebApiAnimator(doc, effectiveCallbacks, rootElement,\n animatorConfig.mode === PxAnimatorMode.webapi // forcing webapi\n ) ||\n createFrameLoopAnimator(doc, adapter, effectiveCallbacks, rootElement)\n );\n }\n apiRef = res;\n\n if (animatorConfig.debugInstName) {\n (window as any)[animatorConfig.debugInstName] = res; // Exposing as global variable for debug\n }\n\n return res;\n}\n\n\n/**\n * Creates an animator instance from an AnimatedSvgDocument.\n *\n * This function serves as the main entry point for the animation library. It automatically\n * chooses the best animation engine available ('webapi' or 'frames') or can be\n * forced to use a specific one.\n *\n * @param doc The animated SVG document.\n * @param callbacks Optional object with callback functions for animation lifecycle events (play, pause, finish, etc.).\n * @param containerElement Optional selector or element to render the SVG into.\n * @returns An PxAnimatorAPI instance to programmatically control the animation.\n */\nexport function createAnimatorImpl(\n doc: PxAnimatedSvgDocument,\n adapter?: PxPlatformAdapter,\n callbacks?: PxAnimatorCallbacksConfig,\n containerElement?: string | Element\n): PxAnimatorAPI {\n\n // Validate every `node.effects` bucket against `PxEffectsSchema` and warn\n // about any shape drift. Doesn't mutate or block — the materialiser tries\n // its best even when shapes are off, but a warning helps spot wire-format\n // regressions early.\n const effectsWarnings = validateNodeEffects(doc as any);\n for (const w of effectsWarnings) console.warn('[PxAnimator] effects shape warning:', w);\n\n // Decide the engine upfront so the materialisation pipeline knows which\n // stages to run. `auto` (and any non-`frames` value) resolves to `webapi`\n // for materialisation purposes; if webapi later returns null at engine\n // construction, frames is used as fallback — slight over-materialisation\n // for that doc, but no correctness issue.\n const animatorConfig = getAnimatorConfig(doc) || {};\n const engine: PxAnimatorEngine = animatorConfig.mode === PxAnimatorMode.frames\n ? PxAnimatorEngine.frames\n : PxAnimatorEngine.webapi;\n\n // Run the full document materialisation pipeline:\n // effects → loops → motion-path (webapi only) → animated-use (webapi only)\n // The exact same function is exported for the Editor — no parallel pipeline.\n doc = materialiseAllInTree(doc, engine);\n\n let rootElement: Element | null = null;\n\n // Render whenever there's a container. A document with no children is still a\n // document — it carries the viewBox/size that make it a viewport — so it renders as an\n // EMPTY `<svg>`. Gating on `doc.children` left `getRootElement()` answering `null`,\n // which a consumer cannot tell apart from \"the render failed\".\n if (containerElement) {\n\n doc = generateNewIds(doc); // Regenerate IDs so repeated calls to createAnimator(...) produce different ids in elements\n\n const containerEl = typeof containerElement === 'string' ?\n document.querySelector(containerElement) : containerElement;\n\n if (containerEl) {\n rootElement = renderNode(doc);\n if (rootElement) {\n containerEl.replaceChildren(rootElement);\n }\n }\n }\n\n return createAnimatorFromConfig(doc, adapter, callbacks, rootElement);\n}\n\nexport const PX_ANIMATOR_DATA_KEY = 'data';\n\nexport interface PxAnimatorOptions {\n /** URL to fetch the animation document from. Provide either this or `data`, not both. */\n src?: string;\n /** Inline animation document object. Provide either this or `src`, not both. */\n data?: PxAnimatedSvgDocument;\n /** Platform adapter for frame-loop rendering. */\n adapter?: PxPlatformAdapter;\n /** Callback functions for animation lifecycle events. */\n callbacks?: PxAnimatorCallbacksConfig;\n /** CSS selector or element to render the SVG into. */\n container?: string | Element;\n}\n\n/**\n * Creates an animator instance to control SVG animations.\n *\n * @param options.src URL to fetch the animation document from.\n * @param options.data Inline animation document object.\n * @param options.container CSS selector or element to render the SVG into.\n * @returns A PxAnimatorAPI instance to programmatically control the animation.\n */\nexport function createAnimator(options: PxAnimatorOptions): PxAnimatorAPI {\n\n const { src, data, adapter, callbacks, container } = options;\n\n if (data !== undefined && src !== undefined) {\n throw new Error('createAnimator: provide either `src` or `data`, not both');\n }\n if (data === undefined && src === undefined) {\n throw new Error('createAnimator: either `src` or `data` is required');\n }\n\n if (data !== undefined) {\n return createAnimatorImpl(data, adapter, callbacks, container);\n }\n\n // URL provided - fetch and create animator\n let animator: PxAnimatorAPI | null = null;\n\n // Control calls made before the fetch resolves are queued and replayed (in\n // order) once the animator is ready, so e.g. `createAnimator({src}).play()`\n // works as expected. Getters are not queued — they return their \"not ready\n // yet\" value until the document loads.\n let pending: Array<(api: PxAnimatorAPI) => void> | null = [];\n let destroyed = false;\n\n const enqueue = (call: (api: PxAnimatorAPI) => void) => {\n if (animator) {\n call(animator);\n } else if (pending) {\n pending.push(call);\n }\n };\n\n fetch(src!).then(res => res.json()).then(json => {\n if (destroyed) return; // destroy() was called before the document loaded\n if (isPxElementFileFormat(json)) {\n animator = createAnimatorImpl(json, adapter, callbacks, container);\n const queued = pending;\n pending = null;\n queued?.forEach(call => call(animator!));\n } else {\n console.error('createAnimator: invalid animation document format at \"' + src + '\"');\n }\n }).catch(err => {\n pending = null;\n console.error('createAnimator: failed to load \"' + src + '\"', err);\n });\n\n // Return a proxy that forwards calls once loaded\n return {\n \"isReady\": () => !!animator,\n \"getRootElement\": () => animator ? animator.getRootElement() : null,\n \"isPlaying\": () => animator?.isPlaying() || false,\n \"play\": () => { enqueue(api => api.play()); },\n \"pause\": () => { enqueue(api => api.pause()); },\n \"cancel\": () => { enqueue(api => api.cancel()); },\n \"finish\": () => { enqueue(api => api.finish()); },\n \"setPlaybackRate\": (rate: number) => { enqueue(api => api.setPlaybackRate(rate)); },\n \"getCurrentTime\": () => animator ? animator.getCurrentTime() : null,\n \"setCurrentTime\": (time: number) => { enqueue(api => api.setCurrentTime(time)); },\n \"destroy\": () => {\n destroyed = true;\n pending = null; // drop any queued calls\n animator?.destroy();\n }\n };\n}\n\n/**\n * Scan and load for tags, e.g.\n * <div data-px-animation-src=\"animation.json\"></div>\n */\nexport function loadTagAnimators() {\n const elements = document.querySelectorAll('[' + PX_ANIM_SRC_ATTR_NAME + ']');\n for (let i = 0; i < elements.length; i++) {\n const element = elements[i];\n if (!(element as any)[PX_ANIM_ATTR_NAME]) {\n const src = element.getAttribute(PX_ANIM_SRC_ATTR_NAME);\n if (src) {\n (element as any)[PX_ANIM_ATTR_NAME] = createAnimator({ src, container: element });\n }\n }\n }\n}\n\nif (typeof window !== 'undefined') {\n (window as any)[\"loadTagAnimators\"] = loadTagAnimators;\n (window as any)[\"createAnimator\"] = createAnimator;\n (window as any)[\"setupAnimationTriggers\"] = setupAnimationTriggers;\n}","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport type { JsMode, OutAction, PxAnimatedSvgDocument, PxAnimatorAPI, PxNode, PxPlatformAdapter, PxTrigger, StartOn } from '@pixodesk/svg-animator-web';\nimport { camelCaseToKebabWordIfNeeded, createAnimator, FillMode, generateNewIds, getNormalizedProps, STYLE_ATTR_NAMES } from '@pixodesk/svg-animator-web';\nimport type { CSSProperties, FC, ReactElement } from 'react';\nimport React, { createElement, useEffect, useImperativeHandle, useRef } from 'react';\nimport { useDepsVersion } from './Utils';\n\n\n// -- Public types -----------------------------------------------------------\n\nexport interface ReactAnimatorApi {\n /** Returns true if the animation is currently running. */\n isPlaying(): boolean;\n\n /** Starts or resumes the animation. */\n play(): void;\n\n /** Pauses the animation at its current state. */\n pause(): void;\n\n /** Stops the animation and resets it to its initial state. */\n cancel(): void;\n\n /** Jumps to the end of the animation and holds the final state. */\n finish(): void;\n\n /** Changes the speed of the animation. 1 is normal, 2 is double, -1 is reverse. */\n setPlaybackRate(rate: number): void;\n\n /** Returns the current playback time in milliseconds. */\n getCurrentTime(): number | null;\n\n /** Jumps to a specific time (in milliseconds) in the animation. */\n setCurrentTime(time: number): void;\n}\n\nexport interface PixodeskSvgAnimatorImplProps {\n className?: string;\n style?: CSSProperties;\n doc: PxAnimatedSvgDocument;\n compMode: PixodeskSvgAnimatorCompMode;\n\n /** Imperative API handle populated by the inner component. */\n apiHolderRef: React.RefObject<PxAnimatorAPI | null>;\n\n /**\n * Latest lifecycle callbacks, read at invocation time so the memoised\n * inner component always calls the current props even though it never\n * re-renders.\n */\n callbacksRef: React.RefObject<PixodeskSvgAnimatorCallbacks>;\n}\n\n/** Lifecycle callback props (subset of {@link PixodeskSvgAnimatorProps}). */\nexport interface PixodeskSvgAnimatorCallbacks {\n onPlay?: () => void;\n onStop?: () => void;\n onPause?: () => void;\n onCancel?: () => void;\n onFinish?: () => void;\n onRemove?: () => void;\n}\n\nexport interface PixodeskSvgAnimatorProps {\n\n className?: string;\n\n style?: CSSProperties;\n\n // -- Source ---------------------------------------------------------------\n\n /**\n * The animation document to render.\n *\n * TODO: Accept PxFileConfig | string to support URL-based loading, e.g.\n * <PixodeskSvgAnimator doc=\"/animation.json\" />\n */\n doc: PxAnimatedSvgDocument;\n\n // -- Rendering mode ------------------------------------------------------\n\n /** Forces a specific rendering engine. Defaults to 'auto'. */\n mode?: JsMode;\n\n // -- Timing overrides ----------------------------------------------------\n\n /** Delay before the animation starts, in milliseconds. */\n delay?: number;\n\n /** Defines the element's style when the animation is not active. */\n fill?: FillMode;\n\n /** Number of iterations, or 'infinite' for endless looping. */\n iterations?: number | 'infinite';\n\n /** Duration of a single iteration in milliseconds. */\n duration?: number;\n\n /** Playback direction. */\n direction?: PlaybackDirection;\n\n /** Target frame rate (frames per second). */\n frameRate?: number;\n\n // -- Trigger overrides ---------------------------------------------------\n\n /** The event that starts the animation. When omitted, uses the value from the document config. */\n startOn?: StartOn;\n\n /** Behaviour when the trigger condition ends (e.g. mouse-out, second click). */\n outAction?: OutAction;\n\n /** Visibility ratio (0.0–1.0) required to trigger a scrollIntoView animation. Defaults to 0.5. */\n scrollIntoViewThreshold?: number;\n\n // -- Declarative control -------------------------------------------------\n\n /** When true, uses triggers defined in the animation document. */\n autoplay?: boolean;\n\n /**\n * Starts the animation unconditionally, ignoring document triggers.\n * Equivalent to `startOn=\"load\"` / `outAction=\"continue\"`.\n */\n play?: boolean;\n\n /** Pauses current playback. Only meaningful when `play` or `autoplay` is set. */\n pause?: boolean;\n\n // -- Imperative control --------------------------------------------------\n\n /** Ref populated with the imperative playback API. */\n apiRef?: React.RefObject<ReactAnimatorApi | null>;\n\n // -- Controlled (external) time ------------------------------------------\n\n /** Seek to a specific point in the animation, as a fraction (0–1) of the whole timeline (duration × iterations). */\n time?: number;\n\n /** Seek to a specific point in the animation (milliseconds). */\n timeMs?: number;\n\n // -- Callbacks -----------------------------------------------------------\n\n /** Called when the animation starts or resumes. */\n onPlay?: () => void;\n\n /** Called when the animation stops for any reason (pause / cancel / finish / removal). */\n onStop?: () => void;\n\n /** Called when the animation is paused. */\n onPause?: () => void;\n\n /** Called when the animation is cancelled. */\n onCancel?: () => void;\n\n /** Called when the animation finishes naturally. */\n onFinish?: () => void;\n\n /** Called when the animation is removed. */\n onRemove?: () => void;\n}\n\n\n// -- Internal types ---------------------------------------------------------\n\nenum PixodeskSvgAnimatorCompMode {\n static = 'static',\n autoplay = 'autoplay',\n play = 'play',\n imperativeApi = 'imperativeApi',\n fixedTime = 'fixedTime'\n}\n\n\n// -- React ↔ Animator bridge ------------------------------------------------\n\n/**\n * Creates a platform adapter that routes animator attribute updates\n * to the corresponding React-managed DOM refs.\n */\nexport function createReactAdapter(elementRefs: React.RefObject<Map<string, any>>) {\n const warnedSelectors = new Set<string>();\n\n const adapter: PxPlatformAdapter = {\n isConnected: () => {\n return true;\n },\n setAttribute: (id, attrName, value) => {\n\n attrName = camelCaseToKebabWordIfNeeded(attrName);\n\n const selector = getSelector(id);\n\n const element = elementRefs.current.get(id);\n\n if (!element && !warnedSelectors.has(selector)) {\n warnedSelectors.add(selector);\n console.warn('setAttribute: No elements found for selector \"' + selector + '\"');\n console.warn(elementRefs.current);\n }\n\n if (element) {\n element.setAttribute(attrName, value);\n if (STYLE_ATTR_NAMES.has(attrName)) {\n (element as HTMLElement).style[attrName as any] = value;\n }\n }\n },\n };\n return adapter;\n}\n\nexport function getSelector(id: string) {\n return '#' + id;\n}\n\n// FIXME: add model validation (e.g. isElementFileJson check)\n\n\n// -- Inner component (memoised, never re-renders) ---------------------------\n\nconst PixodeskSvgAnimatorImpl: FC<PixodeskSvgAnimatorImplProps> = ({\n className, style, doc, compMode, apiHolderRef, callbacksRef\n}) => {\n\n doc = generateNewIds(doc);\n\n const elementRefs = useRef(new Map<string, any>());\n\n const renderNode = (node: PxNode | undefined, isRoot = false): ReactElement | null => {\n if (!node) return null;\n\n const { type, animate, meta, children, ...props } = node;\n\n const normProps = getNormalizedProps(props);\n\n normProps['ref'] = (domEl: any) => {\n if (node['id']) elementRefs.current.set(node['id'], domEl);\n // return () => {};\n };\n\n // Apply the component's className/style props to the root SVG element.\n if (isRoot) {\n if (className) {\n normProps['className'] = normProps['className']\n ? normProps['className'] + ' ' + className\n : className;\n }\n if (style) normProps['style'] = style;\n }\n\n return createElement(type, normProps, children?.map(child => renderNode(child)));\n };\n\n const root = doc ? renderNode(doc, true) : null;\n\n // Create the animator once per document and tear it down on unmount.\n useEffect(() => {\n\n // Route lifecycle events through `callbacksRef` so the latest callback\n // props are invoked even though this component never re-renders.\n const cb = (name: keyof PixodeskSvgAnimatorCallbacks, alsoStop = false) => () => {\n callbacksRef.current?.[name]?.();\n if (alsoStop) callbacksRef.current?.onStop?.();\n };\n const callbacks = {\n onPlay: cb('onPlay'),\n onPause: cb('onPause', true),\n onCancel: cb('onCancel', true),\n onFinish: cb('onFinish', true),\n onRemove: cb('onRemove', true),\n };\n\n let api: PxAnimatorAPI | undefined = createAnimator({ data: doc, adapter: createReactAdapter(elementRefs), callbacks });\n apiHolderRef.current = api;\n\n return () => {\n api?.destroy();\n apiHolderRef.current = null;\n };\n }, [doc, apiHolderRef, callbacksRef]);\n\n return root;\n};\n\n/** Memoised wrapper — the inner component never re-renders (props are stable by design). */\nconst PixodeskSvgAnimatorImplOnce = React.memo(\n PixodeskSvgAnimatorImpl,\n () => true // Don't re-render\n);\n\n\n// -- Main public component --------------------------------------------------\n\n/**\n * React component for rendering and controlling Pixodesk SVG animations.\n *\n * Supports four mutually-exclusive control modes:\n *\n * 1. **Autoplay** – uses triggers from the animation document.\n * ```tsx\n * <PixodeskSvgAnimator doc={animation} autoplay />\n * ```\n *\n * 2. **Declarative play/pause** – controlled via boolean props.\n * ```tsx\n * <PixodeskSvgAnimator doc={animation} play pause={false} />\n * ```\n *\n * 3. **Imperative** – exposes a ref-based API for full programmatic control.\n * ```tsx\n * const api = useRef<ReactAnimatorApi>(null);\n * <PixodeskSvgAnimator doc={animation} apiRef={api} />\n * <button onClick={() => api.current?.play()}>Play</button>\n * ```\n *\n * 4. **Controlled time** – renders a single frame at a given time.\n * ```tsx\n * <PixodeskSvgAnimator doc={animation} time={0.5} />\n * <PixodeskSvgAnimator doc={animation} timeMs={500} />\n * ```\n */\nconst PixodeskSvgAnimator: FC<PixodeskSvgAnimatorProps> = ({\n className, style,\n doc, autoplay, play, pause, time, timeMs, apiRef,\n\n // Overrides\n mode, delay, fill, iterations, duration, direction, frameRate,\n\n startOn, outAction, scrollIntoViewThreshold,\n\n onPlay, onStop, onPause, onCancel, onFinish, onRemove\n}) => {\n\n // Determine which control mode is active.\n let compMode = PixodeskSvgAnimatorCompMode.static;\n if (apiRef) {\n compMode = PixodeskSvgAnimatorCompMode.imperativeApi;\n } else if (autoplay) {\n compMode = PixodeskSvgAnimatorCompMode.autoplay;\n } else if (time !== undefined || timeMs !== undefined) {\n compMode = PixodeskSvgAnimatorCompMode.fixedTime;\n } else if (play !== undefined || pause !== undefined) {\n compMode = PixodeskSvgAnimatorCompMode.play;\n }\n\n // In non-autoplay modes, override the document trigger to 'programmatic'\n // so the component can manage playback itself.\n if (compMode !== PixodeskSvgAnimatorCompMode.autoplay) {\n const startOn = doc.animator?.trigger?.startOn;\n if (\n startOn &&\n startOn !== 'programmatic' // FIXME: use enum\n ) {\n doc = {\n ...doc,\n animator: {\n ...doc.animator,\n trigger: {\n ...doc.animator?.trigger,\n startOn: 'programmatic' // FIXME: use enum\n }\n }\n };\n }\n }\n\n // Apply timing overrides from props onto the document config.\n if (\n mode !== undefined ||\n duration !== undefined ||\n delay !== undefined ||\n iterations !== undefined ||\n fill !== undefined ||\n direction !== undefined ||\n frameRate !== undefined\n ) {\n const animator = doc.animator || {};\n doc = {\n ...doc,\n animator: {\n ...animator,\n mode: mode !== undefined ? mode : animator.mode,\n duration: duration !== undefined ? duration : animator.duration,\n delay: delay !== undefined ? delay : animator.delay,\n iterations: iterations !== undefined ? iterations : animator.iterations,\n fill: fill !== undefined ? fill : animator.fill,\n direction: direction !== undefined ? direction : animator.direction,\n frameRate: frameRate !== undefined ? frameRate : animator.frameRate\n }\n };\n }\n\n // Apply trigger overrides from props.\n if (\n startOn !== undefined ||\n outAction !== undefined ||\n scrollIntoViewThreshold !== undefined\n ) {\n const trigger: PxTrigger = doc.animator?.trigger || {};\n doc = {\n ...doc,\n animator: {\n ...doc.animator,\n trigger: {\n ...trigger,\n startOn: startOn !== undefined ? startOn : trigger.startOn,\n outAction: outAction !== undefined ? outAction : trigger.outAction,\n scrollIntoViewThreshold: scrollIntoViewThreshold !== undefined ? scrollIntoViewThreshold : trigger.scrollIntoViewThreshold\n }\n }\n };\n }\n\n // Controlled-time mode: compute the absolute seek target. `time` is a\n // fraction (0–1) of the WHOLE timeline (duration × iterations); `timeMs`\n // is absolute milliseconds. The seek is applied through the animator API\n // (setCurrentTime) below — the document itself stays stable, so scrubbing\n // does NOT recreate the animator.\n let seekMs: number | undefined;\n if (compMode === PixodeskSvgAnimatorCompMode.fixedTime) {\n const animator = doc.animator || {};\n if (time !== undefined) {\n const iterationsValue = iterations ?? animator.iterations;\n const iterationsCount = typeof iterationsValue === 'number' && iterationsValue >= 1 ? iterationsValue : 1;\n const singleDuration = duration ?? animator.duration ?? 1000; // engine default duration\n seekMs = time * singleDuration * iterationsCount;\n }\n if (timeMs !== undefined) seekMs = timeMs;\n }\n\n const apiHolderRef = useRef<PxAnimatorAPI | null>(null);\n\n // Keep the latest callback props readable by the memoised inner component.\n const callbacksRef = useRef<PixodeskSvgAnimatorCallbacks>({});\n callbacksRef.current = { onPlay, onStop, onPause, onCancel, onFinish, onRemove };\n\n // Expose the imperative API via the consumer-provided ref.\n useImperativeHandle(apiRef, () => {\n return {\n isPlaying: () => apiHolderRef.current?.isPlaying() || false,\n play: () => apiHolderRef.current?.play(),\n pause: () => apiHolderRef.current?.pause(),\n cancel: () => apiHolderRef.current?.cancel(),\n finish: () => apiHolderRef.current?.finish(),\n setPlaybackRate: (rate: number) => apiHolderRef.current?.setPlaybackRate(rate),\n getCurrentTime: () => apiHolderRef.current?.getCurrentTime() ?? null,\n setCurrentTime: (time: number) => apiHolderRef.current?.setCurrentTime(time),\n };\n }, []);\n\n // Increment key when the document, mode, or root styling changes to force\n // a full remount (the inner component is memoised and never re-renders).\n const key = useDepsVersion(compMode, doc, className, style);\n\n // Sync declarative play/pause props with the animator. Re-runs after a\n // remount (`key` in deps) so a doc swap re-applies the current state.\n useEffect(() => {\n\n if (compMode === PixodeskSvgAnimatorCompMode.play) {\n if (play && !pause) {\n apiHolderRef.current?.play();\n } else if (pause) {\n apiHolderRef.current?.pause();\n } else if (play === false) {\n // explicit play=false → jump to the end state\n apiHolderRef.current?.finish();\n } else {\n // pause-only usage: pause switched off → resume\n apiHolderRef.current?.play();\n }\n }\n\n return () => {\n if (compMode === PixodeskSvgAnimatorCompMode.play) {\n // Intentionally read at cleanup time (NOT snapshotted at effect\n // time): the inner component nulls the ref when it destroys the\n // animator, so this pauses only a still-live instance. A\n // snapshot would call pause() on a destroyed animator and emit\n // a spurious onPause after teardown.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n apiHolderRef.current?.pause();\n }\n };\n }, [compMode, play, pause, key]);\n\n // Controlled-time mode: seek through the animator API. Scrubbing `time` /\n // `timeMs` only re-runs this effect — the animator is NOT recreated.\n useEffect(() => {\n if (compMode === PixodeskSvgAnimatorCompMode.fixedTime && seekMs !== undefined) {\n apiHolderRef.current?.setCurrentTime(seekMs);\n apiHolderRef.current?.pause();\n }\n }, [compMode, seekMs, key]);\n\n return (\n <PixodeskSvgAnimatorImplOnce\n key={key}\n className={className}\n style={style}\n compMode={compMode}\n doc={doc}\n apiHolderRef={apiHolderRef}\n callbacksRef={callbacksRef}\n />\n );\n};\n\nexport default PixodeskSvgAnimator;","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { useRef } from 'react';\n\nexport function deepEquals(a: any, b: any): boolean {\n // Handle primitives and null\n if (a === b) return true;\n if (a == null || b == null) return false;\n if (typeof a !== 'object' || typeof b !== 'object') return false;\n\n // Check for cycles using WeakSet\n const seen = new WeakSet();\n\n function equals(x: any, y: any): boolean {\n // Primitive/null check\n if (x === y) return true;\n if (x == null || y == null) return false;\n if (typeof x !== 'object' || typeof y !== 'object') return false;\n\n // Cycle detection\n if (seen.has(x)) {\n throw new Error('Circular reference detected');\n }\n seen.add(x);\n\n // Array check\n const xIsArray = Array.isArray(x);\n const yIsArray = Array.isArray(y);\n if (xIsArray !== yIsArray) return false;\n\n if (xIsArray) {\n if (x.length !== y.length) return false;\n for (let i = 0; i < x.length; i++) {\n if (!equals(x[i], y[i])) return false;\n }\n return true;\n }\n\n // Object check\n const xKeys = Object.keys(x);\n const yKeys = Object.keys(y);\n if (xKeys.length !== yKeys.length) return false;\n\n for (const key of xKeys) {\n if (!yKeys.includes(key)) return false;\n if (!equals(x[key], y[key])) return false;\n }\n\n return true;\n }\n\n return equals(a, b);\n}\n\n\n/**\n * Compares two arrays of dependencies using identity check first (===),\n * falling back to deep equality if references differ.\n * This is optimized for immutable data that may be recreated with same values.\n */\nfunction areDepsEqual(prevDeps: Array<any>, nextDeps: Array<any>): boolean {\n if (prevDeps.length !== nextDeps.length) return false;\n\n for (let i = 0; i < prevDeps.length; i++) {\n // Fast path: same reference (common for immutable data)\n if (prevDeps[i] === nextDeps[i]) continue;\n\n // Slow path: different reference but possibly same content\n if (!deepEquals(prevDeps[i], nextDeps[i])) return false;\n }\n\n return true;\n}\n\n/**\n * Returns a stable numeric version ID that only increments when dependencies\n * actually change (by reference or deep equality).\n */\nexport function useDepsVersion(...deps: Array<any>): number {\n const cache = useRef<{\n versionId: number;\n deps: Array<any>;\n } | null>(null);\n\n // First render - initialize with version 1\n if (cache.current === null) {\n cache.current = {\n versionId: 1,\n deps: deps\n };\n return 1;\n }\n\n // Check if any dependency changed (by reference or value)\n if (!areDepsEqual(cache.current.deps, deps)) {\n // Dependencies changed - increment version and update cache\n cache.current = {\n versionId: cache.current.versionId + 1,\n deps: deps\n };\n }\n\n return cache.current.versionId;\n}","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { OutAction, StartOn } from \"@pixodesk/svg-animator-web\";\nimport { CSSProperties, FC, ReactNode, useEffect, useRef, useState } from \"react\";\n\n\ntype AnimState = 'idle' | 'paused' | 'playing';\n\n/**\n * Controls playback of a SVG+CSS animated files by toggling class names on a wrapper div.\n *\n * Intended for use with SVG files exported from the Pixodesk editor using the\n * **CSS Keyframes** (no `<script>` tag). Import the SVG as a React component\n * via SVGR (`vite-plugin-svgr` or `@svgr/webpack`) and pass it as `children`:\n *\n * ```tsx\n * import AnimationSvg from './animation.svg?react'; // SVGR\n *\n * <PixodeskSvgCssAnimator startOn=\"mouseOver\" outAction=\"pause\">\n * <AnimationSvg />\n * </PixodeskSvgCssAnimator>\n * ```\n *\n * The wrapper div carries one of three animation states via CSS class names:\n * - *(no class)* — idle, animation not started\n * - `px-anim-enabled` — started but paused\n * - `px-anim-enabled px-anim-playing` — actively playing\n *\n * @param children - The SVGR-imported SVG component to animate.\n * @param startOn - What triggers the animation to start:\n * - `'load'` — plays immediately on mount (default)\n * - `'mouseOver'` — plays on hover\n * - `'click'` — plays on click, toggles on second click\n * - `'scrollIntoView'` — plays when the element enters the viewport\n * @param outAction - What happens when the trigger ends (hover/scroll out, second click):\n * - `'continue'` — keeps playing (default)\n * - `'pause'` — pauses at the current frame\n * - `'reset'` — resets to the beginning\n * @param className - Additional CSS class names to apply to the wrapper div.\n * @param style - Inline styles for the wrapper div (e.g. `{ width: 400, height: 400 }`).\n */\nconst PixodeskSvgCssAnimator: FC<{\n className?: string;\n style?: CSSProperties;\n children: ReactNode;\n startOn?: StartOn;\n outAction?: OutAction;\n}> = ({ className, style, children, startOn = 'load', outAction = 'continue' }) => {\n\n const [state, setState] = useState<AnimState>(startOn === 'load' ? 'playing' : 'idle');\n\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (startOn !== 'scrollIntoView') return;\n const el = ref.current;\n if (!el) return;\n const outState: AnimState = (\n outAction === 'reset' ? 'idle' :\n outAction === 'pause' ? 'paused' : 'playing'\n );\n const observer = new IntersectionObserver(\n ([entry]) => setState(entry.isIntersecting ? 'playing' : outState),\n { threshold: 0.1 }\n );\n observer.observe(el);\n return () => observer.disconnect();\n }, [startOn, outAction]);\n\n const goOut = () => setState(\n outAction === 'reset' ? 'idle' :\n outAction === 'pause' ? 'paused' : 'playing'\n );\n\n const handlers =\n startOn === 'mouseOver' ? { onMouseEnter: () => setState('playing'), onMouseLeave: goOut } :\n startOn === 'click' ? { onClick: () => state === 'playing' ? goOut() : setState('playing') } :\n {};\n\n return (\n <div\n ref={ref}\n className={[\n className,\n state === 'playing' ? 'px-anim-enabled px-anim-playing' :\n state === 'paused' ? 'px-anim-enabled' : ''\n ].filter(Boolean).join(' ')}\n style={style}\n {...handlers}\n >\n {children}\n </div>\n );\n};\nexport default PixodeskSvgCssAnimator;"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAWA,UAAI,qBAAqB,uBAAO,IAAI,4BAA4B;AAAhE,UACE,oBAAoB,uBAAO,IAAI,cAAc;AAD/C,UAEE,sBAAsB,uBAAO,IAAI,gBAAgB;AAFnD,UAGE,yBAAyB,uBAAO,IAAI,mBAAmB;AAHzD,UAIE,sBAAsB,uBAAO,IAAI,gBAAgB;AAJnD,UAKE,sBAAsB,uBAAO,IAAI,gBAAgB;AALnD,UAME,qBAAqB,uBAAO,IAAI,eAAe;AANjD,UAOE,yBAAyB,uBAAO,IAAI,mBAAmB;AAPzD,UAQE,sBAAsB,uBAAO,IAAI,gBAAgB;AARnD,UASE,kBAAkB,uBAAO,IAAI,YAAY;AAT3C,UAUE,kBAAkB,uBAAO,IAAI,YAAY;AAV3C,UAWE,sBAAsB,uBAAO,IAAI,gBAAgB;AAXnD,UAYE,wBAAwB,OAAO;AACjC,eAAS,cAAc,eAAe;AACpC,YAAI,SAAS,iBAAiB,aAAa,OAAO,cAAe,QAAO;AACxE,wBACG,yBAAyB,cAAc,qBAAqB,KAC7D,cAAc,YAAY;AAC5B,eAAO,eAAe,OAAO,gBAAgB,gBAAgB;AAAA,MAC/D;AACA,UAAI,uBAAuB;AAAA,QACvB,WAAW,WAAY;AACrB,iBAAO;AAAA,QACT;AAAA,QACA,oBAAoB,WAAY;AAAA,QAAC;AAAA,QACjC,qBAAqB,WAAY;AAAA,QAAC;AAAA,QAClC,iBAAiB,WAAY;AAAA,QAAC;AAAA,MAChC;AAPF,UAQE,SAAS,OAAO;AARlB,UASE,cAAc,CAAC;AACjB,eAAS,UAAU,OAAO,SAAS,SAAS;AAC1C,aAAK,QAAQ;AACb,aAAK,UAAU;AACf,aAAK,OAAO;AACZ,aAAK,UAAU,WAAW;AAAA,MAC5B;AACA,gBAAU,UAAU,mBAAmB,CAAC;AACxC,gBAAU,UAAU,WAAW,SAAU,cAAc,UAAU;AAC/D,YACE,aAAa,OAAO,gBACpB,eAAe,OAAO,gBACtB,QAAQ;AAER,gBAAM;AAAA,YACJ;AAAA,UACF;AACF,aAAK,QAAQ,gBAAgB,MAAM,cAAc,UAAU,UAAU;AAAA,MACvE;AACA,gBAAU,UAAU,cAAc,SAAU,UAAU;AACpD,aAAK,QAAQ,mBAAmB,MAAM,UAAU,aAAa;AAAA,MAC/D;AACA,eAAS,iBAAiB;AAAA,MAAC;AAC3B,qBAAe,YAAY,UAAU;AACrC,eAAS,cAAc,OAAO,SAAS,SAAS;AAC9C,aAAK,QAAQ;AACb,aAAK,UAAU;AACf,aAAK,OAAO;AACZ,aAAK,UAAU,WAAW;AAAA,MAC5B;AACA,UAAI,yBAA0B,cAAc,YAAY,IAAI,eAAe;AAC3E,6BAAuB,cAAc;AACrC,aAAO,wBAAwB,UAAU,SAAS;AAClD,6BAAuB,uBAAuB;AAC9C,UAAI,cAAc,MAAM;AACxB,eAAS,OAAO;AAAA,MAAC;AACjB,UAAI,uBAAuB,EAAE,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK;AAAhE,UACE,iBAAiB,OAAO,UAAU;AACpC,eAAS,aAAa,MAAM,KAAK,OAAO;AACtC,YAAI,UAAU,MAAM;AACpB,eAAO;AAAA,UACL,UAAU;AAAA,UACV;AAAA,UACA;AAAA,UACA,KAAK,WAAW,UAAU,UAAU;AAAA,UACpC;AAAA,QACF;AAAA,MACF;AACA,eAAS,mBAAmB,YAAY,QAAQ;AAC9C,eAAO,aAAa,WAAW,MAAM,QAAQ,WAAW,KAAK;AAAA,MAC/D;AACA,eAAS,eAAe,QAAQ;AAC9B,eACE,aAAa,OAAO,UACpB,SAAS,UACT,OAAO,aAAa;AAAA,MAExB;AACA,eAAS,OAAO,KAAK;AACnB,YAAI,gBAAgB,EAAE,KAAK,MAAM,KAAK,KAAK;AAC3C,eACE,MACA,IAAI,QAAQ,SAAS,SAAU,OAAO;AACpC,iBAAO,cAAc,KAAK;AAAA,QAC5B,CAAC;AAAA,MAEL;AACA,UAAI,6BAA6B;AACjC,eAAS,cAAc,SAAS,OAAO;AACrC,eAAO,aAAa,OAAO,WAAW,SAAS,WAAW,QAAQ,QAAQ,MACtE,OAAO,KAAK,QAAQ,GAAG,IACvB,MAAM,SAAS,EAAE;AAAA,MACvB;AACA,eAAS,gBAAgB,UAAU;AACjC,gBAAQ,SAAS,QAAQ;AAAA,UACvB,KAAK;AACH,mBAAO,SAAS;AAAA,UAClB,KAAK;AACH,kBAAM,SAAS;AAAA,UACjB;AACE,oBACG,aAAa,OAAO,SAAS,SAC1B,SAAS,KAAK,MAAM,IAAI,KACtB,SAAS,SAAS,WACpB,SAAS;AAAA,cACP,SAAU,gBAAgB;AACxB,8BAAc,SAAS,WACnB,SAAS,SAAS,aACnB,SAAS,QAAQ;AAAA,cACtB;AAAA,cACA,SAAU,OAAO;AACf,8BAAc,SAAS,WACnB,SAAS,SAAS,YAAc,SAAS,SAAS;AAAA,cACxD;AAAA,YACF,IACJ,SAAS,QACT;AAAA,cACA,KAAK;AACH,uBAAO,SAAS;AAAA,cAClB,KAAK;AACH,sBAAM,SAAS;AAAA,YACnB;AAAA,QACJ;AACA,cAAM;AAAA,MACR;AACA,eAAS,aAAa,UAAU,OAAO,eAAe,WAAW,UAAU;AACzE,YAAI,OAAO,OAAO;AAClB,YAAI,gBAAgB,QAAQ,cAAc,KAAM,YAAW;AAC3D,YAAI,iBAAiB;AACrB,YAAI,SAAS,SAAU,kBAAiB;AAAA;AAEtC,kBAAQ,MAAM;AAAA,YACZ,KAAK;AAAA,YACL,KAAK;AAAA,YACL,KAAK;AACH,+BAAiB;AACjB;AAAA,YACF,KAAK;AACH,sBAAQ,SAAS,UAAU;AAAA,gBACzB,KAAK;AAAA,gBACL,KAAK;AACH,mCAAiB;AACjB;AAAA,gBACF,KAAK;AACH,yBACG,iBAAiB,SAAS,OAC3B;AAAA,oBACE,eAAe,SAAS,QAAQ;AAAA,oBAChC;AAAA,oBACA;AAAA,oBACA;AAAA,oBACA;AAAA,kBACF;AAAA,cAEN;AAAA,UACJ;AACF,YAAI;AACF,iBACG,WAAW,SAAS,QAAQ,GAC5B,iBACC,OAAO,YAAY,MAAM,cAAc,UAAU,CAAC,IAAI,WACxD,YAAY,QAAQ,KACd,gBAAgB,IAClB,QAAQ,mBACL,gBACC,eAAe,QAAQ,4BAA4B,KAAK,IAAI,MAChE,aAAa,UAAU,OAAO,eAAe,IAAI,SAAU,GAAG;AAC5D,mBAAO;AAAA,UACT,CAAC,KACD,QAAQ,aACP,eAAe,QAAQ,MACrB,WAAW;AAAA,YACV;AAAA,YACA,iBACG,QAAQ,SAAS,OACjB,YAAY,SAAS,QAAQ,SAAS,MACnC,MACC,KAAK,SAAS,KAAK;AAAA,cAClB;AAAA,cACA;AAAA,YACF,IAAI,OACR;AAAA,UACJ,IACF,MAAM,KAAK,QAAQ,IACvB;AAEJ,yBAAiB;AACjB,YAAI,iBAAiB,OAAO,YAAY,MAAM,YAAY;AAC1D,YAAI,YAAY,QAAQ;AACtB,mBAAS,IAAI,GAAG,IAAI,SAAS,QAAQ;AACnC,YAAC,YAAY,SAAS,CAAC,GACpB,OAAO,iBAAiB,cAAc,WAAW,CAAC,GAClD,kBAAkB;AAAA,cACjB;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,iBACK,IAAI,cAAc,QAAQ,GAAI,eAAe,OAAO;AAC7D,eACE,WAAW,EAAE,KAAK,QAAQ,GAAG,IAAI,GACjC,EAAE,YAAY,SAAS,KAAK,GAAG;AAG/B,YAAC,YAAY,UAAU,OACpB,OAAO,iBAAiB,cAAc,WAAW,GAAG,GACpD,kBAAkB;AAAA,cACjB;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AAAA,iBACG,aAAa,MAAM;AAC1B,cAAI,eAAe,OAAO,SAAS;AACjC,mBAAO;AAAA,cACL,gBAAgB,QAAQ;AAAA,cACxB;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF;AACF,kBAAQ,OAAO,QAAQ;AACvB,gBAAM;AAAA,YACJ,qDACG,sBAAsB,QACnB,uBAAuB,OAAO,KAAK,QAAQ,EAAE,KAAK,IAAI,IAAI,MAC1D,SACJ;AAAA,UACJ;AAAA,QACF;AACA,eAAO;AAAA,MACT;AACA,eAAS,YAAY,UAAU,MAAM,SAAS;AAC5C,YAAI,QAAQ,SAAU,QAAO;AAC7B,YAAI,SAAS,CAAC,GACZ,QAAQ;AACV,qBAAa,UAAU,QAAQ,IAAI,IAAI,SAAU,OAAO;AACtD,iBAAO,KAAK,KAAK,SAAS,OAAO,OAAO;AAAA,QAC1C,CAAC;AACD,eAAO;AAAA,MACT;AACA,eAAS,gBAAgB,SAAS;AAChC,YAAI,OAAO,QAAQ,SAAS;AAC1B,cAAI,OAAO,QAAQ;AACnB,iBAAO,KAAK;AACZ,eAAK;AAAA,YACH,SAAU,cAAc;AACtB,kBAAI,MAAM,QAAQ,WAAW,OAAO,QAAQ;AAC1C,gBAAC,QAAQ,UAAU,GAAK,QAAQ,UAAU;AAAA,YAC9C;AAAA,YACA,SAAU,OAAO;AACf,kBAAI,MAAM,QAAQ,WAAW,OAAO,QAAQ;AAC1C,gBAAC,QAAQ,UAAU,GAAK,QAAQ,UAAU;AAAA,YAC9C;AAAA,UACF;AACA,iBAAO,QAAQ,YAAa,QAAQ,UAAU,GAAK,QAAQ,UAAU;AAAA,QACvE;AACA,YAAI,MAAM,QAAQ,QAAS,QAAO,QAAQ,QAAQ;AAClD,cAAM,QAAQ;AAAA,MAChB;AACA,UAAI,oBACA,eAAe,OAAO,cAClB,cACA,SAAU,OAAO;AACf,YACE,aAAa,OAAO,UACpB,eAAe,OAAO,OAAO,YAC7B;AACA,cAAI,QAAQ,IAAI,OAAO,WAAW,SAAS;AAAA,YACzC,SAAS;AAAA,YACT,YAAY;AAAA,YACZ,SACE,aAAa,OAAO,SACpB,SAAS,SACT,aAAa,OAAO,MAAM,UACtB,OAAO,MAAM,OAAO,IACpB,OAAO,KAAK;AAAA,YAClB;AAAA,UACF,CAAC;AACD,cAAI,CAAC,OAAO,cAAc,KAAK,EAAG;AAAA,QACpC,WACE,aAAa,OAAO,WACpB,eAAe,OAAO,QAAQ,MAC9B;AACA,kBAAQ,KAAK,qBAAqB,KAAK;AACvC;AAAA,QACF;AACA,gBAAQ,MAAM,KAAK;AAAA,MACrB;AA5BR,UA6BE,WAAW;AAAA,QACT,KAAK;AAAA,QACL,SAAS,SAAU,UAAU,aAAa,gBAAgB;AACxD;AAAA,YACE;AAAA,YACA,WAAY;AACV,0BAAY,MAAM,MAAM,SAAS;AAAA,YACnC;AAAA,YACA;AAAA,UACF;AAAA,QACF;AAAA,QACA,OAAO,SAAU,UAAU;AACzB,cAAI,IAAI;AACR,sBAAY,UAAU,WAAY;AAChC;AAAA,UACF,CAAC;AACD,iBAAO;AAAA,QACT;AAAA,QACA,SAAS,SAAU,UAAU;AAC3B,iBACE,YAAY,UAAU,SAAU,OAAO;AACrC,mBAAO;AAAA,UACT,CAAC,KAAK,CAAC;AAAA,QAEX;AAAA,QACA,MAAM,SAAU,UAAU;AACxB,cAAI,CAAC,eAAe,QAAQ;AAC1B,kBAAM;AAAA,cACJ;AAAA,YACF;AACF,iBAAO;AAAA,QACT;AAAA,MACF;AACF,cAAQ,WAAW;AACnB,cAAQ,WAAW;AACnB,cAAQ,YAAY;AACpB,cAAQ,WAAW;AACnB,cAAQ,WAAW;AACnB,cAAQ,gBAAgB;AACxB,cAAQ,aAAa;AACrB,cAAQ,WAAW;AACnB,cAAQ,kEACN;AACF,cAAQ,qBAAqB;AAAA,QAC3B,WAAW;AAAA,QACX,GAAG,SAAU,MAAM;AACjB,iBAAO,qBAAqB,EAAE,aAAa,IAAI;AAAA,QACjD;AAAA,MACF;AACA,cAAQ,QAAQ,SAAU,IAAI;AAC5B,eAAO,WAAY;AACjB,iBAAO,GAAG,MAAM,MAAM,SAAS;AAAA,QACjC;AAAA,MACF;AACA,cAAQ,cAAc,WAAY;AAChC,eAAO;AAAA,MACT;AACA,cAAQ,eAAe,SAAU,SAAS,QAAQ,UAAU;AAC1D,YAAI,SAAS,WAAW,WAAW;AACjC,gBAAM;AAAA,YACJ,0DAA0D,UAAU;AAAA,UACtE;AACF,YAAI,QAAQ,OAAO,CAAC,GAAG,QAAQ,KAAK,GAClC,MAAM,QAAQ;AAChB,YAAI,QAAQ;AACV,eAAK,YAAa,WAAW,OAAO,QAAQ,MAAM,KAAK,OAAO,MAAM;AAClE,aAAC,eAAe,KAAK,QAAQ,QAAQ,KACnC,UAAU,YACV,aAAa,YACb,eAAe,YACd,UAAU,YAAY,WAAW,OAAO,QACxC,MAAM,QAAQ,IAAI,OAAO,QAAQ;AACxC,YAAI,WAAW,UAAU,SAAS;AAClC,YAAI,MAAM,SAAU,OAAM,WAAW;AAAA,iBAC5B,IAAI,UAAU;AACrB,mBAAS,aAAa,MAAM,QAAQ,GAAG,IAAI,GAAG,IAAI,UAAU;AAC1D,uBAAW,CAAC,IAAI,UAAU,IAAI,CAAC;AACjC,gBAAM,WAAW;AAAA,QACnB;AACA,eAAO,aAAa,QAAQ,MAAM,KAAK,KAAK;AAAA,MAC9C;AACA,cAAQ,gBAAgB,SAAU,cAAc;AAC9C,uBAAe;AAAA,UACb,UAAU;AAAA,UACV,eAAe;AAAA,UACf,gBAAgB;AAAA,UAChB,cAAc;AAAA,UACd,UAAU;AAAA,UACV,UAAU;AAAA,QACZ;AACA,qBAAa,WAAW;AACxB,qBAAa,WAAW;AAAA,UACtB,UAAU;AAAA,UACV,UAAU;AAAA,QACZ;AACA,eAAO;AAAA,MACT;AACA,cAAQ,gBAAgB,SAAU,MAAM,QAAQ,UAAU;AACxD,YAAI,UACF,QAAQ,CAAC,GACT,MAAM;AACR,YAAI,QAAQ;AACV,eAAK,YAAa,WAAW,OAAO,QAAQ,MAAM,KAAK,OAAO,MAAM;AAClE,2BAAe,KAAK,QAAQ,QAAQ,KAClC,UAAU,YACV,aAAa,YACb,eAAe,aACd,MAAM,QAAQ,IAAI,OAAO,QAAQ;AACxC,YAAI,iBAAiB,UAAU,SAAS;AACxC,YAAI,MAAM,eAAgB,OAAM,WAAW;AAAA,iBAClC,IAAI,gBAAgB;AAC3B,mBAAS,aAAa,MAAM,cAAc,GAAG,IAAI,GAAG,IAAI,gBAAgB;AACtE,uBAAW,CAAC,IAAI,UAAU,IAAI,CAAC;AACjC,gBAAM,WAAW;AAAA,QACnB;AACA,YAAI,QAAQ,KAAK;AACf,eAAK,YAAc,iBAAiB,KAAK,cAAe;AACtD,uBAAW,MAAM,QAAQ,MACtB,MAAM,QAAQ,IAAI,eAAe,QAAQ;AAChD,eAAO,aAAa,MAAM,KAAK,KAAK;AAAA,MACtC;AACA,cAAQ,YAAY,WAAY;AAC9B,eAAO,EAAE,SAAS,KAAK;AAAA,MACzB;AACA,cAAQ,aAAa,SAAU,QAAQ;AACrC,eAAO,EAAE,UAAU,wBAAwB,OAAe;AAAA,MAC5D;AACA,cAAQ,iBAAiB;AACzB,cAAQ,OAAO,SAAU,MAAM;AAC7B,eAAO;AAAA,UACL,UAAU;AAAA,UACV,UAAU,EAAE,SAAS,IAAI,SAAS,KAAK;AAAA,UACvC,OAAO;AAAA,QACT;AAAA,MACF;AACA,cAAQ,OAAO,SAAU,MAAM,SAAS;AACtC,eAAO;AAAA,UACL,UAAU;AAAA,UACV;AAAA,UACA,SAAS,WAAW,UAAU,OAAO;AAAA,QACvC;AAAA,MACF;AACA,cAAQ,kBAAkB,SAAU,OAAO;AACzC,YAAI,iBAAiB,qBAAqB,GACxC,oBAAoB,CAAC;AACvB,6BAAqB,IAAI;AACzB,YAAI;AACF,cAAI,cAAc,MAAM,GACtB,0BAA0B,qBAAqB;AACjD,mBAAS,2BACP,wBAAwB,mBAAmB,WAAW;AACxD,uBAAa,OAAO,eAClB,SAAS,eACT,eAAe,OAAO,YAAY,QAClC,YAAY,KAAK,MAAM,iBAAiB;AAAA,QAC5C,SAAS,OAAO;AACd,4BAAkB,KAAK;AAAA,QACzB,UAAE;AACA,mBAAS,kBACP,SAAS,kBAAkB,UAC1B,eAAe,QAAQ,kBAAkB,QACzC,qBAAqB,IAAI;AAAA,QAC9B;AAAA,MACF;AACA,cAAQ,2BAA2B,WAAY;AAC7C,eAAO,qBAAqB,EAAE,gBAAgB;AAAA,MAChD;AACA,cAAQ,MAAM,SAAU,QAAQ;AAC9B,eAAO,qBAAqB,EAAE,IAAI,MAAM;AAAA,MAC1C;AACA,cAAQ,iBAAiB,SAAU,QAAQ,cAAc,WAAW;AAClE,eAAO,qBAAqB,EAAE,eAAe,QAAQ,cAAc,SAAS;AAAA,MAC9E;AACA,cAAQ,cAAc,SAAU,UAAU,MAAM;AAC9C,eAAO,qBAAqB,EAAE,YAAY,UAAU,IAAI;AAAA,MAC1D;AACA,cAAQ,aAAa,SAAU,SAAS;AACtC,eAAO,qBAAqB,EAAE,WAAW,OAAO;AAAA,MAClD;AACA,cAAQ,gBAAgB,WAAY;AAAA,MAAC;AACrC,cAAQ,mBAAmB,SAAU,OAAO,cAAc;AACxD,eAAO,qBAAqB,EAAE,iBAAiB,OAAO,YAAY;AAAA,MACpE;AACA,cAAQ,YAAY,SAAU,QAAQ,MAAM;AAC1C,eAAO,qBAAqB,EAAE,UAAU,QAAQ,IAAI;AAAA,MACtD;AACA,cAAQ,iBAAiB,SAAU,UAAU;AAC3C,eAAO,qBAAqB,EAAE,eAAe,QAAQ;AAAA,MACvD;AACA,cAAQ,QAAQ,WAAY;AAC1B,eAAO,qBAAqB,EAAE,MAAM;AAAA,MACtC;AACA,cAAQ,sBAAsB,SAAU,KAAK,QAAQ,MAAM;AACzD,eAAO,qBAAqB,EAAE,oBAAoB,KAAK,QAAQ,IAAI;AAAA,MACrE;AACA,cAAQ,qBAAqB,SAAU,QAAQ,MAAM;AACnD,eAAO,qBAAqB,EAAE,mBAAmB,QAAQ,IAAI;AAAA,MAC/D;AACA,cAAQ,kBAAkB,SAAU,QAAQ,MAAM;AAChD,eAAO,qBAAqB,EAAE,gBAAgB,QAAQ,IAAI;AAAA,MAC5D;AACA,cAAQ,UAAU,SAAU,QAAQ,MAAM;AACxC,eAAO,qBAAqB,EAAE,QAAQ,QAAQ,IAAI;AAAA,MACpD;AACA,cAAQ,gBAAgB,SAAU,aAAa,SAAS;AACtD,eAAO,qBAAqB,EAAE,cAAc,aAAa,OAAO;AAAA,MAClE;AACA,cAAQ,aAAa,SAAU,SAAS,YAAY,MAAM;AACxD,eAAO,qBAAqB,EAAE,WAAW,SAAS,YAAY,IAAI;AAAA,MACpE;AACA,cAAQ,SAAS,SAAU,cAAc;AACvC,eAAO,qBAAqB,EAAE,OAAO,YAAY;AAAA,MACnD;AACA,cAAQ,WAAW,SAAU,cAAc;AACzC,eAAO,qBAAqB,EAAE,SAAS,YAAY;AAAA,MACrD;AACA,cAAQ,uBAAuB,SAC7B,WACA,aACA,mBACA;AACA,eAAO,qBAAqB,EAAE;AAAA,UAC5B;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MACF;AACA,cAAQ,gBAAgB,WAAY;AAClC,eAAO,qBAAqB,EAAE,cAAc;AAAA,MAC9C;AACA,cAAQ,UAAU;AAAA;AAAA;;;AC7hBlB;AAAA;AAAA;AAWA,uBAAiB,QAAQ,IAAI,aAC1B,WAAY;AACX,iBAAS,yBAAyB,YAAY,MAAM;AAClD,iBAAO,eAAe,UAAU,WAAW,YAAY;AAAA,YACrD,KAAK,WAAY;AACf,sBAAQ;AAAA,gBACN;AAAA,gBACA,KAAK,CAAC;AAAA,gBACN,KAAK,CAAC;AAAA,cACR;AAAA,YACF;AAAA,UACF,CAAC;AAAA,QACH;AACA,iBAAS,cAAc,eAAe;AACpC,cAAI,SAAS,iBAAiB,aAAa,OAAO;AAChD,mBAAO;AACT,0BACG,yBAAyB,cAAc,qBAAqB,KAC7D,cAAc,YAAY;AAC5B,iBAAO,eAAe,OAAO,gBAAgB,gBAAgB;AAAA,QAC/D;AACA,iBAAS,SAAS,gBAAgB,YAAY;AAC5C,4BACI,iBAAiB,eAAe,iBAC/B,eAAe,eAAe,eAAe,SAChD;AACF,cAAI,aAAa,iBAAiB,MAAM;AACxC,kDAAwC,UAAU,MAC/C,QAAQ;AAAA,YACP;AAAA,YACA;AAAA,YACA;AAAA,UACF,GACC,wCAAwC,UAAU,IAAI;AAAA,QAC3D;AACA,iBAAS,UAAU,OAAO,SAAS,SAAS;AAC1C,eAAK,QAAQ;AACb,eAAK,UAAU;AACf,eAAK,OAAO;AACZ,eAAK,UAAU,WAAW;AAAA,QAC5B;AACA,iBAAS,iBAAiB;AAAA,QAAC;AAC3B,iBAAS,cAAc,OAAO,SAAS,SAAS;AAC9C,eAAK,QAAQ;AACb,eAAK,UAAU;AACf,eAAK,OAAO;AACZ,eAAK,UAAU,WAAW;AAAA,QAC5B;AACA,iBAAS,OAAO;AAAA,QAAC;AACjB,iBAAS,mBAAmB,OAAO;AACjC,iBAAO,KAAK;AAAA,QACd;AACA,iBAAS,uBAAuB,OAAO;AACrC,cAAI;AACF,+BAAmB,KAAK;AACxB,gBAAI,2BAA2B;AAAA,UACjC,SAAS,GAAG;AACV,uCAA2B;AAAA,UAC7B;AACA,cAAI,0BAA0B;AAC5B,uCAA2B;AAC3B,gBAAI,wBAAwB,yBAAyB;AACrD,gBAAI,oCACD,eAAe,OAAO,UACrB,OAAO,eACP,MAAM,OAAO,WAAW,KAC1B,MAAM,YAAY,QAClB;AACF,kCAAsB;AAAA,cACpB;AAAA,cACA;AAAA,cACA;AAAA,YACF;AACA,mBAAO,mBAAmB,KAAK;AAAA,UACjC;AAAA,QACF;AACA,iBAAS,yBAAyB,MAAM;AACtC,cAAI,QAAQ,KAAM,QAAO;AACzB,cAAI,eAAe,OAAO;AACxB,mBAAO,KAAK,aAAa,yBACrB,OACA,KAAK,eAAe,KAAK,QAAQ;AACvC,cAAI,aAAa,OAAO,KAAM,QAAO;AACrC,kBAAQ,MAAM;AAAA,YACZ,KAAK;AACH,qBAAO;AAAA,YACT,KAAK;AACH,qBAAO;AAAA,YACT,KAAK;AACH,qBAAO;AAAA,YACT,KAAK;AACH,qBAAO;AAAA,YACT,KAAK;AACH,qBAAO;AAAA,YACT,KAAK;AACH,qBAAO;AAAA,UACX;AACA,cAAI,aAAa,OAAO;AACtB,oBACG,aAAa,OAAO,KAAK,OACxB,QAAQ;AAAA,cACN;AAAA,YACF,GACF,KAAK,UACL;AAAA,cACA,KAAK;AACH,uBAAO;AAAA,cACT,KAAK;AACH,uBAAO,KAAK,eAAe;AAAA,cAC7B,KAAK;AACH,wBAAQ,KAAK,SAAS,eAAe,aAAa;AAAA,cACpD,KAAK;AACH,oBAAI,YAAY,KAAK;AACrB,uBAAO,KAAK;AACZ,yBACI,OAAO,UAAU,eAAe,UAAU,QAAQ,IACnD,OAAO,OAAO,OAAO,gBAAgB,OAAO,MAAM;AACrD,uBAAO;AAAA,cACT,KAAK;AACH,uBACG,YAAY,KAAK,eAAe,MACjC,SAAS,YACL,YACA,yBAAyB,KAAK,IAAI,KAAK;AAAA,cAE/C,KAAK;AACH,4BAAY,KAAK;AACjB,uBAAO,KAAK;AACZ,oBAAI;AACF,yBAAO,yBAAyB,KAAK,SAAS,CAAC;AAAA,gBACjD,SAAS,GAAG;AAAA,gBAAC;AAAA,YACjB;AACF,iBAAO;AAAA,QACT;AACA,iBAAS,YAAY,MAAM;AACzB,cAAI,SAAS,oBAAqB,QAAO;AACzC,cACE,aAAa,OAAO,QACpB,SAAS,QACT,KAAK,aAAa;AAElB,mBAAO;AACT,cAAI;AACF,gBAAI,OAAO,yBAAyB,IAAI;AACxC,mBAAO,OAAO,MAAM,OAAO,MAAM;AAAA,UACnC,SAAS,GAAG;AACV,mBAAO;AAAA,UACT;AAAA,QACF;AACA,iBAAS,WAAW;AAClB,cAAI,aAAa,qBAAqB;AACtC,iBAAO,SAAS,aAAa,OAAO,WAAW,SAAS;AAAA,QAC1D;AACA,iBAAS,eAAe;AACtB,iBAAO,MAAM,uBAAuB;AAAA,QACtC;AACA,iBAAS,YAAY,QAAQ;AAC3B,cAAI,eAAe,KAAK,QAAQ,KAAK,GAAG;AACtC,gBAAI,SAAS,OAAO,yBAAyB,QAAQ,KAAK,EAAE;AAC5D,gBAAI,UAAU,OAAO,eAAgB,QAAO;AAAA,UAC9C;AACA,iBAAO,WAAW,OAAO;AAAA,QAC3B;AACA,iBAAS,2BAA2B,OAAO,aAAa;AACtD,mBAAS,wBAAwB;AAC/B,2CACI,6BAA6B,MAC/B,QAAQ;AAAA,cACN;AAAA,cACA;AAAA,YACF;AAAA,UACJ;AACA,gCAAsB,iBAAiB;AACvC,iBAAO,eAAe,OAAO,OAAO;AAAA,YAClC,KAAK;AAAA,YACL,cAAc;AAAA,UAChB,CAAC;AAAA,QACH;AACA,iBAAS,yCAAyC;AAChD,cAAI,gBAAgB,yBAAyB,KAAK,IAAI;AACtD,iCAAuB,aAAa,MAChC,uBAAuB,aAAa,IAAI,MAC1C,QAAQ;AAAA,YACN;AAAA,UACF;AACF,0BAAgB,KAAK,MAAM;AAC3B,iBAAO,WAAW,gBAAgB,gBAAgB;AAAA,QACpD;AACA,iBAAS,aAAa,MAAM,KAAK,OAAO,OAAO,YAAY,WAAW;AACpE,cAAI,UAAU,MAAM;AACpB,iBAAO;AAAA,YACL,UAAU;AAAA,YACV;AAAA,YACA;AAAA,YACA;AAAA,YACA,QAAQ;AAAA,UACV;AACA,oBAAU,WAAW,UAAU,UAAU,QACrC,OAAO,eAAe,MAAM,OAAO;AAAA,YACjC,YAAY;AAAA,YACZ,KAAK;AAAA,UACP,CAAC,IACD,OAAO,eAAe,MAAM,OAAO,EAAE,YAAY,OAAI,OAAO,KAAK,CAAC;AACtE,eAAK,SAAS,CAAC;AACf,iBAAO,eAAe,KAAK,QAAQ,aAAa;AAAA,YAC9C,cAAc;AAAA,YACd,YAAY;AAAA,YACZ,UAAU;AAAA,YACV,OAAO;AAAA,UACT,CAAC;AACD,iBAAO,eAAe,MAAM,cAAc;AAAA,YACxC,cAAc;AAAA,YACd,YAAY;AAAA,YACZ,UAAU;AAAA,YACV,OAAO;AAAA,UACT,CAAC;AACD,iBAAO,eAAe,MAAM,eAAe;AAAA,YACzC,cAAc;AAAA,YACd,YAAY;AAAA,YACZ,UAAU;AAAA,YACV,OAAO;AAAA,UACT,CAAC;AACD,iBAAO,eAAe,MAAM,cAAc;AAAA,YACxC,cAAc;AAAA,YACd,YAAY;AAAA,YACZ,UAAU;AAAA,YACV,OAAO;AAAA,UACT,CAAC;AACD,iBAAO,WAAW,OAAO,OAAO,KAAK,KAAK,GAAG,OAAO,OAAO,IAAI;AAC/D,iBAAO;AAAA,QACT;AACA,iBAAS,mBAAmB,YAAY,QAAQ;AAC9C,mBAAS;AAAA,YACP,WAAW;AAAA,YACX;AAAA,YACA,WAAW;AAAA,YACX,WAAW;AAAA,YACX,WAAW;AAAA,YACX,WAAW;AAAA,UACb;AACA,qBAAW,WACR,OAAO,OAAO,YAAY,WAAW,OAAO;AAC/C,iBAAO;AAAA,QACT;AACA,iBAAS,kBAAkB,MAAM;AAC/B,yBAAe,IAAI,IACf,KAAK,WAAW,KAAK,OAAO,YAAY,KACxC,aAAa,OAAO,QACpB,SAAS,QACT,KAAK,aAAa,oBACjB,gBAAgB,KAAK,SAAS,SAC3B,eAAe,KAAK,SAAS,KAAK,KAClC,KAAK,SAAS,MAAM,WACnB,KAAK,SAAS,MAAM,OAAO,YAAY,KACxC,KAAK,WAAW,KAAK,OAAO,YAAY;AAAA,QAClD;AACA,iBAAS,eAAe,QAAQ;AAC9B,iBACE,aAAa,OAAO,UACpB,SAAS,UACT,OAAO,aAAa;AAAA,QAExB;AACA,iBAAS,OAAO,KAAK;AACnB,cAAI,gBAAgB,EAAE,KAAK,MAAM,KAAK,KAAK;AAC3C,iBACE,MACA,IAAI,QAAQ,SAAS,SAAU,OAAO;AACpC,mBAAO,cAAc,KAAK;AAAA,UAC5B,CAAC;AAAA,QAEL;AACA,iBAAS,cAAc,SAAS,OAAO;AACrC,iBAAO,aAAa,OAAO,WACzB,SAAS,WACT,QAAQ,QAAQ,OACb,uBAAuB,QAAQ,GAAG,GAAG,OAAO,KAAK,QAAQ,GAAG,KAC7D,MAAM,SAAS,EAAE;AAAA,QACvB;AACA,iBAAS,gBAAgB,UAAU;AACjC,kBAAQ,SAAS,QAAQ;AAAA,YACvB,KAAK;AACH,qBAAO,SAAS;AAAA,YAClB,KAAK;AACH,oBAAM,SAAS;AAAA,YACjB;AACE,sBACG,aAAa,OAAO,SAAS,SAC1B,SAAS,KAAK,MAAM,IAAI,KACtB,SAAS,SAAS,WACpB,SAAS;AAAA,gBACP,SAAU,gBAAgB;AACxB,gCAAc,SAAS,WACnB,SAAS,SAAS,aACnB,SAAS,QAAQ;AAAA,gBACtB;AAAA,gBACA,SAAU,OAAO;AACf,gCAAc,SAAS,WACnB,SAAS,SAAS,YACnB,SAAS,SAAS;AAAA,gBACvB;AAAA,cACF,IACJ,SAAS,QACT;AAAA,gBACA,KAAK;AACH,yBAAO,SAAS;AAAA,gBAClB,KAAK;AACH,wBAAM,SAAS;AAAA,cACnB;AAAA,UACJ;AACA,gBAAM;AAAA,QACR;AACA,iBAAS,aAAa,UAAU,OAAO,eAAe,WAAW,UAAU;AACzE,cAAI,OAAO,OAAO;AAClB,cAAI,gBAAgB,QAAQ,cAAc,KAAM,YAAW;AAC3D,cAAI,iBAAiB;AACrB,cAAI,SAAS,SAAU,kBAAiB;AAAA;AAEtC,oBAAQ,MAAM;AAAA,cACZ,KAAK;AAAA,cACL,KAAK;AAAA,cACL,KAAK;AACH,iCAAiB;AACjB;AAAA,cACF,KAAK;AACH,wBAAQ,SAAS,UAAU;AAAA,kBACzB,KAAK;AAAA,kBACL,KAAK;AACH,qCAAiB;AACjB;AAAA,kBACF,KAAK;AACH,2BACG,iBAAiB,SAAS,OAC3B;AAAA,sBACE,eAAe,SAAS,QAAQ;AAAA,sBAChC;AAAA,sBACA;AAAA,sBACA;AAAA,sBACA;AAAA,oBACF;AAAA,gBAEN;AAAA,YACJ;AACF,cAAI,gBAAgB;AAClB,6BAAiB;AACjB,uBAAW,SAAS,cAAc;AAClC,gBAAI,WACF,OAAO,YAAY,MAAM,cAAc,gBAAgB,CAAC,IAAI;AAC9D,wBAAY,QAAQ,KACd,gBAAgB,IAClB,QAAQ,aACL,gBACC,SAAS,QAAQ,4BAA4B,KAAK,IAAI,MAC1D,aAAa,UAAU,OAAO,eAAe,IAAI,SAAU,GAAG;AAC5D,qBAAO;AAAA,YACT,CAAC,KACD,QAAQ,aACP,eAAe,QAAQ,MACrB,QAAQ,SAAS,QACd,kBAAkB,eAAe,QAAQ,SAAS,OAClD,uBAAuB,SAAS,GAAG,IACtC,gBAAgB;AAAA,cACf;AAAA,cACA,iBACG,QAAQ,SAAS,OACjB,kBAAkB,eAAe,QAAQ,SAAS,MAC/C,MACC,KAAK,SAAS,KAAK;AAAA,gBAClB;AAAA,gBACA;AAAA,cACF,IAAI,OACR;AAAA,YACJ,GACA,OAAO,aACL,QAAQ,kBACR,eAAe,cAAc,KAC7B,QAAQ,eAAe,OACvB,eAAe,UACf,CAAC,eAAe,OAAO,cACtB,cAAc,OAAO,YAAY,IACnC,WAAW,gBACd,MAAM,KAAK,QAAQ;AACvB,mBAAO;AAAA,UACT;AACA,2BAAiB;AACjB,qBAAW,OAAO,YAAY,MAAM,YAAY;AAChD,cAAI,YAAY,QAAQ;AACtB,qBAAS,IAAI,GAAG,IAAI,SAAS,QAAQ;AACnC,cAAC,YAAY,SAAS,CAAC,GACpB,OAAO,WAAW,cAAc,WAAW,CAAC,GAC5C,kBAAkB;AAAA,gBACjB;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AAAA,mBACK,IAAI,cAAc,QAAQ,GAAI,eAAe,OAAO;AAC7D,iBACE,MAAM,SAAS,YACZ,oBACC,QAAQ;AAAA,cACN;AAAA,YACF,GACD,mBAAmB,OACpB,WAAW,EAAE,KAAK,QAAQ,GAC1B,IAAI,GACN,EAAE,YAAY,SAAS,KAAK,GAAG;AAG/B,cAAC,YAAY,UAAU,OACpB,OAAO,WAAW,cAAc,WAAW,GAAG,GAC9C,kBAAkB;AAAA,gBACjB;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AAAA,mBACG,aAAa,MAAM;AAC1B,gBAAI,eAAe,OAAO,SAAS;AACjC,qBAAO;AAAA,gBACL,gBAAgB,QAAQ;AAAA,gBACxB;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,cACF;AACF,oBAAQ,OAAO,QAAQ;AACvB,kBAAM;AAAA,cACJ,qDACG,sBAAsB,QACnB,uBAAuB,OAAO,KAAK,QAAQ,EAAE,KAAK,IAAI,IAAI,MAC1D,SACJ;AAAA,YACJ;AAAA,UACF;AACA,iBAAO;AAAA,QACT;AACA,iBAAS,YAAY,UAAU,MAAM,SAAS;AAC5C,cAAI,QAAQ,SAAU,QAAO;AAC7B,cAAI,SAAS,CAAC,GACZ,QAAQ;AACV,uBAAa,UAAU,QAAQ,IAAI,IAAI,SAAU,OAAO;AACtD,mBAAO,KAAK,KAAK,SAAS,OAAO,OAAO;AAAA,UAC1C,CAAC;AACD,iBAAO;AAAA,QACT;AACA,iBAAS,gBAAgB,SAAS;AAChC,cAAI,OAAO,QAAQ,SAAS;AAC1B,gBAAI,SAAS,QAAQ;AACrB,oBAAQ,WAAW,OAAO,QAAQ,OAAO,MAAM,YAAY,IAAI;AAC/D,qBAAS,QAAQ;AACjB,gBAAI,WAAW,OAAO;AACtB,qBAAS;AAAA,cACP,SAAU,cAAc;AACtB,oBAAI,MAAM,QAAQ,WAAW,OAAO,QAAQ,SAAS;AACnD,0BAAQ,UAAU;AAClB,0BAAQ,UAAU;AAClB,sBAAI,UAAU,QAAQ;AACtB,0BAAQ,YAAY,QAAQ,MAAM,YAAY,IAAI;AAClD,6BAAW,SAAS,WAChB,SAAS,SAAS,aACnB,SAAS,QAAQ;AAAA,gBACtB;AAAA,cACF;AAAA,cACA,SAAU,OAAO;AACf,oBAAI,MAAM,QAAQ,WAAW,OAAO,QAAQ,SAAS;AACnD,0BAAQ,UAAU;AAClB,0BAAQ,UAAU;AAClB,sBAAI,WAAW,QAAQ;AACvB,0BAAQ,aAAa,SAAS,MAAM,YAAY,IAAI;AACpD,6BAAW,SAAS,WAChB,SAAS,SAAS,YAAc,SAAS,SAAS;AAAA,gBACxD;AAAA,cACF;AAAA,YACF;AACA,qBAAS,QAAQ;AACjB,gBAAI,QAAQ,QAAQ;AAClB,qBAAO,QAAQ;AACf,kBAAI,cAAc,SAAS;AAC3B,2BAAa,OAAO,gBAAgB,OAAO,OAAO;AAAA,YACpD;AACA,mBAAO,QAAQ,YACX,QAAQ,UAAU,GAAK,QAAQ,UAAU;AAAA,UAC/C;AACA,cAAI,MAAM,QAAQ;AAChB,mBACG,SAAS,QAAQ,SAClB,WAAW,UACT,QAAQ;AAAA,cACN;AAAA,cACA;AAAA,YACF,GACF,aAAa,UACX,QAAQ;AAAA,cACN;AAAA,cACA;AAAA,YACF,GACF,OAAO;AAEX,gBAAM,QAAQ;AAAA,QAChB;AACA,iBAAS,oBAAoB;AAC3B,cAAI,aAAa,qBAAqB;AACtC,mBAAS,cACP,QAAQ;AAAA,YACN;AAAA,UACF;AACF,iBAAO;AAAA,QACT;AACA,iBAAS,yBAAyB;AAChC,+BAAqB;AAAA,QACvB;AACA,iBAAS,YAAY,MAAM;AACzB,cAAI,SAAS;AACX,gBAAI;AACF,kBAAI,iBAAiB,YAAY,KAAK,OAAO,GAAG,MAAM,GAAG,CAAC;AAC1D,iCAAmB,UAAU,OAAO,aAAa,GAAG;AAAA,gBAClD;AAAA,gBACA;AAAA,cACF,EAAE;AAAA,YACJ,SAAS,MAAM;AACb,gCAAkB,SAAU,UAAU;AACpC,0BAAO,+BACH,6BAA6B,MAC/B,gBAAgB,OAAO,kBACrB,QAAQ;AAAA,kBACN;AAAA,gBACF;AACJ,oBAAI,UAAU,IAAI,eAAe;AACjC,wBAAQ,MAAM,YAAY;AAC1B,wBAAQ,MAAM,YAAY,MAAM;AAAA,cAClC;AAAA,YACF;AACF,iBAAO,gBAAgB,IAAI;AAAA,QAC7B;AACA,iBAAS,gBAAgB,QAAQ;AAC/B,iBAAO,IAAI,OAAO,UAAU,eAAe,OAAO,iBAC9C,IAAI,eAAe,MAAM,IACzB,OAAO,CAAC;AAAA,QACd;AACA,iBAAS,YAAY,cAAc,mBAAmB;AACpD,gCAAsB,gBAAgB,KACpC,QAAQ;AAAA,YACN;AAAA,UACF;AACF,0BAAgB;AAAA,QAClB;AACA,iBAAS,6BAA6B,aAAa,SAAS,QAAQ;AAClE,cAAI,QAAQ,qBAAqB;AACjC,cAAI,SAAS;AACX,gBAAI,MAAM,MAAM;AACd,kBAAI;AACF,8BAAc,KAAK;AACnB,4BAAY,WAAY;AACtB,yBAAO,6BAA6B,aAAa,SAAS,MAAM;AAAA,gBAClE,CAAC;AACD;AAAA,cACF,SAAS,OAAO;AACd,qCAAqB,aAAa,KAAK,KAAK;AAAA,cAC9C;AAAA,gBACG,sBAAqB,WAAW;AACvC,cAAI,qBAAqB,aAAa,UAChC,QAAQ,gBAAgB,qBAAqB,YAAY,GAC1D,qBAAqB,aAAa,SAAS,GAC5C,OAAO,KAAK,KACZ,QAAQ,WAAW;AAAA,QACzB;AACA,iBAAS,cAAc,OAAO;AAC5B,cAAI,CAAC,YAAY;AACf,yBAAa;AACb,gBAAI,IAAI;AACR,gBAAI;AACF,qBAAO,IAAI,MAAM,QAAQ,KAAK;AAC5B,oBAAI,WAAW,MAAM,CAAC;AACtB,mBAAG;AACD,uCAAqB,gBAAgB;AACrC,sBAAI,eAAe,SAAS,KAAE;AAC9B,sBAAI,SAAS,cAAc;AACzB,wBAAI,qBAAqB,eAAe;AACtC,4BAAM,CAAC,IAAI;AACX,4BAAM,OAAO,GAAG,CAAC;AACjB;AAAA,oBACF;AACA,+BAAW;AAAA,kBACb,MAAO;AAAA,gBACT,SAAS;AAAA,cACX;AACA,oBAAM,SAAS;AAAA,YACjB,SAAS,OAAO;AACd,oBAAM,OAAO,GAAG,IAAI,CAAC,GAAG,qBAAqB,aAAa,KAAK,KAAK;AAAA,YACtE,UAAE;AACA,2BAAa;AAAA,YACf;AAAA,UACF;AAAA,QACF;AACA,wBAAgB,OAAO,kCACrB,eACE,OAAO,+BAA+B,+BACxC,+BAA+B,4BAA4B,MAAM,CAAC;AACpE,YAAI,qBAAqB,uBAAO,IAAI,4BAA4B,GAC9D,oBAAoB,uBAAO,IAAI,cAAc,GAC7C,sBAAsB,uBAAO,IAAI,gBAAgB,GACjD,yBAAyB,uBAAO,IAAI,mBAAmB,GACvD,sBAAsB,uBAAO,IAAI,gBAAgB,GACjD,sBAAsB,uBAAO,IAAI,gBAAgB,GACjD,qBAAqB,uBAAO,IAAI,eAAe,GAC/C,yBAAyB,uBAAO,IAAI,mBAAmB,GACvD,sBAAsB,uBAAO,IAAI,gBAAgB,GACjD,2BAA2B,uBAAO,IAAI,qBAAqB,GAC3D,kBAAkB,uBAAO,IAAI,YAAY,GACzC,kBAAkB,uBAAO,IAAI,YAAY,GACzC,sBAAsB,uBAAO,IAAI,gBAAgB,GACjD,wBAAwB,OAAO,UAC/B,0CAA0C,CAAC,GAC3C,uBAAuB;AAAA,UACrB,WAAW,WAAY;AACrB,mBAAO;AAAA,UACT;AAAA,UACA,oBAAoB,SAAU,gBAAgB;AAC5C,qBAAS,gBAAgB,aAAa;AAAA,UACxC;AAAA,UACA,qBAAqB,SAAU,gBAAgB;AAC7C,qBAAS,gBAAgB,cAAc;AAAA,UACzC;AAAA,UACA,iBAAiB,SAAU,gBAAgB;AACzC,qBAAS,gBAAgB,UAAU;AAAA,UACrC;AAAA,QACF,GACA,SAAS,OAAO,QAChB,cAAc,CAAC;AACjB,eAAO,OAAO,WAAW;AACzB,kBAAU,UAAU,mBAAmB,CAAC;AACxC,kBAAU,UAAU,WAAW,SAAU,cAAc,UAAU;AAC/D,cACE,aAAa,OAAO,gBACpB,eAAe,OAAO,gBACtB,QAAQ;AAER,kBAAM;AAAA,cACJ;AAAA,YACF;AACF,eAAK,QAAQ,gBAAgB,MAAM,cAAc,UAAU,UAAU;AAAA,QACvE;AACA,kBAAU,UAAU,cAAc,SAAU,UAAU;AACpD,eAAK,QAAQ,mBAAmB,MAAM,UAAU,aAAa;AAAA,QAC/D;AACA,YAAI,iBAAiB;AAAA,UACnB,WAAW;AAAA,YACT;AAAA,YACA;AAAA,UACF;AAAA,UACA,cAAc;AAAA,YACZ;AAAA,YACA;AAAA,UACF;AAAA,QACF;AACA,aAAK,UAAU;AACb,yBAAe,eAAe,MAAM,KAClC,yBAAyB,QAAQ,eAAe,MAAM,CAAC;AAC3D,uBAAe,YAAY,UAAU;AACrC,yBAAiB,cAAc,YAAY,IAAI,eAAe;AAC9D,uBAAe,cAAc;AAC7B,eAAO,gBAAgB,UAAU,SAAS;AAC1C,uBAAe,uBAAuB;AACtC,YAAI,cAAc,MAAM,SACtB,yBAAyB,uBAAO,IAAI,wBAAwB,GAC5D,uBAAuB;AAAA,UACrB,GAAG;AAAA,UACH,GAAG;AAAA,UACH,GAAG;AAAA,UACH,GAAG;AAAA,UACH,UAAU;AAAA,UACV,kBAAkB;AAAA,UAClB,kBAAkB;AAAA,UAClB,yBAAyB;AAAA,UACzB,eAAe;AAAA,UACf,cAAc,CAAC;AAAA,UACf,iBAAiB;AAAA,UACjB,4BAA4B;AAAA,QAC9B,GACA,iBAAiB,OAAO,UAAU,gBAClC,aAAa,QAAQ,aACjB,QAAQ,aACR,WAAY;AACV,iBAAO;AAAA,QACT;AACN,yBAAiB;AAAA,UACf,0BAA0B,SAAU,mBAAmB;AACrD,mBAAO,kBAAkB;AAAA,UAC3B;AAAA,QACF;AACA,YAAI,4BAA4B;AAChC,YAAI,yBAAyB,CAAC;AAC9B,YAAI,yBAAyB,eAAe,yBAAyB;AAAA,UACnE;AAAA,UACA;AAAA,QACF,EAAE;AACF,YAAI,wBAAwB,WAAW,YAAY,YAAY,CAAC;AAChE,YAAI,mBAAmB,OACrB,6BAA6B,QAC7B,oBACE,eAAe,OAAO,cAClB,cACA,SAAU,OAAO;AACf,cACE,aAAa,OAAO,UACpB,eAAe,OAAO,OAAO,YAC7B;AACA,gBAAI,QAAQ,IAAI,OAAO,WAAW,SAAS;AAAA,cACzC,SAAS;AAAA,cACT,YAAY;AAAA,cACZ,SACE,aAAa,OAAO,SACpB,SAAS,SACT,aAAa,OAAO,MAAM,UACtB,OAAO,MAAM,OAAO,IACpB,OAAO,KAAK;AAAA,cAClB;AAAA,YACF,CAAC;AACD,gBAAI,CAAC,OAAO,cAAc,KAAK,EAAG;AAAA,UACpC,WACE,aAAa,OAAO,WACpB,eAAe,OAAO,QAAQ,MAC9B;AACA,oBAAQ,KAAK,qBAAqB,KAAK;AACvC;AAAA,UACF;AACA,kBAAQ,MAAM,KAAK;AAAA,QACrB,GACN,6BAA6B,OAC7B,kBAAkB,MAClB,gBAAgB,GAChB,oBAAoB,OACpB,aAAa,OACb,yBACE,eAAe,OAAO,iBAClB,SAAU,UAAU;AAClB,yBAAe,WAAY;AACzB,mBAAO,eAAe,QAAQ;AAAA,UAChC,CAAC;AAAA,QACH,IACA;AACR,yBAAiB,OAAO,OAAO;AAAA,UAC7B,WAAW;AAAA,UACX,GAAG,SAAU,MAAM;AACjB,mBAAO,kBAAkB,EAAE,aAAa,IAAI;AAAA,UAC9C;AAAA,QACF,CAAC;AACD,YAAI,SAAS;AAAA,UACX,KAAK;AAAA,UACL,SAAS,SAAU,UAAU,aAAa,gBAAgB;AACxD;AAAA,cACE;AAAA,cACA,WAAY;AACV,4BAAY,MAAM,MAAM,SAAS;AAAA,cACnC;AAAA,cACA;AAAA,YACF;AAAA,UACF;AAAA,UACA,OAAO,SAAU,UAAU;AACzB,gBAAI,IAAI;AACR,wBAAY,UAAU,WAAY;AAChC;AAAA,YACF,CAAC;AACD,mBAAO;AAAA,UACT;AAAA,UACA,SAAS,SAAU,UAAU;AAC3B,mBACE,YAAY,UAAU,SAAU,OAAO;AACrC,qBAAO;AAAA,YACT,CAAC,KAAK,CAAC;AAAA,UAEX;AAAA,UACA,MAAM,SAAU,UAAU;AACxB,gBAAI,CAAC,eAAe,QAAQ;AAC1B,oBAAM;AAAA,gBACJ;AAAA,cACF;AACF,mBAAO;AAAA,UACT;AAAA,QACF;AACA,gBAAQ,WAAW;AACnB,gBAAQ,WAAW;AACnB,gBAAQ,YAAY;AACpB,gBAAQ,WAAW;AACnB,gBAAQ,WAAW;AACnB,gBAAQ,gBAAgB;AACxB,gBAAQ,aAAa;AACrB,gBAAQ,WAAW;AACnB,gBAAQ,kEACN;AACF,gBAAQ,qBAAqB;AAC7B,gBAAQ,MAAM,SAAU,UAAU;AAChC,cAAI,eAAe,qBAAqB,UACtC,oBAAoB;AACtB;AACA,cAAI,QAAS,qBAAqB,WAC9B,SAAS,eAAe,eAAe,CAAC,GAC1C,kBAAkB;AACpB,cAAI;AACF,gBAAI,SAAS,SAAS;AAAA,UACxB,SAAS,OAAO;AACd,iCAAqB,aAAa,KAAK,KAAK;AAAA,UAC9C;AACA,cAAI,IAAI,qBAAqB,aAAa;AACxC,kBACG,YAAY,cAAc,iBAAiB,GAC3C,WAAW,gBAAgB,qBAAqB,YAAY,GAC5D,qBAAqB,aAAa,SAAS,GAC5C;AAEJ,cACE,SAAS,UACT,aAAa,OAAO,UACpB,eAAe,OAAO,OAAO,MAC7B;AACA,gBAAI,WAAW;AACf,mCAAuB,WAAY;AACjC,iCACE,sBACE,oBAAoB,MACtB,QAAQ;AAAA,gBACN;AAAA,cACF;AAAA,YACJ,CAAC;AACD,mBAAO;AAAA,cACL,MAAM,SAAU,SAAS,QAAQ;AAC/B,kCAAkB;AAClB,yBAAS;AAAA,kBACP,SAAU,aAAa;AACrB,gCAAY,cAAc,iBAAiB;AAC3C,wBAAI,MAAM,mBAAmB;AAC3B,0BAAI;AACF,sCAAc,KAAK,GACjB,YAAY,WAAY;AACtB,iCAAO;AAAA,4BACL;AAAA,4BACA;AAAA,4BACA;AAAA,0BACF;AAAA,wBACF,CAAC;AAAA,sBACL,SAAS,SAAS;AAChB,6CAAqB,aAAa,KAAK,OAAO;AAAA,sBAChD;AACA,0BAAI,IAAI,qBAAqB,aAAa,QAAQ;AAChD,4BAAI,eAAe;AAAA,0BACjB,qBAAqB;AAAA,wBACvB;AACA,6CAAqB,aAAa,SAAS;AAC3C,+BAAO,YAAY;AAAA,sBACrB;AAAA,oBACF,MAAO,SAAQ,WAAW;AAAA,kBAC5B;AAAA,kBACA,SAAU,OAAO;AACf,gCAAY,cAAc,iBAAiB;AAC3C,wBAAI,qBAAqB,aAAa,UAChC,QAAQ;AAAA,sBACR,qBAAqB;AAAA,oBACvB,GACC,qBAAqB,aAAa,SAAS,GAC5C,OAAO,KAAK,KACZ,OAAO,KAAK;AAAA,kBAClB;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AACA,cAAI,uBAAuB;AAC3B,sBAAY,cAAc,iBAAiB;AAC3C,gBAAM,sBACH,cAAc,KAAK,GACpB,MAAM,MAAM,UACV,uBAAuB,WAAY;AACjC,+BACE,sBACE,oBAAoB,MACtB,QAAQ;AAAA,cACN;AAAA,YACF;AAAA,UACJ,CAAC,GACF,qBAAqB,WAAW;AACnC,cAAI,IAAI,qBAAqB,aAAa;AACxC,kBACI,WAAW,gBAAgB,qBAAqB,YAAY,GAC7D,qBAAqB,aAAa,SAAS,GAC5C;AAEJ,iBAAO;AAAA,YACL,MAAM,SAAU,SAAS,QAAQ;AAC/B,gCAAkB;AAClB,oBAAM,qBACA,qBAAqB,WAAW,OAClC,YAAY,WAAY;AACtB,uBAAO;AAAA,kBACL;AAAA,kBACA;AAAA,kBACA;AAAA,gBACF;AAAA,cACF,CAAC,KACD,QAAQ,oBAAoB;AAAA,YAClC;AAAA,UACF;AAAA,QACF;AACA,gBAAQ,QAAQ,SAAU,IAAI;AAC5B,iBAAO,WAAY;AACjB,mBAAO,GAAG,MAAM,MAAM,SAAS;AAAA,UACjC;AAAA,QACF;AACA,gBAAQ,cAAc,WAAY;AAChC,iBAAO;AAAA,QACT;AACA,gBAAQ,oBAAoB,WAAY;AACtC,cAAI,kBAAkB,qBAAqB;AAC3C,iBAAO,SAAS,kBAAkB,OAAO,gBAAgB;AAAA,QAC3D;AACA,gBAAQ,eAAe,SAAU,SAAS,QAAQ,UAAU;AAC1D,cAAI,SAAS,WAAW,WAAW;AACjC,kBAAM;AAAA,cACJ,0DACE,UACA;AAAA,YACJ;AACF,cAAI,QAAQ,OAAO,CAAC,GAAG,QAAQ,KAAK,GAClC,MAAM,QAAQ,KACd,QAAQ,QAAQ;AAClB,cAAI,QAAQ,QAAQ;AAClB,gBAAI;AACJ,eAAG;AACD,kBACE,eAAe,KAAK,QAAQ,KAAK,MAChC,2BAA2B,OAAO;AAAA,gBACjC;AAAA,gBACA;AAAA,cACF,EAAE,QACF,yBAAyB,gBACzB;AACA,2CAA2B;AAC3B,sBAAM;AAAA,cACR;AACA,yCAA2B,WAAW,OAAO;AAAA,YAC/C;AACA,yCAA6B,QAAQ,SAAS;AAC9C,wBAAY,MAAM,MACf,uBAAuB,OAAO,GAAG,GAAI,MAAM,KAAK,OAAO;AAC1D,iBAAK,YAAY;AACf,eAAC,eAAe,KAAK,QAAQ,QAAQ,KACnC,UAAU,YACV,aAAa,YACb,eAAe,YACd,UAAU,YAAY,WAAW,OAAO,QACxC,MAAM,QAAQ,IAAI,OAAO,QAAQ;AAAA,UACxC;AACA,cAAI,WAAW,UAAU,SAAS;AAClC,cAAI,MAAM,SAAU,OAAM,WAAW;AAAA,mBAC5B,IAAI,UAAU;AACrB,uCAA2B,MAAM,QAAQ;AACzC,qBAAS,IAAI,GAAG,IAAI,UAAU;AAC5B,uCAAyB,CAAC,IAAI,UAAU,IAAI,CAAC;AAC/C,kBAAM,WAAW;AAAA,UACnB;AACA,kBAAQ;AAAA,YACN,QAAQ;AAAA,YACR;AAAA,YACA;AAAA,YACA;AAAA,YACA,QAAQ;AAAA,YACR,QAAQ;AAAA,UACV;AACA,eAAK,MAAM,GAAG,MAAM,UAAU,QAAQ;AACpC,8BAAkB,UAAU,GAAG,CAAC;AAClC,iBAAO;AAAA,QACT;AACA,gBAAQ,gBAAgB,SAAU,cAAc;AAC9C,yBAAe;AAAA,YACb,UAAU;AAAA,YACV,eAAe;AAAA,YACf,gBAAgB;AAAA,YAChB,cAAc;AAAA,YACd,UAAU;AAAA,YACV,UAAU;AAAA,UACZ;AACA,uBAAa,WAAW;AACxB,uBAAa,WAAW;AAAA,YACtB,UAAU;AAAA,YACV,UAAU;AAAA,UACZ;AACA,uBAAa,mBAAmB;AAChC,uBAAa,oBAAoB;AACjC,iBAAO;AAAA,QACT;AACA,gBAAQ,gBAAgB,SAAU,MAAM,QAAQ,UAAU;AACxD,mBAAS,IAAI,GAAG,IAAI,UAAU,QAAQ;AACpC,8BAAkB,UAAU,CAAC,CAAC;AAChC,cAAI,CAAC;AACL,cAAI,MAAM;AACV,cAAI,QAAQ;AACV,iBAAK,YAAa,6BAChB,EAAE,YAAY,WACd,SAAS,WACP,4BAA4B,MAC9B,QAAQ;AAAA,cACN;AAAA,YACF,IACF,YAAY,MAAM,MACf,uBAAuB,OAAO,GAAG,GAAI,MAAM,KAAK,OAAO,MAC1D;AACE,6BAAe,KAAK,QAAQ,QAAQ,KAClC,UAAU,YACV,aAAa,YACb,eAAe,aACd,EAAE,QAAQ,IAAI,OAAO,QAAQ;AACpC,cAAI,iBAAiB,UAAU,SAAS;AACxC,cAAI,MAAM,eAAgB,GAAE,WAAW;AAAA,mBAC9B,IAAI,gBAAgB;AAC3B,qBACM,aAAa,MAAM,cAAc,GAAG,KAAK,GAC7C,KAAK,gBACL;AAEA,yBAAW,EAAE,IAAI,UAAU,KAAK,CAAC;AACnC,mBAAO,UAAU,OAAO,OAAO,UAAU;AACzC,cAAE,WAAW;AAAA,UACf;AACA,cAAI,QAAQ,KAAK;AACf,iBAAK,YAAc,iBAAiB,KAAK,cAAe;AACtD,yBAAW,EAAE,QAAQ,MAAM,EAAE,QAAQ,IAAI,eAAe,QAAQ;AACpE,iBACE;AAAA,YACE;AAAA,YACA,eAAe,OAAO,OAClB,KAAK,eAAe,KAAK,QAAQ,YACjC;AAAA,UACN;AACF,cAAI,WAAW,MAAM,qBAAqB;AAC1C,iBAAO;AAAA,YACL;AAAA,YACA;AAAA,YACA;AAAA,YACA,SAAS;AAAA,YACT,WAAW,MAAM,uBAAuB,IAAI;AAAA,YAC5C,WAAW,WAAW,YAAY,IAAI,CAAC,IAAI;AAAA,UAC7C;AAAA,QACF;AACA,gBAAQ,YAAY,WAAY;AAC9B,cAAI,YAAY,EAAE,SAAS,KAAK;AAChC,iBAAO,KAAK,SAAS;AACrB,iBAAO;AAAA,QACT;AACA,gBAAQ,aAAa,SAAU,QAAQ;AACrC,kBAAQ,UAAU,OAAO,aAAa,kBAClC,QAAQ;AAAA,YACN;AAAA,UACF,IACA,eAAe,OAAO,SACpB,QAAQ;AAAA,YACN;AAAA,YACA,SAAS,SAAS,SAAS,OAAO;AAAA,UACpC,IACA,MAAM,OAAO,UACb,MAAM,OAAO,UACb,QAAQ;AAAA,YACN;AAAA,YACA,MAAM,OAAO,SACT,6CACA;AAAA,UACN;AACN,kBAAQ,UACN,QAAQ,OAAO,gBACf,QAAQ;AAAA,YACN;AAAA,UACF;AACF,cAAI,cAAc,EAAE,UAAU,wBAAwB,OAAe,GACnE;AACF,iBAAO,eAAe,aAAa,eAAe;AAAA,YAChD,YAAY;AAAA,YACZ,cAAc;AAAA,YACd,KAAK,WAAY;AACf,qBAAO;AAAA,YACT;AAAA,YACA,KAAK,SAAU,MAAM;AACnB,wBAAU;AACV,qBAAO,QACL,OAAO,gBACN,OAAO,eAAe,QAAQ,QAAQ,EAAE,OAAO,KAAK,CAAC,GACrD,OAAO,cAAc;AAAA,YAC1B;AAAA,UACF,CAAC;AACD,iBAAO;AAAA,QACT;AACA,gBAAQ,iBAAiB;AACzB,gBAAQ,OAAO,SAAU,MAAM;AAC7B,iBAAO,EAAE,SAAS,IAAI,SAAS,KAAK;AACpC,cAAI,WAAW;AAAA,YACX,UAAU;AAAA,YACV,UAAU;AAAA,YACV,OAAO;AAAA,UACT,GACA,SAAS;AAAA,YACP,MAAM;AAAA,YACN,OAAO;AAAA,YACP,KAAK;AAAA,YACL,OAAO;AAAA,YACP,OAAO;AAAA,YACP,YAAY,MAAM,uBAAuB;AAAA,YACzC,WAAW,QAAQ,aAAa,QAAQ,WAAW,QAAQ,IAAI;AAAA,UACjE;AACF,eAAK,UAAU;AACf,mBAAS,aAAa,CAAC,EAAE,SAAS,OAAO,CAAC;AAC1C,iBAAO;AAAA,QACT;AACA,gBAAQ,OAAO,SAAU,MAAM,SAAS;AACtC,kBAAQ,QACN,QAAQ;AAAA,YACN;AAAA,YACA,SAAS,OAAO,SAAS,OAAO;AAAA,UAClC;AACF,oBAAU;AAAA,YACR,UAAU;AAAA,YACV;AAAA,YACA,SAAS,WAAW,UAAU,OAAO;AAAA,UACvC;AACA,cAAI;AACJ,iBAAO,eAAe,SAAS,eAAe;AAAA,YAC5C,YAAY;AAAA,YACZ,cAAc;AAAA,YACd,KAAK,WAAY;AACf,qBAAO;AAAA,YACT;AAAA,YACA,KAAK,SAAU,MAAM;AACnB,wBAAU;AACV,mBAAK,QACH,KAAK,gBACJ,OAAO,eAAe,MAAM,QAAQ,EAAE,OAAO,KAAK,CAAC,GACnD,KAAK,cAAc;AAAA,YACxB;AAAA,UACF,CAAC;AACD,iBAAO;AAAA,QACT;AACA,gBAAQ,kBAAkB,SAAU,OAAO;AACzC,cAAI,iBAAiB,qBAAqB,GACxC,oBAAoB,CAAC;AACvB,4BAAkB,iBAAiB,oBAAI,IAAI;AAC3C,+BAAqB,IAAI;AACzB,cAAI;AACF,gBAAI,cAAc,MAAM,GACtB,0BAA0B,qBAAqB;AACjD,qBAAS,2BACP,wBAAwB,mBAAmB,WAAW;AACxD,yBAAa,OAAO,eAClB,SAAS,eACT,eAAe,OAAO,YAAY,SACjC,qBAAqB,oBACtB,YAAY,KAAK,wBAAwB,sBAAsB,GAC/D,YAAY,KAAK,MAAM,iBAAiB;AAAA,UAC5C,SAAS,OAAO;AACd,8BAAkB,KAAK;AAAA,UACzB,UAAE;AACA,qBAAS,kBACP,kBAAkB,mBAChB,QAAQ,kBAAkB,eAAe,MAC3C,kBAAkB,eAAe,MAAM,GACvC,KAAK,SACH,QAAQ;AAAA,cACN;AAAA,YACF,IACF,SAAS,kBACP,SAAS,kBAAkB,UAC1B,SAAS,eAAe,SACvB,eAAe,UAAU,kBAAkB,SAC3C,QAAQ;AAAA,cACN;AAAA,YACF,GACD,eAAe,QAAQ,kBAAkB,QAC3C,qBAAqB,IAAI;AAAA,UAC9B;AAAA,QACF;AACA,gBAAQ,2BAA2B,WAAY;AAC7C,iBAAO,kBAAkB,EAAE,gBAAgB;AAAA,QAC7C;AACA,gBAAQ,MAAM,SAAU,QAAQ;AAC9B,iBAAO,kBAAkB,EAAE,IAAI,MAAM;AAAA,QACvC;AACA,gBAAQ,iBAAiB,SAAU,QAAQ,cAAc,WAAW;AAClE,iBAAO,kBAAkB,EAAE;AAAA,YACzB;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AACA,gBAAQ,cAAc,SAAU,UAAU,MAAM;AAC9C,iBAAO,kBAAkB,EAAE,YAAY,UAAU,IAAI;AAAA,QACvD;AACA,gBAAQ,aAAa,SAAU,SAAS;AACtC,cAAI,aAAa,kBAAkB;AACnC,kBAAQ,aAAa,uBACnB,QAAQ;AAAA,YACN;AAAA,UACF;AACF,iBAAO,WAAW,WAAW,OAAO;AAAA,QACtC;AACA,gBAAQ,gBAAgB,SAAU,OAAO,aAAa;AACpD,iBAAO,kBAAkB,EAAE,cAAc,OAAO,WAAW;AAAA,QAC7D;AACA,gBAAQ,mBAAmB,SAAU,OAAO,cAAc;AACxD,iBAAO,kBAAkB,EAAE,iBAAiB,OAAO,YAAY;AAAA,QACjE;AACA,gBAAQ,YAAY,SAAU,QAAQ,MAAM;AAC1C,kBAAQ,UACN,QAAQ;AAAA,YACN;AAAA,UACF;AACF,iBAAO,kBAAkB,EAAE,UAAU,QAAQ,IAAI;AAAA,QACnD;AACA,gBAAQ,iBAAiB,SAAU,UAAU;AAC3C,iBAAO,kBAAkB,EAAE,eAAe,QAAQ;AAAA,QACpD;AACA,gBAAQ,QAAQ,WAAY;AAC1B,iBAAO,kBAAkB,EAAE,MAAM;AAAA,QACnC;AACA,gBAAQ,sBAAsB,SAAU,KAAK,QAAQ,MAAM;AACzD,iBAAO,kBAAkB,EAAE,oBAAoB,KAAK,QAAQ,IAAI;AAAA,QAClE;AACA,gBAAQ,qBAAqB,SAAU,QAAQ,MAAM;AACnD,kBAAQ,UACN,QAAQ;AAAA,YACN;AAAA,UACF;AACF,iBAAO,kBAAkB,EAAE,mBAAmB,QAAQ,IAAI;AAAA,QAC5D;AACA,gBAAQ,kBAAkB,SAAU,QAAQ,MAAM;AAChD,kBAAQ,UACN,QAAQ;AAAA,YACN;AAAA,UACF;AACF,iBAAO,kBAAkB,EAAE,gBAAgB,QAAQ,IAAI;AAAA,QACzD;AACA,gBAAQ,UAAU,SAAU,QAAQ,MAAM;AACxC,iBAAO,kBAAkB,EAAE,QAAQ,QAAQ,IAAI;AAAA,QACjD;AACA,gBAAQ,gBAAgB,SAAU,aAAa,SAAS;AACtD,iBAAO,kBAAkB,EAAE,cAAc,aAAa,OAAO;AAAA,QAC/D;AACA,gBAAQ,aAAa,SAAU,SAAS,YAAY,MAAM;AACxD,iBAAO,kBAAkB,EAAE,WAAW,SAAS,YAAY,IAAI;AAAA,QACjE;AACA,gBAAQ,SAAS,SAAU,cAAc;AACvC,iBAAO,kBAAkB,EAAE,OAAO,YAAY;AAAA,QAChD;AACA,gBAAQ,WAAW,SAAU,cAAc;AACzC,iBAAO,kBAAkB,EAAE,SAAS,YAAY;AAAA,QAClD;AACA,gBAAQ,uBAAuB,SAC7B,WACA,aACA,mBACA;AACA,iBAAO,kBAAkB,EAAE;AAAA,YACzB;AAAA,YACA;AAAA,YACA;AAAA,UACF;AAAA,QACF;AACA,gBAAQ,gBAAgB,WAAY;AAClC,iBAAO,kBAAkB,EAAE,cAAc;AAAA,QAC3C;AACA,gBAAQ,UAAU;AAClB,wBAAgB,OAAO,kCACrB,eACE,OAAO,+BAA+B,8BACxC,+BAA+B,2BAA2B,MAAM,CAAC;AAAA,MACrE,GAAG;AAAA;AAAA;;;ACnwCL;AAAA;AAAA;AAEA,UAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,eAAO,UAAU;AAAA,MACnB,OAAO;AACL,eAAO,UAAU;AAAA,MACnB;AAAA;AAAA;;;ACNA;AAAA;AAAA;AAWA,UAAI,qBAAqB,uBAAO,IAAI,4BAA4B;AAAhE,UACE,sBAAsB,uBAAO,IAAI,gBAAgB;AACnD,eAAS,QAAQ,MAAM,QAAQ,UAAU;AACvC,YAAI,MAAM;AACV,mBAAW,aAAa,MAAM,KAAK;AACnC,mBAAW,OAAO,QAAQ,MAAM,KAAK,OAAO;AAC5C,YAAI,SAAS,QAAQ;AACnB,qBAAW,CAAC;AACZ,mBAAS,YAAY;AACnB,sBAAU,aAAa,SAAS,QAAQ,IAAI,OAAO,QAAQ;AAAA,QAC/D,MAAO,YAAW;AAClB,iBAAS,SAAS;AAClB,eAAO;AAAA,UACL,UAAU;AAAA,UACV;AAAA,UACA;AAAA,UACA,KAAK,WAAW,SAAS,SAAS;AAAA,UAClC,OAAO;AAAA,QACT;AAAA,MACF;AACA,cAAQ,WAAW;AACnB,cAAQ,MAAM;AACd,cAAQ,OAAO;AAAA;AAAA;;;ACjCf;AAAA;AAAA;AAWA,uBAAiB,QAAQ,IAAI,aAC1B,WAAY;AACX,iBAAS,yBAAyB,MAAM;AACtC,cAAI,QAAQ,KAAM,QAAO;AACzB,cAAI,eAAe,OAAO;AACxB,mBAAO,KAAK,aAAa,yBACrB,OACA,KAAK,eAAe,KAAK,QAAQ;AACvC,cAAI,aAAa,OAAO,KAAM,QAAO;AACrC,kBAAQ,MAAM;AAAA,YACZ,KAAK;AACH,qBAAO;AAAA,YACT,KAAK;AACH,qBAAO;AAAA,YACT,KAAK;AACH,qBAAO;AAAA,YACT,KAAK;AACH,qBAAO;AAAA,YACT,KAAK;AACH,qBAAO;AAAA,YACT,KAAK;AACH,qBAAO;AAAA,UACX;AACA,cAAI,aAAa,OAAO;AACtB,oBACG,aAAa,OAAO,KAAK,OACxB,QAAQ;AAAA,cACN;AAAA,YACF,GACF,KAAK,UACL;AAAA,cACA,KAAK;AACH,uBAAO;AAAA,cACT,KAAK;AACH,uBAAO,KAAK,eAAe;AAAA,cAC7B,KAAK;AACH,wBAAQ,KAAK,SAAS,eAAe,aAAa;AAAA,cACpD,KAAK;AACH,oBAAI,YAAY,KAAK;AACrB,uBAAO,KAAK;AACZ,yBACI,OAAO,UAAU,eAAe,UAAU,QAAQ,IACnD,OAAO,OAAO,OAAO,gBAAgB,OAAO,MAAM;AACrD,uBAAO;AAAA,cACT,KAAK;AACH,uBACG,YAAY,KAAK,eAAe,MACjC,SAAS,YACL,YACA,yBAAyB,KAAK,IAAI,KAAK;AAAA,cAE/C,KAAK;AACH,4BAAY,KAAK;AACjB,uBAAO,KAAK;AACZ,oBAAI;AACF,yBAAO,yBAAyB,KAAK,SAAS,CAAC;AAAA,gBACjD,SAAS,GAAG;AAAA,gBAAC;AAAA,YACjB;AACF,iBAAO;AAAA,QACT;AACA,iBAAS,mBAAmB,OAAO;AACjC,iBAAO,KAAK;AAAA,QACd;AACA,iBAAS,uBAAuB,OAAO;AACrC,cAAI;AACF,+BAAmB,KAAK;AACxB,gBAAI,2BAA2B;AAAA,UACjC,SAAS,GAAG;AACV,uCAA2B;AAAA,UAC7B;AACA,cAAI,0BAA0B;AAC5B,uCAA2B;AAC3B,gBAAI,wBAAwB,yBAAyB;AACrD,gBAAI,oCACD,eAAe,OAAO,UACrB,OAAO,eACP,MAAM,OAAO,WAAW,KAC1B,MAAM,YAAY,QAClB;AACF,kCAAsB;AAAA,cACpB;AAAA,cACA;AAAA,cACA;AAAA,YACF;AACA,mBAAO,mBAAmB,KAAK;AAAA,UACjC;AAAA,QACF;AACA,iBAAS,YAAY,MAAM;AACzB,cAAI,SAAS,oBAAqB,QAAO;AACzC,cACE,aAAa,OAAO,QACpB,SAAS,QACT,KAAK,aAAa;AAElB,mBAAO;AACT,cAAI;AACF,gBAAI,OAAO,yBAAyB,IAAI;AACxC,mBAAO,OAAO,MAAM,OAAO,MAAM;AAAA,UACnC,SAAS,GAAG;AACV,mBAAO;AAAA,UACT;AAAA,QACF;AACA,iBAAS,WAAW;AAClB,cAAI,aAAa,qBAAqB;AACtC,iBAAO,SAAS,aAAa,OAAO,WAAW,SAAS;AAAA,QAC1D;AACA,iBAAS,eAAe;AACtB,iBAAO,MAAM,uBAAuB;AAAA,QACtC;AACA,iBAAS,YAAY,QAAQ;AAC3B,cAAI,eAAe,KAAK,QAAQ,KAAK,GAAG;AACtC,gBAAI,SAAS,OAAO,yBAAyB,QAAQ,KAAK,EAAE;AAC5D,gBAAI,UAAU,OAAO,eAAgB,QAAO;AAAA,UAC9C;AACA,iBAAO,WAAW,OAAO;AAAA,QAC3B;AACA,iBAAS,2BAA2B,OAAO,aAAa;AACtD,mBAAS,wBAAwB;AAC/B,2CACI,6BAA6B,MAC/B,QAAQ;AAAA,cACN;AAAA,cACA;AAAA,YACF;AAAA,UACJ;AACA,gCAAsB,iBAAiB;AACvC,iBAAO,eAAe,OAAO,OAAO;AAAA,YAClC,KAAK;AAAA,YACL,cAAc;AAAA,UAChB,CAAC;AAAA,QACH;AACA,iBAAS,yCAAyC;AAChD,cAAI,gBAAgB,yBAAyB,KAAK,IAAI;AACtD,iCAAuB,aAAa,MAChC,uBAAuB,aAAa,IAAI,MAC1C,QAAQ;AAAA,YACN;AAAA,UACF;AACF,0BAAgB,KAAK,MAAM;AAC3B,iBAAO,WAAW,gBAAgB,gBAAgB;AAAA,QACpD;AACA,iBAAS,aAAa,MAAM,KAAK,OAAO,OAAO,YAAY,WAAW;AACpE,cAAI,UAAU,MAAM;AACpB,iBAAO;AAAA,YACL,UAAU;AAAA,YACV;AAAA,YACA;AAAA,YACA;AAAA,YACA,QAAQ;AAAA,UACV;AACA,oBAAU,WAAW,UAAU,UAAU,QACrC,OAAO,eAAe,MAAM,OAAO;AAAA,YACjC,YAAY;AAAA,YACZ,KAAK;AAAA,UACP,CAAC,IACD,OAAO,eAAe,MAAM,OAAO,EAAE,YAAY,OAAI,OAAO,KAAK,CAAC;AACtE,eAAK,SAAS,CAAC;AACf,iBAAO,eAAe,KAAK,QAAQ,aAAa;AAAA,YAC9C,cAAc;AAAA,YACd,YAAY;AAAA,YACZ,UAAU;AAAA,YACV,OAAO;AAAA,UACT,CAAC;AACD,iBAAO,eAAe,MAAM,cAAc;AAAA,YACxC,cAAc;AAAA,YACd,YAAY;AAAA,YACZ,UAAU;AAAA,YACV,OAAO;AAAA,UACT,CAAC;AACD,iBAAO,eAAe,MAAM,eAAe;AAAA,YACzC,cAAc;AAAA,YACd,YAAY;AAAA,YACZ,UAAU;AAAA,YACV,OAAO;AAAA,UACT,CAAC;AACD,iBAAO,eAAe,MAAM,cAAc;AAAA,YACxC,cAAc;AAAA,YACd,YAAY;AAAA,YACZ,UAAU;AAAA,YACV,OAAO;AAAA,UACT,CAAC;AACD,iBAAO,WAAW,OAAO,OAAO,KAAK,KAAK,GAAG,OAAO,OAAO,IAAI;AAC/D,iBAAO;AAAA,QACT;AACA,iBAAS,WACP,MACA,QACA,UACA,kBACA,YACA,WACA;AACA,cAAI,WAAW,OAAO;AACtB,cAAI,WAAW;AACb,gBAAI;AACF,kBAAI,YAAY,QAAQ,GAAG;AACzB,qBACE,mBAAmB,GACnB,mBAAmB,SAAS,QAC5B;AAEA,oCAAkB,SAAS,gBAAgB,CAAC;AAC9C,uBAAO,UAAU,OAAO,OAAO,QAAQ;AAAA,cACzC;AACE,wBAAQ;AAAA,kBACN;AAAA,gBACF;AAAA,gBACC,mBAAkB,QAAQ;AACjC,cAAI,eAAe,KAAK,QAAQ,KAAK,GAAG;AACtC,uBAAW,yBAAyB,IAAI;AACxC,gBAAI,OAAO,OAAO,KAAK,MAAM,EAAE,OAAO,SAAU,GAAG;AACjD,qBAAO,UAAU;AAAA,YACnB,CAAC;AACD,+BACE,IAAI,KAAK,SACL,oBAAoB,KAAK,KAAK,SAAS,IAAI,WAC3C;AACN,kCAAsB,WAAW,gBAAgB,MAC7C,OACA,IAAI,KAAK,SAAS,MAAM,KAAK,KAAK,SAAS,IAAI,WAAW,MAC5D,QAAQ;AAAA,cACN;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YACF,GACC,sBAAsB,WAAW,gBAAgB,IAAI;AAAA,UAC1D;AACA,qBAAW;AACX,qBAAW,aACR,uBAAuB,QAAQ,GAAI,WAAW,KAAK;AACtD,sBAAY,MAAM,MACf,uBAAuB,OAAO,GAAG,GAAI,WAAW,KAAK,OAAO;AAC/D,cAAI,SAAS,QAAQ;AACnB,uBAAW,CAAC;AACZ,qBAAS,YAAY;AACnB,wBAAU,aAAa,SAAS,QAAQ,IAAI,OAAO,QAAQ;AAAA,UAC/D,MAAO,YAAW;AAClB,sBACE;AAAA,YACE;AAAA,YACA,eAAe,OAAO,OAClB,KAAK,eAAe,KAAK,QAAQ,YACjC;AAAA,UACN;AACF,iBAAO;AAAA,YACL;AAAA,YACA;AAAA,YACA;AAAA,YACA,SAAS;AAAA,YACT;AAAA,YACA;AAAA,UACF;AAAA,QACF;AACA,iBAAS,kBAAkB,MAAM;AAC/B,yBAAe,IAAI,IACf,KAAK,WAAW,KAAK,OAAO,YAAY,KACxC,aAAa,OAAO,QACpB,SAAS,QACT,KAAK,aAAa,oBACjB,gBAAgB,KAAK,SAAS,SAC3B,eAAe,KAAK,SAAS,KAAK,KAClC,KAAK,SAAS,MAAM,WACnB,KAAK,SAAS,MAAM,OAAO,YAAY,KACxC,KAAK,WAAW,KAAK,OAAO,YAAY;AAAA,QAClD;AACA,iBAAS,eAAe,QAAQ;AAC9B,iBACE,aAAa,OAAO,UACpB,SAAS,UACT,OAAO,aAAa;AAAA,QAExB;AACA,YAAIA,SAAQ,iBACV,qBAAqB,uBAAO,IAAI,4BAA4B,GAC5D,oBAAoB,uBAAO,IAAI,cAAc,GAC7C,sBAAsB,uBAAO,IAAI,gBAAgB,GACjD,yBAAyB,uBAAO,IAAI,mBAAmB,GACvD,sBAAsB,uBAAO,IAAI,gBAAgB,GACjD,sBAAsB,uBAAO,IAAI,gBAAgB,GACjD,qBAAqB,uBAAO,IAAI,eAAe,GAC/C,yBAAyB,uBAAO,IAAI,mBAAmB,GACvD,sBAAsB,uBAAO,IAAI,gBAAgB,GACjD,2BAA2B,uBAAO,IAAI,qBAAqB,GAC3D,kBAAkB,uBAAO,IAAI,YAAY,GACzC,kBAAkB,uBAAO,IAAI,YAAY,GACzC,sBAAsB,uBAAO,IAAI,gBAAgB,GACjD,yBAAyB,uBAAO,IAAI,wBAAwB,GAC5D,uBACEA,OAAM,iEACR,iBAAiB,OAAO,UAAU,gBAClC,cAAc,MAAM,SACpB,aAAa,QAAQ,aACjB,QAAQ,aACR,WAAY;AACV,iBAAO;AAAA,QACT;AACN,QAAAA,SAAQ;AAAA,UACN,0BAA0B,SAAU,mBAAmB;AACrD,mBAAO,kBAAkB;AAAA,UAC3B;AAAA,QACF;AACA,YAAI;AACJ,YAAI,yBAAyB,CAAC;AAC9B,YAAI,yBAAyBA,OAAM,yBAAyB;AAAA,UAC1DA;AAAA,UACA;AAAA,QACF,EAAE;AACF,YAAI,wBAAwB,WAAW,YAAY,YAAY,CAAC;AAChE,YAAI,wBAAwB,CAAC;AAC7B,gBAAQ,WAAW;AACnB,gBAAQ,MAAM,SAAU,MAAM,QAAQ,UAAU;AAC9C,cAAI,mBACF,MAAM,qBAAqB;AAC7B,iBAAO;AAAA,YACL;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,mBACI,MAAM,uBAAuB,IAC7B;AAAA,YACJ,mBAAmB,WAAW,YAAY,IAAI,CAAC,IAAI;AAAA,UACrD;AAAA,QACF;AACA,gBAAQ,OAAO,SAAU,MAAM,QAAQ,UAAU;AAC/C,cAAI,mBACF,MAAM,qBAAqB;AAC7B,iBAAO;AAAA,YACL;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,mBACI,MAAM,uBAAuB,IAC7B;AAAA,YACJ,mBAAmB,WAAW,YAAY,IAAI,CAAC,IAAI;AAAA,UACrD;AAAA,QACF;AAAA,MACF,GAAG;AAAA;AAAA;;;AC/VL;AAAA;AAAA;AAEA,UAAI,QAAQ,IAAI,aAAa,cAAc;AACzC,eAAO,UAAU;AAAA,MACnB,OAAO;AACL,eAAO,UAAU;AAAA,MACnB;AAAA;AAAA;;;ACNA;AAAA;AAAA;AAAA;AAAA;A;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACmGA,WAAS,QAAQ,MAA6B;AAC1C,QAAI,CAAC,KAAK,OAAQ,QAAO;AACzB,QAAI,SAAS;AACb,eAAW,OAAO,MAAM;AACpB,UAAI,IAAI,WAAW,GAAG,EAAG,WAAU;UAC9B,YAAW,SAAS,MAAM,MAAM;IACzC;AACA,WAAO;EACX;AAQA,MAAe,OAAf,MAA8F;IAO1F,aAAa,KAAuB;AAAE,aAAO,KAAK,QAAQ,GAAG;IAAG;IAEhE,WAA0C;AAAE,aAAO,IAAI,SAAS,IAAI;IAAG;EAC3E;AAaA,MAAM,WAAN,cAA0B,KAA0B;IAEhD,YAA6B,OAAyB;AAAE,YAAM;AAAjC,WAAA,QAAA;AAD7B,WAAS,WAAW;IAC6C;IAEjE,SAAS,KAA6B;AAClC,UAAI,QAAQ,UAAa,QAAQ,KAAM,QAAO;AAC9C,aAAO,KAAK,MAAM,aAAa,GAAG,IAAI,KAAK,MAAM,SAAS,GAAG,IAAI;IACrE;IAEA,QAAQ,KAAc,KAA2B,MAA+B;AAC5E,UAAI,QAAQ,UAAa,QAAQ,KAAM,QAAO;AAC9C,aAAO,KAAK,MAAM,QAAQ,KAAK,KAAK,IAAI;IAC5C;IAES,aAAa,KAAuB;AACzC,aAAO,QAAQ,UAAa,QAAQ,QAAQ,KAAK,MAAM,aAAa,GAAG;IAC3E;EACJ;AAQA,MAAM,MAAN,cAAkB,KAAa;IAC3B,YAAqB,WAAmB,IAAI;AAAE,YAAM;AAA/B,WAAA,WAAA;IAAkC;IACvD,SAAS,KAAsB;AAAE,aAAO,OAAO,QAAQ,WAAW,MAAM,KAAK;IAAU;IACvF,QAAQ,KAAc,KAA2B,MAA+B;AAC5E,UAAI,OAAO,QAAQ,SAAU,QAAO;AACpC,aAAA,OAAA,SAAA,IAAK,OAAO,KAAK,QAAQ,QAAA,OAAA,OAAQ,CAAC,CAAC,IAAI,4BAA4B,OAAO,GAAA;AAC1E,aAAO;IACX;EACJ;AAGA,MAAM,MAAN,cAAkB,KAAa;IAC3B,YAAqB,WAAmB,GAAG;AAAE,YAAM;AAA9B,WAAA,WAAA;IAAiC;IACtD,SAAS,KAAsB;AAC3B,aAAO,OAAO,QAAQ,YAAY,SAAS,GAAG,IAAI,MAAM,KAAK;IACjE;IACA,QAAQ,KAAc,KAA2B,MAA+B;AAC5E,UAAI,OAAO,QAAQ,YAAY,SAAS,GAAG,EAAG,QAAO;AACrD,aAAA,OAAA,SAAA,IAAK,OAAO,KAAK,QAAQ,QAAA,OAAA,OAAQ,CAAC,CAAC,IAAI,mCAAmC,KAAK,UAAU,GAAG,CAAA;AAC5F,aAAO;IACX;EACJ;AAGA,MAAM,OAAN,cAAmB,KAAc;IAC7B,YAAqB,WAAoB,OAAO;AAAE,YAAM;AAAnC,WAAA,WAAA;IAAsC;IAC3D,SAAS,KAAuB;AAAE,aAAO,OAAO,QAAQ,YAAY,MAAM,KAAK;IAAU;IACzF,QAAQ,KAAc,KAA2B,MAA+B;AAC5E,UAAI,OAAO,QAAQ,UAAW,QAAO;AACrC,aAAA,OAAA,SAAA,IAAK,OAAO,KAAK,QAAQ,QAAA,OAAA,OAAQ,CAAC,CAAC,IAAI,6BAA6B,OAAO,GAAA;AAC3E,aAAO;IACX;EACJ;AAQA,MAAM,UAAN,cAA2D,KAAQ;IAE/D,YAA6B,OAAU;AAAE,YAAM;AAAlB,WAAA,QAAA;AAAqB,WAAK,WAAW;IAAO;IACzE,SAAS,KAAiB;AAAE,aAAO,QAAQ,KAAK,QAAQ,KAAK,QAAQ,KAAK;IAAU;IACpF,QAAQ,KAAc,KAA2B,MAA+B;AAC5E,UAAI,QAAQ,KAAK,MAAO,QAAO;AAC/B,aAAA,OAAA,SAAA,IAAK,OAAO,KAAK,QAAQ,QAAA,OAAA,OAAQ,CAAC,CAAC,IAAI,gBAAgB,KAAK,UAAU,KAAK,KAAK,IAAI,WAAW,KAAK,UAAU,GAAG,CAAA;AACjH,aAAO;IACX;EACJ;AAQA,MAAM,OAAN,cAA8C,KAAQ;IAElD,YAA6B,QAAsB,YAAgB;AAC/D,YAAM;AADmB,WAAA,SAAA;AAEzB,WAAK,WAAW,cAAA,OAAA,aAAc,OAAO,CAAC;IAC1C;IACA,SAAS,KAAiB;AAAE,aAAO,KAAK,OAAO,SAAS,GAAQ,IAAK,MAAY,KAAK;IAAU;IAChG,QAAQ,KAAc,KAA2B,MAA+B;AAC5E,UAAI,KAAK,OAAO,SAAS,GAAQ,EAAG,QAAO;AAC3C,aAAA,OAAA,SAAA,IAAK,OAAO,KAAK,QAAQ,QAAA,OAAA,OAAQ,CAAC,CAAC,IAAI,uBAAuB,KAAK,OAAO,IAAI,CAAA,MAAK,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,WAAW,KAAK,UAAU,GAAG,CAAA;AACjJ,aAAO;IACX;EACJ;AASA,MAAM,QAAN,cAAuB,KAAQ;IAE3B,YAA6B,SAAqC,YAAgB;AAC9E,YAAM;AADmB,WAAA,UAAA;AAEzB,WAAK,WAAW,cAAA,OAAA,aAAc,QAAQ,CAAC,EAAE;IAC7C;IACA,SAAS,KAAiB;AACtB,iBAAW,KAAK,KAAK,SAAS;AAC1B,YAAI,EAAE,QAAQ,GAAG,EAAG,QAAO,EAAE,SAAS,GAAG;MAC7C;AACA,aAAO,KAAK;IAChB;IACA,QAAQ,KAAc,KAA2B,MAA+B;AA7PpF,UAAA;AA+PQ,UAAI,KAAK,QAAQ,KAAK,CAAA,MAAK,EAAE,QAAQ,GAAG,CAAC,EAAG,QAAO;AACnD,aAAA,OAAA,SAAA,IAAK,OAAO,KAAK,QAAQ,QAAA,OAAA,OAAQ,CAAC,CAAC,IAAI,2CAA0C,KAAA,KAAK,UAAU,GAAG,MAAlB,OAAA,KAAuB,IAAI,MAAM,GAAG,EAAE,CAAA;AACvH,aAAO;IACX;IACS,aAAa,KAAuB;AAAE,aAAO,KAAK,QAAQ,KAAK,CAAA,MAAK,EAAE,aAAa,GAAG,CAAC;IAAG;EACvG;AAkBA,MAAM,qBAAN,cAAoC,KAAQ;IAIxC,YACqB,MACA,UACjB,YACF;AACE,YAAM;AAJW,WAAA,OAAA;AACA,WAAA,WAAA;AAIjB,WAAK,WAAW,cAAA,OAAA,aAAc,SAAS,CAAC,EAAE;AAC1C,WAAK,OAAO,oBAAI,IAAI;AACpB,iBAAW,KAAK,UAAU;AACtB,cAAM,YAAY,EAAE,OAAO,IAAI;AAC/B,YAAI,UAAW,MAAK,KAAK,IAAI,UAAU,UAAU,CAAC;MACtD;IACJ;IAEQ,YAAY,KAAuC;AACvD,UAAI,QAAQ,QAAQ,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,EAAG,QAAO;AAC1E,YAAM,MAAO,IAAgC,KAAK,IAAI;AACtD,UAAI,QAAQ,UAAa,QAAQ,KAAM,QAAO;AAC9C,aAAO,KAAK,KAAK,IAAI,GAAgC;IACzD;IAEA,SAAS,KAAiB;AA/S9B,UAAA;AAgTQ,eAAQ,KAAA,KAAK,YAAY,GAAG,MAApB,OAAA,KAAyB,KAAK,SAAS,CAAC,GAAG,SAAS,GAAG;IACnE;IAEA,QAAQ,KAAc,KAA2B,MAA+B;AAC5E,YAAM,SAAS,KAAK,YAAY,GAAG;AACnC,UAAI,CAAC,QAAQ;AACT,cAAM,MAAO,QAAQ,QAAQ,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,GAAG,IACnE,IAAgC,KAAK,IAAI,IAAI;AACpD,eAAA,OAAA,SAAA,IAAK,OAAO,KAAK,QAAQ,QAAA,OAAA,OAAQ,CAAC,CAAC,IAAI,6CACjC,KAAK,OAAO,MAAM,KAAK,UAAU,GAAG,CAAA;AAC1C,eAAO;MACX;AACA,aAAO,OAAO,QAAQ,KAAK,KAAK,IAAI;IACxC;IAES,aAAa,KAAuB;AACzC,UAAI,QAAQ,QAAQ,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,EAAG,QAAO;AAC1E,YAAM,SAAS,KAAK,YAAY,GAAG;AACnC,aAAO,SAAS,OAAO,aAAa,GAAG,IAAI,KAAK,SAAS,CAAC,EAAE,aAAa,GAAG;IAChF;EACJ;AAoBA,MAAM,MAAN,cAAsC,KAAoB;IAGtD,YAAqB,QAAW;AAC5B,YAAM;AADW,WAAA,SAAA;AAEjB,YAAM,IAAS,CAAC;AAChB,iBAAW,OAAO,OAAO,KAAK,MAAM,EAAG,GAAE,GAAG,IAAI,OAAO,GAAG,EAAE;AAC5D,WAAK,WAAW;IACpB;IAEA,SAAS,KAA6B;AAClC,YAAM,MAAO,OAAO,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,GAAG,IAAK,MAAa,CAAC;AACpF,YAAM,MAAW,CAAC;AAClB,iBAAW,OAAO,OAAO,KAAK,KAAK,MAAM,GAAG;AACxC,YAAI,GAAG,IAAI,KAAK,OAAO,GAAG,EAAE,SAAS,IAAI,GAAG,CAAC;MACjD;AACA,aAAO;IACX;IAEA,QAAQ,KAAc,KAA2B,MAA+B;AAC5E,UAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,GAAG;AACvD,eAAA,OAAA,SAAA,IAAK,OAAO,KAAK,QAAQ,QAAA,OAAA,OAAQ,CAAC,CAAC,IAAI,6BAA6B,MAAM,QAAQ,GAAG,IAAI,UAAU,OAAO,IAAA;AAC1G,eAAO;MACX;AACA,YAAM,MAAM;AACZ,YAAM,IAAI,QAAA,OAAA,OAAQ,CAAC;AACnB,UAAI,KAAK;AACT,iBAAW,OAAO,OAAO,KAAK,KAAK,MAAM,GAAG;AACxC,UAAE,KAAK,GAAG;AACV,YAAI,CAAC,KAAK,OAAO,GAAG,EAAE,QAAQ,IAAI,GAAG,GAAG,KAAK,CAAC,EAAG,MAAK;AACtD,UAAE,IAAI;MACV;AAGA,UAAI,OAAA,OAAA,SAAA,IAAK,QAAQ;AACb,mBAAW,OAAO,OAAO,KAAK,GAAG,GAAG;AAChC,cAAI,OAAO,KAAK,OAAQ;AACxB,YAAE,KAAK,GAAG;AACV,cAAI,OAAO,KAAK,QAAQ,CAAC,IAAI,wBAAwB;AACrD,YAAE,IAAI;AACN,eAAK;QACT;MACJ;AACA,aAAO;IACX;IAES,aAAa,KAAuB;AACzC,aAAO,CAAC,CAAC,OAAO,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,GAAG;IACjE;EACJ;AAwBA,MAAM,UAAN,cAAmD,KAA2B;IAG1E,YAAqB,QAA4B,aAA2B;AACxE,YAAM;AADW,WAAA,SAAA;AAA4B,WAAA,cAAA;AAE7C,YAAM,IAAS,CAAC;AAChB,iBAAW,OAAO,OAAO,KAAK,MAAM,EAAG,GAAE,GAAG,IAAI,OAAO,GAAG,EAAE;AAC5D,WAAK,WAAW;IACpB;IAEA,SAAS,KAAoC;AACzC,YAAM,MAAgC,OAAO,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,GAAG,IACpF,MACA,CAAC;AACP,YAAM,MAA+BC,gBAAA,CAAA,GAAK,GAAA;AAC1C,iBAAW,OAAO,OAAO,KAAK,KAAK,MAAM,GAAG;AACxC,YAAI,GAAG,IAAI,KAAK,OAAO,GAAG,EAAE,SAAS,IAAI,GAAG,CAAC;MACjD;AACA,UAAI,KAAK,aAAa;AAClB,mBAAW,OAAO,OAAO,KAAK,GAAG,GAAG;AAChC,cAAI,EAAE,OAAO,KAAK,QAAS,KAAI,GAAG,IAAI,KAAK,YAAY,SAAS,IAAI,GAAG,CAAC;QAC5E;MACJ;AACA,aAAO;IACX;IAEA,QAAQ,KAAc,KAA2B,MAA+B;AAC5E,UAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,GAAG;AACvD,eAAA,OAAA,SAAA,IAAK,OAAO,KAAK,QAAQ,QAAA,OAAA,OAAQ,CAAC,CAAC,IAAI,6BAA6B,MAAM,QAAQ,GAAG,IAAI,UAAU,OAAO,IAAA;AAC1G,eAAO;MACX;AACA,YAAM,MAAM;AACZ,YAAM,IAAI,QAAA,OAAA,OAAQ,CAAC;AACnB,UAAI,KAAK;AACT,iBAAW,OAAO,OAAO,KAAK,KAAK,MAAM,GAAG;AACxC,UAAE,KAAK,GAAG;AACV,YAAI,CAAC,KAAK,OAAO,GAAG,EAAE,QAAQ,IAAI,GAAG,GAAG,KAAK,CAAC,EAAG,MAAK;AACtD,UAAE,IAAI;MACV;AACA,UAAI,KAAK,aAAa;AAClB,mBAAW,OAAO,OAAO,KAAK,GAAG,GAAG;AAChC,cAAI,OAAO,KAAK,OAAQ;AACxB,YAAE,KAAK,GAAG;AACV,cAAI,CAAC,KAAK,YAAY,QAAQ,IAAI,GAAG,GAAG,KAAK,CAAC,EAAG,MAAK;AACtD,YAAE,IAAI;QACV;MACJ;AACA,aAAO;IACX;IAES,aAAa,KAAuB;AACzC,aAAO,CAAC,CAAC,OAAO,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,GAAG;IACjE;EACJ;AASA,MAAM,MAAN,cAAqB,KAAe;IAEhC,YAA6B,MAAmB;AAAE,YAAM;AAA3B,WAAA,OAAA;AAD7B,WAAS,WAAqB,CAAC;IAC4B;IAE3D,SAAS,KAAwB;AAC7B,UAAI,CAAC,MAAM,QAAQ,GAAG,EAAG,QAAO,CAAC;AACjC,YAAM,MAAgB,CAAC;AACvB,iBAAW,MAAM,KAAK;AAClB,YAAI,KAAK,KAAK,aAAa,EAAE,EAAG,KAAI,KAAK,KAAK,KAAK,SAAS,EAAE,CAAC;MACnE;AACA,aAAO;IACX;IAEA,QAAQ,KAAc,KAA2B,MAA+B;AAC5E,UAAI,CAAC,MAAM,QAAQ,GAAG,GAAG;AACrB,eAAA,OAAA,SAAA,IAAK,OAAO,KAAK,QAAQ,QAAA,OAAA,OAAQ,CAAC,CAAC,IAAI,2BAA2B,OAAO,GAAA;AACzE,eAAO;MACX;AACA,YAAM,IAAI,QAAA,OAAA,OAAQ,CAAC;AACnB,UAAI,KAAK;AACT,eAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACjC,UAAE,KAAK,MAAM,IAAI,GAAG;AACpB,YAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,CAAC,GAAG,KAAK,CAAC,EAAG,MAAK;AAC7C,UAAE,IAAI;MACV;AACA,aAAO;IACX;IAES,aAAa,KAAuB;AAAE,aAAO,MAAM,QAAQ,GAAG;IAAG;EAC9E;AAQA,MAAM,MAAN,cAAqB,KAAwB;IAEzC,YAA6B,OAAoB;AAAE,YAAM;AAA5B,WAAA,QAAA;AAD7B,WAAS,WAA8B,CAAC;IACoB;IAE5D,SAAS,KAAiC;AACtC,UAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,EAAG,QAAO,CAAC;AACnE,YAAM,MAAyB,CAAC;AAChC,iBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,GAAG,GAAG;AACtC,YAAI,KAAK,MAAM,aAAa,CAAC,EAAG,KAAI,CAAC,IAAI,KAAK,MAAM,SAAS,CAAC;MAClE;AACA,aAAO;IACX;IAEA,QAAQ,KAAc,KAA2B,MAA+B;AAC5E,UAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,GAAG;AACvD,eAAA,OAAA,SAAA,IAAK,OAAO,KAAK,QAAQ,QAAA,OAAA,OAAQ,CAAC,CAAC,IAAI,oCAAoC,MAAM,QAAQ,GAAG,IAAI,UAAU,OAAO,IAAA;AACjH,eAAO;MACX;AACA,YAAM,IAAI,QAAA,OAAA,OAAQ,CAAC;AACnB,UAAI,KAAK;AACT,iBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,GAAa,GAAG;AAChD,UAAE,KAAK,CAAC;AACR,YAAI,CAAC,KAAK,MAAM,QAAQ,GAAG,KAAK,CAAC,EAAG,MAAK;AACzC,UAAE,IAAI;MACV;AACA,aAAO;IACX;IAES,aAAa,KAAuB;AACzC,aAAO,CAAC,CAAC,OAAO,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,GAAG;IACjE;EACJ;AAQA,MAAM,MAAN,cAAkB,KAAU;IAA5B,cAAA;AAAA,YAAA,GAAA,SAAA;AACI,WAAS,WAAgB;IAAA;IACzB,SAAS,KAAmB;AAAE,aAAO;IAAK;IAC1C,QAAQ,MAAe,MAA4B,OAAgC;AAAE,aAAO;IAAM;IACzF,aAAa,MAAwB;AAAE,aAAO;IAAM;EACjE;AAQA,MAAM,OAAN,cAAsB,KAAQ;IAE1B,YAA6B,IAAgC,UAAa;AAAE,YAAM;AAArD,WAAA,KAAA;AAAgC,WAAA,WAAA;AAD7D,WAAQ,WAA+B;IAC8C;IAErF,IAAY,SAAsB;AA5jBtC,UAAA;AA6jBQ,cAAO,KAAA,KAAK,aAAL,OAAA,KAAkB,KAAK,WAAW,KAAK,GAAG;IACrD;IAEA,SAAS,KAAiB;AAAE,aAAO,KAAK,OAAO,SAAS,GAAG;IAAG;IAC9D,QAAQ,KAAc,KAA2B,MAA+B;AAAE,aAAO,KAAK,OAAO,QAAQ,KAAK,KAAK,IAAI;IAAG;IACrH,aAAa,KAAuB;AAAE,aAAO,KAAK,OAAO,aAAa,GAAG;IAAG;EACzF;AAaA,MAAM,QAAN,cAAiE,KAAoB;IAGjF,YAA6B,SAAY;AACrC,YAAM;AADmB,WAAA,UAAA;AAEzB,WAAK,WAAW,QAAQ,IAAI,CAAA,MAAK,EAAE,QAAQ;IAC/C;IAEA,SAAS,KAA6B;AAClC,UAAI,CAAC,MAAM,QAAQ,GAAG,KAAK,IAAI,WAAW,KAAK,QAAQ,OAAQ,QAAO,KAAK;AAC3E,aAAO,KAAK,QAAQ,IAAI,CAAC,GAAG,MAAM,EAAE,SAAU,IAAkB,CAAC,CAAC,CAAC;IACvE;IAEA,QAAQ,KAAc,KAA2B,MAA+B;AAC5E,UAAI,CAAC,MAAM,QAAQ,GAAG,KAAK,IAAI,WAAW,KAAK,QAAQ,QAAQ;AAC3D,eAAA,OAAA,SAAA,IAAK,OAAO,KAAK,QAAQ,QAAA,OAAA,OAAQ,CAAC,CAAC,IAAI,gCAAgC,KAAK,QAAQ,SAAS,YAAY,MAAM,QAAQ,GAAG,IAAI,WAAY,IAAkB,SAAS,MAAM,OAAO,IAAA;AAClL,eAAO;MACX;AACA,YAAM,IAAI,QAAA,OAAA,OAAQ,CAAC;AACnB,UAAI,KAAK;AACT,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ,KAAK;AAC1C,UAAE,KAAK,MAAM,IAAI,GAAG;AACpB,YAAI,CAAE,KAAK,QAA8C,CAAC,EAAE,QAAS,IAAkB,CAAC,GAAG,KAAK,CAAC,EAAG,MAAK;AACzG,UAAE,IAAI;MACV;AACA,aAAO;IACX;;IAGS,aAAa,KAAuB;AACzC,aAAO,MAAM,QAAQ,GAAG,KAAK,IAAI,WAAW,KAAK,QAAQ;IAC7D;EACJ;AAqBO,WAAS,sBAAyB;AACrC,WAAO,CAAwB,WAAiB;EACpD;AAyDO,MAAM,KAAK;;IAEd,QAAS,CAAC,aAAa,OAA6B,IAAI,IAAI,UAAU;;IAGtE,QAAS,CAAC,aAAa,MAA6B,IAAI,IAAI,UAAU;;IAGtE,SAAS,CAAC,aAAa,UAA6B,IAAI,KAAK,UAAU;;IAGvE,SAAS,CAAsC,UAC3C,IAAI,QAAQ,KAAK;;IAGrB,MAAM,CAA4B,QAAsB,eACpD,IAAI,KAAK,QAAQ,UAAU;;;;;IAM/B,OAAO,CACH,SACA,eAEA,IAAI,MAAM,SAAgB,UAAU;;;;;;;IAQxC,oBAAoB,CAGlB,KAAQ,YACN,IAAI,mBAAmB,KAAK,OAAc;;IAG9C,QAAQ,CAAqB,UACzB,IAAI,IAAI,KAAK;;;;;IAMjB,YAAY,CACR,OACA,eAEA,IAAI,QAAQ,OAAO,UAAU;;;;;;;;IASjC,gBAAgB,CACZ,MACA,UAEA,IAAI,IAAIC,gBAAAA,gBAAA,CAAA,GAAK,KAAK,MAAA,GAAW,KAAA,CAAgB;;IAGjD,OAAO,CAAI,SACP,IAAI,IAAI,IAAI;;IAGhB,QAAQ,CAAI,UACR,IAAI,IAAI,KAAK;;IAGjB,KAAK,MAAqB,IAAI,IAAI;;IAGlC,OAAO,CAA8C,YACjD,IAAI,MAAM,OAAO;;IAGrB,MAAM,CAAI,IAAuB,eAC7B,IAAI,KAAK,IAAI,UAAU;EAC/B;ACzwBO,MAAM,wBAAwB;AAE9B,MAAM,oBAAoB;AAW1B,MAAM,iBAAiB;IAC1B,MAAQ;IACR,QAAQ;IACR,QAAQ;EACZ;AAOO,MAAM,mBAAmB;IAC5B,QAAQ,eAAe;IACvB,QAAQ,eAAe;EAC3B;AAOO,MAAM,YAAY;AAClB,MAAM,oBAAoB;AAG1B,MAAM,iBAAiB,oBAAI,IAAI;IAClC;IAAQ;IAAY;IAAY;IAAQ;IAAW;IAAW;EAClE,CAAC;AAeM,MAAM,sBAAsB,GAAG,MAAM;IACxC,GAAG,OAAO;IACV,GAAG,MAAM,CAAC,GAAG,OAAO,GAAG,GAAG,OAAO,GAAG,GAAG,OAAO,GAAG,GAAG,OAAO,CAAC,CAAU;EAC1E,CAAC;AAyGM,MAAM,wBAAwB,oBAAsC,EAAE,GAAG,MAAM;IAClF,GAAG,OAAO;;IACV,GAAG,OAAO;IACV,GAAG,MAAM,GAAG,OAAO,CAAC;IACpB,GAAG,KAAuB,MAAM,wBAAwB,CAAC,CAAC;IAC1D,GAAG,OAAO,EAAE,MAAM,GAAG,OAAO,EAAE,CAAC;IAC/B,GAAG,KAAqC,MAAM,GAAG,OAAO,EAAE,OAAO,GAAG,MAAM,kBAAkB,EAAE,CAAC,GAAG,EAAE,OAAO,CAAC,EAAE,CAAC;EACnH,CAAC,CAAC;AAaK,MAAM,mBAAmB,oBAAiC,EAAE,GAAG,OAAO;IACzE,MAAM,GAAG,OAAO,EAAE,SAAS;IAC3B,GAAG,GAAG,OAAO,EAAE,SAAS;IACxB,OAAO,GAAG,IAAI,EAAE,SAAS;IACzB,GAAG,GAAG,IAAI,EAAE,SAAS;IACrB,QAAQ,oBAAoB,SAAS;IACrC,GAAG,oBAAoB,SAAS;IAChC,YAAY,GAAG,MAAM,CAAC,GAAG,OAAO,GAAG,GAAG,OAAO,CAAC,CAAU,EAAE,SAAS;IACnE,IAAY,GAAG,MAAM,CAAC,GAAG,OAAO,GAAG,GAAG,OAAO,CAAC,CAAU,EAAE,SAAS;;IACnE,WAAY,GAAG,MAAM,CAAC,GAAG,OAAO,GAAG,GAAG,OAAO,CAAC,CAAU,EAAE,SAAS;IACnE,IAAY,GAAG,MAAM,CAAC,GAAG,OAAO,GAAG,GAAG,OAAO,CAAC,CAAU,EAAE,SAAS;;IACnE,UAAY,GAAG,QAAQ,EAAE,SAAS;;EACtC,CAAC,CAAC;AA6EK,MAAM,eAAe,oBAA6B,EAAE,GAAG,OAAO;IACjE,cAAc,GAAG,OAAO,EAAE,SAAS;IACnC,QAAQ,GAAG,QAAQ,EAAE,SAAS;IAC9B,WAAW,GAAG,QAAQ,EAAE,SAAS;EACrC,CAAC,CAAC;AAiDK,MAAM,4BAA4B,oBAA0C,EAAE,GAAG,OAAO;IAC3F,WAAW,GAAG,MAAM,gBAAgB,EAAE,SAAS;IAC/C,KAAK,GAAG,MAAM,gBAAgB,EAAE,SAAS;IACzC,MAAM,GAAG,MAAM,CAAC,cAAc,GAAG,QAAQ,CAAC,CAAC,EAAE,SAAS;IACtD,YAAY,GAAG,QAAQ,EAAE,SAAS;EACtC,CAAC,CAAC;AAuDK,MAAM,yBAAyB,oBAAuC,EAAE,GAAG,OAAO;IACrF,WAAW,GAAG,MAAM,CAAC,GAAG,OAAO,GAAG,GAAG,OAAO,CAAC,CAAU,EAAE,SAAS;IAClE,QAAQ,GAAG,OAAO,EAAE,SAAS;IAC7B,MAAM,GAAG,OAAO,EAAE,SAAS;IAC3B,OAAO,GAAG,MAAM,CAAC,GAAG,OAAO,GAAG,GAAG,OAAO,CAAC,CAAU,EAAE,SAAS;IAC9D,QAAQ,GAAG,MAAM,CAAC,GAAG,OAAO,GAAG,GAAG,OAAO,CAAC,CAAU,EAAE,SAAS;EACnE,CAAC,CAAC;AAqBK,MAAM,yBAAyB,GAAG,MAAM;IAC3C,GAAG,OAAO;IACV,GAAG,OAAO,EAAE,OAAO,uBAAuB,CAAC;IAC3C;EACJ,CAAC;AAsBM,MAAM,8BAA8B,oBAA4C;IACnF,GAAG,OAAO,yBAAyB;EACvC;AAiCO,MAAM,2BAA2B,oBAAyC,EAAE,GAAG,MAAM;IACxF,GAAG,OAAO;IACV,GAAG,MAAM,GAAG,MAAM,CAAC,GAAG,OAAO,GAAG,2BAA2B,CAAC,CAAC;IAC7D;EACJ,CAAC,CAAC;AAgCK,MAAM,kBAAkB,oBAAgC,EAAE,GAAG,OAAO;IACvE,SAAS,GAAG,KAAK,CAAC,QAAQ,aAAa,SAAS,kBAAkB,cAAc,CAAU,EAAE,SAAS;IACrG,WAAW,GAAG,KAAK,CAAC,YAAY,SAAS,SAAS,SAAS,CAAU,EAAE,SAAS;IAChF,yBAAyB,GAAG,OAAO,EAAE,SAAS;EAClD,CAAC,CAAC;AAuBK,MAAM,gBAAgB,oBAA8B,EAAE,GAAG,OAAO;IACnE,OAAO,GAAG,OAAO;IACjB,GAAG,GAAG,OAAO;EACjB,CAAC,CAAC;AAsBK,MAAM,oBAAoB,oBAAkC,EAAE,GAAG,OAAO;IAC3E,SAAS,GAAG,OAAO;IACnB,OAAO,GAAG,OAAO;IACjB,QAAQ,GAAG,OAAO;IAClB,YAAY,GAAG,OAAO;IACtB,QAAQ,GAAG,OAAO,aAAa;EACnC,CAAC,CAAC;AA2BK,MAAM,eAAe,oBAA6B,EAAE,GAAG,OAAO;IACjE,SAAS,GAAG,OAAO,GAAG,MAAM,CAAC,GAAG,OAAO,GAAG,GAAG,OAAO,GAAG,GAAG,OAAO,GAAG,GAAG,OAAO,CAAC,CAAU,CAAC,EAAE,SAAS;IACrG,YAAY,GAAG,OAAO,2BAA2B,EAAE,SAAS;IAC5D,QAAQ,GAAG,OAAO,GAAG,IAAI,CAAC,EAAE,SAAS;IACrC,QAAQ,GAAG,OAAO,iBAAiB,EAAE,SAAS;EAClD,CAAC,CAAC;AAiFK,MAAM,yBAAyB,oBAAuC,EAAE,GAAG,OAAO;IACrF,MAAM,GAAG,KAAK,CAAC,eAAe,MAAM,eAAe,QAAQ,eAAe,MAAM,CAAU,EAAE,SAAS;IACrG,UAAU,GAAG,OAAO,EAAE,SAAS;IAC/B,OAAO,GAAG,OAAO,EAAE,SAAS;IAC5B,YAAY,GAAG,MAAM,CAAC,GAAG,OAAO,GAAG,GAAG,QAAQ,UAAU,CAAC,CAAC,EAAE,SAAS;IACrE,MAAM,GAAG,KAAK,CAAC,YAAY,aAAa,QAAQ,MAAM,CAAU,EAAE,SAAS;IAC3E,WAAW,GAAG,KAAK,CAAC,UAAU,WAAW,aAAa,mBAAmB,CAAU,EAAE,SAAS;IAC9F,WAAW,GAAG,OAAO,EAAE,SAAS;IAChC,SAAS,gBAAgB,SAAS;IAClC,eAAe,GAAG,QAAQ,EAAE,SAAS;IACrC,aAAa,aAAa,SAAS;IACnC,SAAS,GAAG,OAAO,wBAAwB,EAAE,SAAS;IACtD,OAAO,GAAG,QAAQ,EAAE,SAAS;IAC7B,eAAe,GAAG,OAAO,EAAE,SAAS;EACxC,CAAC,CAAC;AA4BK,MAAM,kBAAkB,oBAAgC,EAAE,GAAG,OAAO;IACvE,IAAI,GAAG,OAAO;IACd,SAAS;EACb,CAAC,CAAC;AA2BK,MAAM,oBAAoB,GAAG,MAAM;IACtC,GAAG,OAAO;IACV,GAAG,OAAO;IACV,GAAG,OAAO,EAAE,OAAO,GAAG,IAAI,EAAE,CAAC;IAC7B;EACJ,CAAC;AA2FD,MAAM,2BAA2B,GAAG,MAAM;IACtC,GAAG,OAAO;IACV,GAAG,OAAO,EAAE,OAAO,GAAG,OAAO,EAAE,CAAC;IAChC,GAAG,OAAO;MACN,WAAW,GAAG,MAAM,gBAAgB;MACpC,YAAY,GAAG,QAAQ,EAAE,SAAS;IACtC,CAAC;EACL,CAAC;AAKD,MAAM,yBAAyB,GAAG,MAAM;IACpC,GAAG,MAAM,CAAC,GAAG,OAAO,GAAG,GAAG,OAAO,CAAC,CAAU;IAC5C,GAAG,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC,GAAG,OAAO,GAAG,GAAG,OAAO,CAAC,CAAU,EAAE,CAAC;IAClE,GAAG,OAAO;MACN,WAAW,GAAG,MAAM,gBAAgB;MACpC,YAAY,GAAG,QAAQ,EAAE,SAAS;IACtC,CAAC;EACL,CAAC;AAYM,MAAM,+BAA+B,oBAA6C,EAAE,GAAG,OAAO;IACjG,WAAW,uBAAuB,SAAS;IAC3C,QAAQ,yBAAyB,SAAS;IAC1C,OAAO,uBAAuB,SAAS;IACvC,MAAM,yBAAyB,SAAS;IACxC,QAAQ,uBAAuB,SAAS;EAC5C,CAAC,CAAC;AAiBK,MAAM,yBAAyB,oBAAuC,EAAE,GAAG,OAAO;IACrF,QAAQ,GAAG,OAAO,EAAE,SAAS;IAC7B,WAAW,uBAAuB,SAAS;IAC3C,QAAQ,yBAAyB,SAAS;IAC1C,OAAO,uBAAuB,SAAS;IACvC,QAAQ,uBAAuB,SAAS;EAC5C,CAAC,CAAC;AAYK,MAAM,yBAAyB,oBAAuC,EAAE,GAAG,OAAO;IACrF,MAAM,GAAG,OAAO,EAAE,SAAS;IAC3B,UAAU,GAAG,OAAO,EAAE,SAAS;IAC/B,WAAW,GAAG,OAAO,EAAE,SAAS;IAChC,kBAAkB,GAAG,OAAO,EAAE,SAAS;EAC3C,CAAC,CAAC;AAqBK,MAAM,yBAAyB,oBAAuC,EAAE,GAAG,OAAO;IACrF,GAAG,GAAG,OAAO,EAAE,SAAS;IACxB,SAAS,0BAA0B,SAAS;EAChD,CAAC,CAAC;AAiBK,MAAM,yBAAyB,oBAAuC,EAAE,GAAG,OAAO;IACrF,QAAQ,yBAAyB,SAAS;IAC1C,OAAO,uBAAuB,SAAS;IACvC,cAAc,GAAG,QAAQ,EAAE,SAAS;EACxC,CAAC,CAAC;AAcK,MAAM,uBAAuB,oBAAqC,EAAE,GAAG,OAAO;IACjF,QAAQ,GAAG,OAAO,EAAE,SAAS;IAC7B,OAAO,GAAG,OAAO,EAAE,SAAS;IAC5B,SAAS,GAAG,OAAO,EAAE,SAAS;IAC9B,UAAU,GAAG,MAAM,CAAC,GAAG,OAAO,GAAG,GAAG,OAAO,CAAC,CAAU,EAAE,SAAS;EACrE,CAAC,CAAC;AAmBK,MAAM,sBAAsB,oBAAoC,EAAE,GAAG,OAAO;IAC/E,MAAM,GAAG,OAAO,EAAE,SAAS;IAC3B,QAAQ,GAAG,OAAO,EAAE,SAAS;IAC7B,QAAQ,qBAAqB,SAAS;EAC1C,CAAC,CAAC;AAqCK,MAAM,iBAAiB;IAC1B,QAAQ;IACR,QAAQ;EACZ;AASO,MAAM,uBAAuB,oBAAqC,EAAE,GAAG,OAAO;IACjF,QAAQ,GAAG,OAAO;IAClB,OAAQ,GAAG,OAAO;EACtB,CAAC,CAAC;AAOF,MAAM,kCAAkC,GAAG,MAAM;IAC7C,GAAG,MAAM,oBAAoB;IAC7B,GAAG,OAAO,EAAE,OAAO,GAAG,MAAM,oBAAoB,EAAE,CAAC;IACnD,GAAG,OAAO,EAAE,WAAW,GAAG,MAAM,gBAAgB,EAAE,CAAC;EACvD,CAAC;AAiBM,MAAM,6BAA6B,oBAA2C,EAAE,GAAG,OAAO;IAC7F,MAAM,GAAG,KAAK,CAAC,eAAe,QAAQ,eAAe,MAAM,CAAU;IACrE,IAAM,GAAG,MAAM,CAAC,GAAG,OAAO,GAAG,GAAG,OAAO,CAAC,CAAU,EAAE,SAAS;IAC7D,IAAM,GAAG,MAAM,CAAC,GAAG,OAAO,GAAG,GAAG,OAAO,CAAC,CAAU,EAAE,SAAS;IAC7D,GAAM,GAAG,MAAM,CAAC,GAAG,OAAO,GAAG,GAAG,OAAO,CAAC,CAAU,EAAE,SAAS;IAC7D,GAAM,GAAG,OAAO,EAAE,SAAS;IAC3B,IAAM,GAAG,MAAM,CAAC,GAAG,OAAO,GAAG,GAAG,OAAO,CAAC,CAAU,EAAE,SAAS;IAC7D,OAAO,gCAAgC,SAAS;IAChD,eAAmB,GAAG,OAAO,EAAE,SAAS;IACxC,cAAmB,GAAG,OAAO,EAAE,SAAS;IACxC,mBAAmB,GAAG,OAAO,EAAE,SAAS;EAC5C,CAAC,CAAC;AAOK,MAAM,+BAA+B;AAuBrC,MAAM,yBAAyB,oBAAuC,EAAE,GAAG,OAAO;IACrF,MAAM,GAAG,OAAO;IAChB,cAAc,GAAG,OAAO,EAAE,SAAS;IACnC,cAAc,GAAG,OAAO,EAAE,SAAS;IACnC,QAAQ,GAAG,OAAO,EAAE,SAAS;IAC7B,SAAS,GAAG,OAAO,EAAE,SAAS;IAC9B,aAAa,yBAAyB,SAAS;IAC/C,YAAY,yBAAyB,SAAS;EAClD,CAAC,CAAC;AAeK,MAAM,qBAAqB,oBAAmC,EAAE,GAAG,OAAO;IAC7E,WAAW,GAAG,QAAQ,EAAE,SAAS;EACrC,CAAC,CAAC;AAoBK,MAAM,kBAAkB,oBAAgC,EAAE,GAAG,OAAO;IACvE,gBAAgB,6BAA6B,SAAS;IACtD,UAAU,uBAAuB,SAAS;IAC1C,UAAU,uBAAuB,SAAS;IAC1C,UAAU,uBAAuB,SAAS;IAC1C,UAAU,uBAAuB,SAAS;IAC1C,OAAO,oBAAoB,SAAS;IACpC,iBAAiB,GAAG,QAAQ,EAAE,SAAS;IACvC,cAAc,2BAA2B,SAAS;IAClD,gBAAgB,6BAA6B,SAAS;IACtD,UAAU,uBAAuB,SAAS;IAC1C,MAAM,mBAAmB,SAAS;EACtC,CAAC,CAAC;AAWK,WAAS,oBAAoB,MAAc,MAA4C;AAC1F,UAAM,WAA0B,CAAC;AAIjC,UAAM,OAAO,CAAC,MAAc,SAAuB;AAC/C,UAAI,QAAQ,KAAK,SAAS;AACtB,cAAM,MAA2B,EAAE,QAAQ,CAAC,GAAG,UAAU,CAAC,GAAG,QAAQ,CAAC,EAAC,QAAA,OAAA,SAAA,KAAM,QAAO;AACpF,cAAM,KAAK,gBAAgB,QAAQ,KAAK,SAAS,KAAK,CAAC,OAAO,UAAU,CAAC;AACzE,YAAI,CAAC,IAAI;AACL,qBAAW,OAAO,IAAI,OAAQ,UAAS,KAAK,GAAG;QACnD;MACJ;AACA,UAAI,QAAQ,MAAM,QAAQ,KAAK,QAAQ,GAAG;AACtC,aAAK,SAAS,QAAQ,CAAC,GAAG,MAAM,KAAK,GAAG,OAAO,eAAe,IAAI,GAAG,CAAC;MAC1E;IACJ;AACA,SAAK,MAAM,MAAM;AACjB,WAAO;EACX;AAeO,MAAM,aAAa,GAAG,WAAW;IACpC,MAAM,GAAG,OAAO;IAChB,IAAI,GAAG,OAAO,EAAE,SAAS;IACzB,MAAM,GAAG,IAAI,EAAE,SAAS;;;;IAIxB,SAAS,gBAAgB,SAAS;;;;IAIlC,SAAS,yBAAyB,SAAS;IAC3C,OAAO,GAAG,MAAM,CAAC,GAAG,OAAO,GAAG,GAAG,OAAO,GAAG,MAAM,CAAC,GAAG,OAAO,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,SAAS;EAC7F,GAAG,iBAAiB;AAKpB,MAAI,eAA8B,GAAG,WAAWC,eAAAC,gBAAA,CAAA,GACzC,WAAW,MAAA,GAD8B;IAE5C,UAAU,GAAG,KAAK,MAAM,GAAG,MAAM,YAAY,GAAG,CAAC,CAAC,EAAE,SAAS;EACjE,CAAA,GAAG,iBAAiB;AA4Cb,MAAM,iBAAiB,GAAG,OAAO;IACpC,OAAO,GAAG,OAAO,EAAE,SAAS;IAC5B,QAAQ,GAAG,OAAO,EAAE,SAAS;IAC7B,SAAS,GAAG,OAAO,EAAE,SAAS;IAC9B,UAAU,uBAAuB,SAAS;EAC9C,CAAC;AAuBM,MAAM,8BAA8B,GAAG,WAAWD,eAAAC,gBAAAA,gBAAA,CAAA,GAClD,WAAW,MAAA,GACX,eAAe,MAAA,GAFmC;IAGrD,MAAM,GAAG,QAAQ,KAAK;;IACtB,UAAU,GAAG,MAAM,YAAY,EAAE,SAAS;EAC9C,CAAA,GAAG,iBAAiB;AA0Db,MAAM,qBAAqB,oBAAmC,EAAE,GAAG,OAAO;IAC7E,GAAG,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;IACjC,GAAG,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,SAAS;IAC5C,GAAG,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC,EAAE,SAAS;IAC5C,GAAG,GAAG,QAAQ,EAAE,SAAS;EAC7B,CAAC,CAAC;AA+DK,WAAS,sBAAsB,UAAkD;AACpF,QAAI,EACA,YACA,OAAO,aAAa,YACpB,CAAC,MAAM,QAAQ,QAAQ,IACxB;AACC,aAAO;IACX;AAEA,WAAO,SAAS,MAAM,MAAM,SAAS,SAAS,SAAS,MAAM;EACjE;AAqBO,WAAS,kBAAkB,KAA0D;AA99C5F,QAAA,IAAA;AA+9CI,YACI,OAAA,OAAA,SAAA,IAAK,eAAY,KAAA,OAAA,OAAA,SAAA,IAAK,SAAL,OAAA,SAAA,GAAW,cAC5B,OAAA,OAAA,SAAA,IAAK,gBAAa,KAAA,OAAA,OAAA,SAAA,IAAK,SAAL,OAAA,SAAA,GAAW;EAErC;AAEO,WAAS,QAAQ,KAAgD;AAr+CxE,QAAA;AAs+CI,QAAI,CAAC,IAAK,QAAO;AACjB,YAAO,KAAA,kBAAkB,GAAG,MAArB,OAAA,SAAA,GAAwB;EACnC;AAEO,WAAS,YAAY,KAAqD;AA1+CjF,QAAA;AA2+CI,QAAI,CAAC,IAAK,QAAO;AACjB,UAAM,WAAU,KAAA,kBAAkB,GAAG,MAArB,OAAA,SAAA,GAAwB;AACxC,QAAI,CAAC,QAAS,QAAO;AACrB,WAAO,OAAO,QAAQ,OAAO,EAAE,IAAI,CAAC,CAAC,IAAI,IAAI,OAAO,EAAE,IAAI,SAAS,KAAK,EAAE;EAC9E;ACz9CO,WAAS,gBAAgB,MAAoB,cAAc,OAAe;AAtBjF,QAAA,IAAA,IAAA,IAAA;AAuBI,UAAM,IAAI,KAAK;AACf,UAAM,IAAI,KAAK;AACf,UAAM,IAAI,KAAK;AACf,UAAM,IAAI,KAAK;AAEf,QAAI,CAAC,EAAE,OAAQ,QAAO;AAEtB,UAAM,IAAmB,CAAC;AAC1B,UAAM,MAAM,EAAE;AACd,MAAE,KAAK,MAAM,EAAE,CAAC,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC;AAEpC,aAAS,MAAM,GAAG,MAAM,KAAK,OAAO;AAChC,YAAM,QAAQ,EAAE,MAAM,CAAC;AACvB,YAAM,SAAQ,KAAA,KAAA,OAAA,SAAA,EAAI,MAAM,CAAA,MAAV,OAAA,KAAgB;AAC9B,YAAM,SAAQ,KAAA,KAAA,OAAA,SAAA,EAAI,GAAA,MAAJ,OAAA,KAAY,EAAE,GAAG;AAC/B,YAAM,QAAQ,EAAE,GAAG;AAGnB,YAAM,SAAS,CAAC,gBAAgB,MAAM,CAAC,MAAM,MAAM,CAAC,KAAK,MAAM,CAAC,MAAM,MAAM,CAAC,OACxE,MAAM,CAAC,MAAM,MAAM,CAAC,KAAK,MAAM,CAAC,MAAM,MAAM,CAAC;AAElD,UAAI,QAAQ;AACR,UAAE,KAAK,MAAM,MAAM,CAAC,IAAI,MAAM,MAAM,CAAC,CAAC;MAC1C,OAAO;AAEH,UAAE,KAAK,MAAM,MAAM,CAAC,IAAI,MAAM,MAAM,CAAC,IAAI,MAAM,MAAM,CAAC,IAAI,MAAM,MAAM,CAAC,IAAI,MAAM,MAAM,CAAC,IAAI,MAAM,MAAM,CAAC,CAAC;MAC9G;IACJ;AAEA,QAAI,KAAK,MAAM,GAAG;AACd,YAAM,QAAQ,EAAE,MAAM,CAAC;AACvB,YAAM,SAAQ,KAAA,KAAA,OAAA,SAAA,EAAI,MAAM,CAAA,MAAV,OAAA,KAAgB;AAC9B,YAAM,UAAS,KAAA,KAAA,OAAA,SAAA,EAAI,CAAA,MAAJ,OAAA,KAAU,EAAE,CAAC;AAC5B,YAAM,SAAS,EAAE,CAAC;AAGlB,YAAM,SAAS,CAAC,gBAAgB,MAAM,CAAC,MAAM,MAAM,CAAC,KAAK,MAAM,CAAC,MAAM,MAAM,CAAC,OACxE,OAAO,CAAC,MAAM,OAAO,CAAC,KAAK,OAAO,CAAC,MAAM,OAAO,CAAC;AAEtD,UAAI,CAAC,QAAQ;AACT,UAAE,KAAK,MAAM,MAAM,CAAC,IAAI,MAAM,MAAM,CAAC,IAAI,MAAM,OAAO,CAAC,IAAI,MAAM,OAAO,CAAC,IAAI,MAAM,OAAO,CAAC,IAAI,MAAM,OAAO,CAAC,CAAC;MAClH;AAEA,QAAE,KAAK,GAAG;IACd;AAEA,WAAO,EAAE,KAAK,EAAE;EACpB;AAQO,WAAS,eAAe,GAAW,GAAW,GAAmB;AACpE,WAAO,KAAK,IAAI,KAAK;EACzB;AASO,WAAS,eAAe,GAAkB,GAAkB,GAA0B;AACzF,UAAM,MAAqB,CAAC;AAC5B,UAAM,QAAQ,KAAK,IAAI,EAAE,QAAQ,EAAE,MAAM;AACzC,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC5B,UAAI,CAAC,IAAI,eAAe,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,KAAK,GAAG,CAAC;IACnD;AACA,WAAO;EACX;AAMO,WAAS,iBAAiB,GAAkB,GAAkB,GAA0B;AAC3F,WAAO;MACH,eAAe,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,KAAK,GAAG,CAAC;MACtC,eAAe,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,KAAK,GAAG,CAAC;MACtC,eAAe,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,KAAK,GAAG,CAAC;MACtC,eAAe,EAAE,CAAC,MAAM,SAAY,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,MAAM,SAAY,IAAI,EAAE,CAAC,GAAG,CAAC;IAClF;EACJ;AAQO,WAAS,mBACZ,QACA,QACA,UACmB;AACnB,UAAM,QAAQ,KAAK,IAAI,OAAO,QAAQ,OAAO,MAAM;AACnD,UAAM,MAA2B,CAAC;AAClC,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC5B,UAAI,KAAK,kBAAkB,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,QAAQ,CAAC;IAC9D;AACA,WAAO;EACX;AAWO,WAAS,kBACZ,OACA,OACA,UACY;AA/IhB,QAAA,IAAA,IAAA,IAAA,IAAA,IAAA,IAAA,IAAA,IAAA;AAgJI,QAAI,CAAC,SAAS,CAAC,MAAO,QAAO,SAAS,SAAS,EAAE,GAAG,CAAC,EAAE;AAEvD,UAAM,IAAI,KAAK,IAAI,KAAK,IAAI,UAAU,CAAC,GAAG,CAAC;AAC3C,UAAM,MAAM,KAAK,IAAI,MAAM,EAAE,QAAQ,MAAM,EAAE,MAAM;AAEnD,UAAM,IAA0B,CAAC;AACjC,UAAM,IAA0B,CAAC;AACjC,UAAM,IAA0B,CAAC;AAEjC,aAAS,MAAM,GAAG,MAAM,KAAK,OAAO;AAChC,YAAM,KAAK,MAAM,EAAE,GAAG;AACtB,YAAM,KAAK,MAAM,EAAE,GAAG;AACtB,QAAE,KAAK,eAAe,IAAI,IAAI,CAAC,CAAC;AAGhC,YAAM,MAAK,MAAA,KAAA,MAAM,MAAN,OAAA,SAAA,GAAU,GAAA,MAAV,OAAA,KAAkB;AAC7B,YAAM,MAAK,MAAA,KAAA,MAAM,MAAN,OAAA,SAAA,GAAU,GAAA,MAAV,OAAA,KAAkB;AAC7B,QAAE,KAAK,eAAe,IAAI,IAAI,CAAC,CAAC;AAEhC,YAAM,MAAK,MAAA,KAAA,MAAM,MAAN,OAAA,SAAA,GAAU,GAAA,MAAV,OAAA,KAAkB;AAC7B,YAAM,MAAK,MAAA,KAAA,MAAM,MAAN,OAAA,SAAA,GAAU,GAAA,MAAV,OAAA,KAAkB;AAC7B,QAAE,KAAK,eAAe,IAAI,IAAI,CAAC,CAAC;IACpC;AAEA,WAAO,EAAE,GAAG,GAAG,EAAE,SAAS,IAAI,QAAW,GAAG,EAAE,SAAS,IAAI,QAAW,IAAG,KAAA,MAAM,MAAN,OAAA,KAAW,MAAM,EAAE;EAChG;AAaO,WAAS,MACZ,OACA,OACA,OACA,QACA,QACM;AACN,QAAI,UAAU,MAAO,QAAO;AAC5B,UAAM,KAAK,QAAQ,UAAU,QAAQ;AACrC,WAAO,SAAS,KAAK,SAAS;EAClC;AAQO,WAAS,kBAAkB,KAAa,KAAa,GAAmB;AAC3E,QAAI,KAAK,EAAG,QAAO;AACnB,QAAI,KAAK,EAAG,QAAO;AAEnB,UAAM,KAAK,IAAI;AACf,UAAM,KAAK,KAAK,MAAM,OAAO;AAC7B,UAAM,KAAK,IAAI,KAAK;AAEpB,aAAS,QAAQ,GAAW;AAAE,eAAS,KAAK,IAAI,MAAM,IAAI,MAAM;IAAG;AACnE,aAAS,SAAS,GAAW;AAAE,cAAQ,IAAI,KAAK,IAAI,IAAI,MAAM,IAAI;IAAI;AAEtE,QAAI,KAAK;AACT,QAAI,KAAK;AACT,QAAI,KAAK;AAET,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AACxB,YAAM,KAAK,QAAQ,EAAE,IAAI;AACzB,UAAI,KAAK,IAAI,EAAE,IAAI,KAAM,QAAO;AAChC,YAAM,KAAK,SAAS,EAAE;AACtB,UAAI,KAAK,IAAI,EAAE,IAAI,KAAM;AACzB,YAAM,KAAK;IACf;AAEA,SAAK;AACL,WAAO,KAAK,IAAI;AACZ,YAAM,KAAK,QAAQ,EAAE;AACrB,UAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAM,QAAO;AACpC,UAAI,IAAI,GAAI,MAAK;UACZ,MAAK;AACV,YAAM,KAAK,MAAM;IACrB;AAEA,WAAO;EACX;AAOO,WAAS,YAAY,QAA0C;AAClE,UAAM,CAAC,KAAK,KAAK,KAAK,GAAG,IAAI;AAE7B,UAAM,KAAK,IAAI;AACf,UAAM,KAAK,KAAK,MAAM,OAAO;AAC7B,UAAM,KAAK,IAAI,KAAK;AAEpB,aAAS,aAAa,GAAW;AAAE,eAAS,KAAK,IAAI,MAAM,IAAI,MAAM;IAAG;AAExE,WAAO,SAAU,GAAW;AACxB,aAAO,aAAa,kBAAkB,KAAK,KAAK,CAAC,CAAC;IACtD;EACJ;AAIA,WAAS,MAAM,GAAW,GAAW,GAAmB;AACpD,WAAO,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;EAC9D;AAMO,WAAS,qBACZ,IAAY,IAAY,IAAY,IAAY,GACmC;AACnF,UAAM,KAAK,MAAM,IAAI,IAAI,CAAC;AAC1B,UAAM,KAAK,MAAM,IAAI,IAAI,CAAC;AAC1B,UAAM,KAAK,MAAM,IAAI,IAAI,CAAC;AAC1B,UAAM,KAAK,MAAM,IAAI,IAAI,CAAC;AAC1B,UAAM,KAAK,MAAM,IAAI,IAAI,CAAC;AAC1B,UAAM,IAAI,MAAM,IAAI,IAAI,CAAC;AACzB,WAAO;MACH,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC;MACpB,OAAO,CAAC,GAAG,IAAI,IAAI,EAAE;IACzB;EACJ;AASO,WAAS,YACZ,QACA,WACuD;AACvD,QAAI,CAAC,OAAQ,QAAO,EAAE,MAAM,QAAW,OAAO,OAAU;AACxD,QAAI,aAAa,EAAG,QAAO,EAAE,MAAM,QAAW,OAAO,OAAO;AAC5D,QAAI,aAAa,EAAG,QAAO,EAAE,MAAM,QAAQ,OAAO,OAAU;AAE5D,UAAM,CAAC,IAAI,IAAI,IAAI,EAAE,IAAI;AACzB,UAAM,IAAI,kBAAkB,IAAI,IAAI,SAAS;AAE7C,UAAM,KAAa,CAAC,GAAG,CAAC;AACxB,UAAM,KAAa,CAAC,IAAI,EAAE;AAC1B,UAAM,KAAa,CAAC,IAAI,EAAE;AAC1B,UAAM,KAAa,CAAC,GAAG,CAAC;AAExB,UAAM,EAAE,MAAM,MAAM,IAAI,qBAAqB,IAAI,IAAI,IAAI,IAAI,CAAC;AAG9D,UAAM,KAAK,KAAK,CAAC,EAAE,CAAC;AACpB,UAAM,KAAK,KAAK,CAAC,EAAE,CAAC;AAEpB,QAAI;AACJ,QAAI,KAAK,QAAQ,KAAK,IAAI,EAAE,IAAI,MAAM;AAClC,mBAAa;QACT,KAAK,CAAC,EAAE,CAAC,IAAI;QAAI,KAAK,CAAC,EAAE,CAAC,IAAI;QAC9B,KAAK,CAAC,EAAE,CAAC,IAAI;QAAI,KAAK,CAAC,EAAE,CAAC,IAAI;MAClC;IACJ;AAEA,QAAI;AACJ,UAAM,KAAK,IAAI;AACf,UAAM,KAAK,IAAI;AACf,QAAI,KAAK,QAAQ,KAAK,IAAI,EAAE,IAAI,MAAM;AAClC,oBAAc;SACT,MAAM,CAAC,EAAE,CAAC,IAAI,MAAM;SAAK,MAAM,CAAC,EAAE,CAAC,IAAI,MAAM;SAC7C,MAAM,CAAC,EAAE,CAAC,IAAI,MAAM;SAAK,MAAM,CAAC,EAAE,CAAC,IAAI,MAAM;MAClD;IACJ;AAEA,WAAO,EAAE,MAAM,YAAY,OAAO,YAAY;EAClD;AAMO,WAAS,cAAc,QAAgD;AAC1E,QAAI,CAAC,OAAQ,QAAO;AACpB,WAAO,CAAC,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,CAAC;EACtE;AAMO,WAAS,OAAO,OAA8B;AACjD,UAAM,IAAI,KAAK,MAAM,MAAM,CAAC,IAAI,GAAG;AACnC,UAAM,IAAI,KAAK,MAAM,MAAM,CAAC,IAAI,GAAG;AACnC,UAAM,IAAI,KAAK,MAAM,MAAM,CAAC,IAAI,GAAG;AACnC,WAAO,MAAM,WAAW,IACpB,UAAU,IAAI,MAAM,IAAI,MAAM,IAAI,MAAM,MAAM,CAAC,IAAI,MACnD,SAAS,IAAI,MAAM,IAAI,MAAM,IAAI;EACzC;AAGO,WAAS,UAAU,GAAqB;AAhW/C,QAAA;AAiWI,UAAM,SAAQ,KAAA,EAAE,MAAM,eAAe,MAAvB,OAAA,SAAA,GAA2B,CAAA;AACzC,QAAI,CAAC,MAAO,OAAM,IAAI,MAAM,yBAAyB;AACrD,UAAM,QAAQ,MAAM,MAAM,GAAG,EAAE,IAAI,CAAA,MAAK,CAAC,EAAE,KAAK,CAAC;AACjD,WAAO,CAAC,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,IAAI,KAAK,GAAI,MAAM,CAAC,MAAM,SAAY,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,CAAE;EACzG;AAGA,WAAS,SAAS,GAAqB;AACnC,UAAM,MAAM,EAAE,MAAM,CAAC;AACrB,UAAM,UAAU,IAAI,UAAU;AAE9B,UAAM,IAAI,UAAU,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,MAAM,GAAG,CAAC;AACpD,UAAM,IAAI,UAAU,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,MAAM,GAAG,CAAC;AACpD,UAAM,IAAI,UAAU,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,MAAM,GAAG,CAAC;AACpD,UAAM,IAAI,IAAI,WAAW,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,IAAI,WAAW,IAAI,IAAI,MAAM,GAAG,CAAC,IAAI;AAEpF,UAAM,SAAS;MACX,SAAS,GAAG,EAAE,IAAI;MAClB,SAAS,GAAG,EAAE,IAAI;MAClB,SAAS,GAAG,EAAE,IAAI;IACtB;AAEA,QAAI,MAAM,MAAM;AACZ,aAAO,KAAK,SAAS,GAAG,EAAE,IAAI,GAAG;IACrC;AAEA,WAAO;EACX;AAIO,WAAS,WAAW,GAA8B;AACrD,QAAI,CAAC,EAAG,QAAO;AACf,QAAI,MAAM,QAAQ,CAAC,EAAG,QAAO;AAC7B,QAAI,OAAO,MAAM,SAAU,QAAO;AAClC,QAAI,EAAE,WAAW,GAAG,GAAG;AACnB,aAAO,SAAS,CAAC;IACrB,WAAW,EAAE,WAAW,KAAK,GAAG;AAC5B,aAAO,UAAU,CAAC;IACtB,OAAO;AAEH,cAAQ,KAAK,+BAA+B,CAAC;IACjD;AACA,WAAO;EACX;AAEO,MAAM,oBAAoB,oBAAI,IAAI,CAAC,SAAS,QAAQ,eAAe,kBAAkB,cAAc,QAAQ,CAAC;AAC5G,MAAM,qBAAqB,oBAAI,IAAI,CAAC,aAAa,UAAU,SAAS,MAAM,CAAC;AAC3E,MAAM,uBAAuB,oBAAI,IAAI,CAAC,mBAAmB,gBAAgB,CAAC;AAiB1E,WAAS,sBACZ,OACA,MACM;AAraV,QAAA;AAsaI,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,aAAY,KAAA,QAAA,OAAA,SAAA,KAAM,cAAN,OAAA,KAAmB;AACrC,UAAM,OAAsB,CAAC;AAC7B,UAAM,IAAI,MAAM;AAChB,UAAM,IAAI,MAAM;AAChB,UAAM,IAAI,MAAM;AAChB,UAAM,IAAI,MAAM;AAChB,UAAM,IAAI,MAAM;AAChB,UAAM,KAAK,YAAY,OAAO;AAC9B,UAAM,KAAK,YAAY,QAAQ;AAC/B,QAAI,EAAG,MAAK,KAAK,eAAe,EAAE,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC,IAAI,KAAK,GAAG;AACjE,QAAI,EAAG,MAAK,KAAK,eAAe,EAAE,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC,IAAI,KAAK,GAAG;AACjE,QAAI,MAAM,UAAa,MAAM,KAAM,MAAK,KAAK,YAAY,IAAI,KAAK,GAAG;AAErE,QAAI,MAAM,UAAa,MAAM,KAAM,MAAK,KAAK,WAAW,IAAI,KAAK,GAAG;AACpE,QAAI,EAAG,MAAK,KAAK,WAAW,EAAE,CAAC,IAAI,MAAM,EAAE,CAAC,IAAI,GAAG;AACnD,QAAI,EAAG,MAAK,KAAK,eAAgB,CAAC,EAAE,CAAC,IAAK,KAAK,MAAO,CAAC,EAAE,CAAC,IAAK,KAAK,GAAG;AACvE,WAAO,KAAK,KAAK,EAAE;EACvB;AACO,MAAM,mBAAmB,oBAAI,IAAI,CAAC,mBAAmB,gBAAgB,CAAC;AACtE,MAAM,sBAAsB;AAM5B,WAAS,qBAAqB,OAAuB;AACxD,WAAO,MAAM,SAAS,GAAG,IAAI,MAAM,QAAQ,aAAa,CAAC,GAAG,WAAW,OAAO,YAAY,CAAC,IAAI;EACnG;AAMO,WAAS,gBAAgB,MAAuB;AACnD,WAAO,CAAC,KAAK,SAAS,GAAG,KAAK,aAAa,KAAK,IAAI;EACxD;AAGA,MAAM,uBAAuB,oBAAI,IAAI;;IAEjC;IACA;;IAGA;IACA;IACA;;IAGA;IACA;IACA;;IAGA;IACA;IACA;;IAGA;IACA;IACA;IACA;IACA;;IAGA;IACA;IACA;;IAGA;IACA;IACA;;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;;;;;;;;EAUJ,CAAC;AAMM,WAAS,6BAA6B,OAAuB;AAChE,WAAO,qBAAqB,IAAI,KAAK,IACjC,QACA,MAAM,QAAQ,sBAAsB,OAAO,EAAE,YAAY;EACjE;AAwBO,WAAS,MAAM,OAAe,KAAa,KAAqB;AACnE,WAAO,KAAK,IAAI,KAAK,KAAK,IAAI,OAAO,GAAG,CAAC;EAC7C;AAgCO,WAAS,iBACZ,IAAY,IAAY,IAAY,IACpC,GACM;AACN,QAAI,KAAK,EAAG,QAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAChC,QAAI,KAAK,EAAG,QAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAChC,UAAM,IAAI,IAAI;AACd,UAAM,KAAK,IAAI;AACf,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,IAAI;AACf,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK;AACX,UAAM,KAAK,IAAI,IAAK;AACpB,UAAM,KAAK,IAAI,KAAK;AACpB,UAAM,KAAK;AACX,WAAO;MACH,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC;MAChD,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,KAAK,GAAG,CAAC;IACpD;EACJ;AAiBA,MAAM,iBAAiB;AAChB,WAAS,sBACZ,IAAY,IAAY,IAAY,IACpC,GACM;AACN,UAAM,SAAS,0BAA0B,IAAI,IAAI,IAAI,IAAI,CAAC;AAC1D,QAAI,OAAO,CAAC,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG;AAEpC,YAAM,UAAU,IAAI,MAAM,IAAI,iBAAiB,IAAI;AACnD,aAAO,0BAA0B,IAAI,IAAI,IAAI,IAAI,OAAO;IAC5D;AACA,WAAO;EACX;AAEA,WAAS,0BACL,IAAY,IAAY,IAAY,IACpC,GACM;AACN,UAAM,IAAI,IAAI;AACd,UAAM,IAAI,IAAI,IAAI;AAClB,UAAM,IAAI,IAAI,IAAI;AAClB,UAAM,IAAI,IAAI,IAAI;AAClB,WAAO;MACH,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC;MAC7D,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,KAAK,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC;IACjE;EACJ;AA4BO,WAAS,sBACZ,IAAY,IAAY,IAAY,IACpC,QAAgB,KACJ;AACZ,UAAM,IAAI,QAAQ;AAClB,UAAM,KAAK,IAAI,aAAa,CAAC;AAC7B,UAAM,KAAK,IAAI,aAAa,CAAC;AAE7B,QAAI,OAAO,iBAAiB,IAAI,IAAI,IAAI,IAAI,CAAC;AAC7C,OAAG,CAAC,IAAI;AACR,OAAG,CAAC,IAAI;AAER,QAAI,MAAM;AACV,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AACxB,YAAM,IAAI,IAAI;AACd,YAAM,MAAM,iBAAiB,IAAI,IAAI,IAAI,IAAI,CAAC;AAC9C,YAAM,KAAK,IAAI,CAAC,IAAI,KAAK,CAAC;AAC1B,YAAM,KAAK,IAAI,CAAC,IAAI,KAAK,CAAC;AAC1B,aAAO,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;AAClC,SAAG,CAAC,IAAI;AACR,SAAG,CAAC,IAAI;AACR,aAAO;IACX;AACA,WAAO,EAAE,IAAI,GAAG;EACpB;AAgBO,WAAS,sBAAsB,KAAmB,UAA0B;AAC/E,UAAM,EAAE,IAAI,GAAG,IAAI;AACnB,UAAM,OAAO,GAAG,SAAS;AACzB,QAAI,YAAY,EAAU,QAAO,GAAG,CAAC;AACrC,QAAI,YAAY,GAAG,IAAI,EAAG,QAAO,GAAG,IAAI;AAGxC,QAAI,KAAK;AACT,QAAI,KAAK;AACT,WAAO,KAAK,IAAI;AACZ,YAAM,MAAO,KAAK,OAAQ;AAC1B,UAAI,GAAG,GAAG,IAAI,SAAU,MAAK,MAAM;UACX,MAAK;IACjC;AAEA,UAAM,QAAQ,GAAG,KAAK,CAAC;AACvB,UAAM,OAAQ,GAAG,EAAE;AACnB,UAAM,OAAQ,OAAO;AACrB,UAAM,OAAQ,OAAO,KAAK,WAAW,SAAS,OAAO;AACrD,WAAO,GAAG,KAAK,CAAC,IAAI,QAAQ,GAAG,EAAE,IAAI,GAAG,KAAK,CAAC;EAClD;AAoBO,WAAS,gBAAgB,KAAmB,GAAmB;AAClE,UAAM,EAAE,IAAI,GAAG,IAAI;AACnB,UAAM,OAAO,GAAG,SAAS;AACzB,QAAI,KAAK,GAAG,CAAC,EAAM,QAAO,GAAG,CAAC;AAC9B,QAAI,KAAK,GAAG,IAAI,EAAG,QAAO,GAAG,IAAI;AACjC,QAAI,KAAK,GAAG,KAAK;AACjB,WAAO,KAAK,IAAI;AACZ,YAAM,MAAO,KAAK,OAAQ;AAC1B,UAAI,GAAG,GAAG,IAAI,EAAG,MAAK,MAAM;UACX,MAAK;IAC1B;AACA,UAAM,QAAQ,GAAG,KAAK,CAAC;AACvB,UAAM,OAAQ,GAAG,EAAE,IAAI;AACvB,UAAM,OAAQ,OAAO,KAAK,IAAI,SAAS,OAAO;AAC9C,WAAO,GAAG,KAAK,CAAC,IAAI,QAAQ,GAAG,EAAE,IAAI,GAAG,KAAK,CAAC;EAClD;AAYO,WAAS,aAAa,QAAmD;AAC5E,QAAI,CAAC,OAAQ,QAAO,CAAC,MAAM;AAC3B,UAAM,UAAkB,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AACnE,WAAO,YAAY,OAAO;EAC9B;ACxwBA,MAAI,aAAa;AACV,WAAS,mBAA2B;AACvC,UAAM,YAAY,KAAK,IAAI,EAAE,SAAS,EAAE;AACxC,UAAM,WAAW,EAAE,YAAY,SAAS,EAAE;AAC1C,UAAM,SAAS,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,UAAU,GAAG,CAAC;AACxD,WAAO,SAAS,YAAY,UAAU;EAC1C;AAMO,WAAS,UAAa,OAAa;AACtC,QAAI,UAAU,QAAQ,OAAO,UAAU,SAAU,QAAO;AACxD,QAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,CAAA,SAAQ,UAAU,IAAI,CAAC;AAElE,UAAM,MAAM;AAEZ,UAAM,SAAkC,CAAC;AACzC,eAAW,OAAO,OAAO,KAAK,GAAG,GAAG;AAChC,aAAO,GAAG,IAAI,UAAU,IAAI,GAAG,CAAC;IACpC;AACA,WAAO;EACX;AAgBO,WAAS,eAAe,KAAmD;AAnDlF,QAAA,IAAA;AAqDI,UAAM,SAAgC,UAAU,GAAG;AAGnD,UAAM,QAAQ,oBAAI,IAAoB;AAGtC,UAAM,eAAe,oBAAI,IAAI,CAAC,QAAQ,YAAY,CAAC;AAGnD,UAAM,cAAc,oBAAI,IAAI;MACxB;MAAQ;MAAU;MAAa;MAAY;MAC3C;MAAU;MAAgB;MAAc;MACxC;MAAU;MAAe;IAC7B,CAAC;AAGD,UAAM,mBAAmB,oBAAI,IAAI,CAAC,UAAU,YAAY,gBAAgB,CAAC;AAGzE,aAAS,WAAW,MAAiB;AACjC,UAAI,CAAC,QAAQ,OAAO,SAAS,SAAU;AAEvC,UAAI,KAAK,MAAM,OAAO,KAAK,OAAO,UAAU;AACxC,cAAM,QAAQ,KAAK;AACnB,cAAM,QAAQ,iBAAiB;AAC/B,cAAM,IAAI,OAAO,KAAK;AACtB,aAAK,KAAK;MACd,WAAW,KAAK,SAAS;AAErB,aAAK,KAAK,iBAAiB;MAC/B;AAGA,UAAI,MAAM,QAAQ,KAAK,QAAQ,GAAG;AAC9B,mBAAW,SAAS,KAAK,UAAU;AAC/B,qBAAW,KAAK;QACpB;MACJ;IACJ;AAGA,aAAS,WAAW,MAAiB;AACjC,UAAI,CAAC,QAAQ,OAAO,SAAS,SAAU;AAEvC,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC7C,YAAI,QAAQ,YAAY;AACpB,cAAI,MAAM,QAAQ,KAAK,GAAG;AACtB,uBAAW,SAAS,OAAO;AACvB,yBAAW,KAAK;YACpB;UACJ;AACA;QACJ;AAEA,YAAI,OAAO,UAAU,UAAU;AAE3B,cAAI,aAAa,IAAI,GAAG,KAAK,MAAM,WAAW,GAAG,GAAG;AAChD,kBAAM,QAAQ,MAAM,MAAM,CAAC;AAC3B,kBAAM,QAAQ,MAAM,IAAI,KAAK;AAC7B,gBAAI,OAAO;AACP,mBAAK,GAAG,IAAI,MAAM;YACtB;UACJ,WAES,YAAY,IAAI,GAAG,GAAG;AAC3B,iBAAK,GAAG,IAAI,eAAe,OAAO,KAAK;UAC3C,WAES,iBAAiB,IAAI,GAAG,GAAG;AAChC,kBAAM,QAAQ,MAAM,IAAI,KAAK;AAC7B,gBAAI,OAAO;AACP,mBAAK,GAAG,IAAI;YAChB;UACJ,WAES,MAAM,SAAS,OAAO,GAAG;AAC9B,iBAAK,GAAG,IAAI,eAAe,OAAO,KAAK;UAC3C;QACJ,WAES,QAAQ,WAAW,OAAO,UAAU,YAAY,UAAU,MAAM;AACrE,qBAAW,CAAC,WAAW,UAAU,KAAK,OAAO,QAAQ,KAAK,GAAG;AACzD,gBAAI,OAAO,eAAe,UAAU;AAC/B,oBAAc,SAAS,IAAI,eAAe,YAAY,KAAK;YAChE;UACJ;QACJ,WAIS,OAAO,UAAU,YAAY,UAAU,MAAM;AAClD,qBAAW,KAAK;QACpB;MACJ;IACJ;AAEA,eAAW,MAAM;AACjB,eAAW,MAAM;AAGjB,UAAM,cAAa,KAAA,OAAO,aAAP,OAAA,SAAA,GAAiB;AACpC,QAAI,cAAc,OAAO,eAAe,UAAU;AAC9C,YAAM,iBAAsC,CAAC;AAC7C,iBAAW,CAAC,IAAI,IAAI,KAAK,OAAO,QAAQ,UAAU,GAAG;AACjD,cAAM,SAAQ,KAAA,MAAM,IAAI,EAAE,MAAZ,OAAA,KAAiB;AAC/B,uBAAe,KAAK,IAAI;MAC5B;AACA,aAAO,WAAWC,eAAAC,gBAAA,CAAA,GAAK,OAAO,QAAA,GAAZ,EAAsB,SAAS,eAAe,CAAA;IACpE;AAEA,WAAO;EACX;AAKA,WAAS,eAAe,OAAe,OAAoC;AACvE,WAAO,MAAM,QAAQ,oBAAoB,CAAC,OAAO,UAAU;AACvD,YAAM,QAAQ,MAAM,IAAI,KAAK;AAC7B,aAAO,QAAQ,UAAU,QAAQ,MAAM;IAC3C,CAAC;EACL;AC1JO,MAAM,4BAA4B,oBAAI,IAAI;IAC7C;IACA;EACJ,CAAC;AAsBD,MAAM,wBAAwB,oBAAI,IAAI;IAClC;;IACA;;IACA;;IACA;;IACA;;IACA;;IACA;;IACA;;IACA;;EACJ,CAAC;AAMD,MAAM,wBAAwB,oBAAI,IAAI,CAAC,QAAQ,cAAc,KAAK,CAAC;AAK5D,MAAM,uBAAuB,oBAAI,IAAY,CAAC,gBAAgB,WAAW,CAAC;AAIjF,MAAM,uBAAuB;AAM7B,MAAM,oBAAoB;AAU1B,MAAM,+BAA+B;AACrC,MAAM,uBAAuB,CAAC,YAAY,QAAQ,UAAU,SAAS,IAAI;AACzE,WAAS,4BAA4BC,MAAsB;AACvD,UAAM,IAAI,6BAA6B,KAAKA,IAAG;AAC/C,WAAO,CAAC,CAAC,KAAK,qBAAqB,KAAK,CAAA,UAAS,EAAE,CAAC,EAAE,WAAW,KAAK,CAAC;EAC3E;AAUA,WAAS,oBAAoB,WAA4B;AAKrD,QAAI,UAAU,WAAW,IAAI,EAAG,QAAO;AACvC,WAAO;EACX;AAoBO,WAAS,uBAAuB,MAAc,OAA6B;AAC9E,UAAM,YAAY,KAAK,YAAY;AAEnC,QAAI,oBAAoB,SAAS,GAAG;AAChC,cAAQ,KAAK,mDAAmD,SAAS;AACzE,aAAO;IACX;AAEA,QAAI,cAAc,UAAU,cAAc,YAAY,cAAc,aAAa;AAC7E,YAAMA,OAAM,OAAO,KAAK;AACxB,UAAIA,KAAI,SAAS,MAAM,KAAK,CAAC,kBAAkB,KAAKA,IAAG,GAAG;AACtD,gBAAQ,KAAK,gBAAgB,YAAY,oDAAoD,KAAK;AAClG,eAAO;MACX;AACA,aAAO;IACX;AAEA,QAAI,sBAAsB,IAAI,SAAS,GAAG;AACtC,YAAMA,OAAM,OAAO,KAAK;AACxB,UAAIA,KAAI,WAAW,GAAG,EAAG,QAAO;AAChC,UAAI,kBAAkB,KAAKA,IAAG,EAAG,QAAO;AAIxC,UAAI,sBAAsB,IAAI,SAAS,MAAM,qBAAqB,KAAKA,IAAG,KAAK,kBAAkB,KAAKA,IAAG,KAAK,4BAA4BA,IAAG,GAAI,QAAO;AACxJ,cAAQ,KAAK,gBAAgB,YAAY,oEAA+D,KAAK;AAC7G,aAAO;IACX;AAEA,WAAO;EACX;AAKO,WAAS,aACZ,OACA,MAC2C;AAtK/C,QAAA;AAuKI,QAAI,CAAC,MAAO,QAAO;AAEnB,QAAI,OAAO,UAAU,UAAU;AAE3B,cAAO,KAAA,QAAA,OAAA,SAAA,KAAM,WAAN,OAAA,SAAA,GAAe,KAAA;IAC1B;AAEA,WAAO;EACX;AAGO,WAAS,mBAAmB,OAA4B;AAC3D,UAAM,YAAiC,CAAC;AAGxC,eAAW,UAAU,OAAO,KAAK,KAAK,GAAG;AAMrC,YAAM,MAAM,qBAAqB,MAAM;AACvC,UAAI,eAAe,IAAI,GAAG,EAAG;AAC7B,UAAI,QAAQ,QAAS;AAErB,UAAI,QAAQ,MAAM,MAAM;AAExB,UAAI,kBAAkB,IAAI,GAAG,KAAK,MAAM,QAAQ,KAAK,GAAG;AACpD,kBAAU,GAAG,IAAI,OAAO,KAAK;MACjC,WACI,QAAQ,eAAe,UAAU,QAAQ,OAAO,UAAU,YAC1D,CAAC,MAAM,QAAQ,KAAK,KAAK,MAAM,SAAS,OAAO,MAAM,UAAU,UACjE;AAGE,kBAAU,WAAW,IAAI,sBAAsB,MAAM,OAAO,EAAE,WAAW,MAAM,CAAC;MACpF,WAAW,mBAAmB,IAAI,GAAG,GAAG;AACpC,YAAI,MAAM,QAAQ,KAAK,GAAG;AACtB,cAAI,QAAQ,YAAa,SAAQ,MAAM,IAAI,CAAC,MAAc,IAAI,IAAI;AAClE,kBAAQ,MAAM,KAAK,GAAG;QAC1B;AACA,YAAI,QAAQ,SAAU,SAAQ,QAAQ;AACtC,kBAAU,WAAW,IAAI,MAAM,MAAM,QAAQ;MACjD,WAAW,UAAU,UAAa,UAAU,MAAM;AAC9C,kBAAU,GAAG,IAAI,OAAO,KAAK;MACjC;IACJ;AAEA,WAAO;EACX;ACnLA,WAAS,eAAe,IAAoC;AArC5D,QAAA;AAsCI,UAAM,KAAI,KAAA,GAAG,UAAH,OAAA,KAAY,GAAG;AACzB,QAAI,CAAC,EAAG,QAAO;AACf,QAAI,MAAM,QAAQ,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,EAAE,CAAC,MAAM,YAAY,OAAO,EAAE,CAAC,MAAM,UAAU;AAE3F,aAAO,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;IACtB;AACA,UAAM,KAAM,EAAuB;AACnC,QAAI,MAAM,QAAQ,EAAE,KAAK,GAAG,UAAU,EAAG,QAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAC7D,WAAO;EACX;AAEA,WAAS,UAAU,IAAwB;AAjD3C,QAAA,IAAA;AAkDI,YAAQ,MAAA,KAAA,GAAG,SAAH,OAAA,KAAW,GAAG,MAAd,OAAA,KAAmB;EAC/B;AAEA,WAAS,YAAY,IAAoC;AArDzD,QAAA;AAsDI,YAAQ,KAAA,GAAG,WAAH,OAAA,KAAa,GAAG;EAC5B;AASO,WAAS,qBAAqB,MAAoC;AAhEzE,QAAA,IAAA,IAAA;AAiEI,UAAM,OAAqC,KAAA,KAAK,cAAL,OAAA,KAAkB,KAAK;AAClE,QAAI,CAAC,MAAM,QAAQ,GAAG,EAAG,QAAO;AAChC,QAAI,KAAK,WAAY,QAAO;AAC5B,eAAW,MAAM,KAAK;AAClB,YAAK,KAAA,GAAG,cAAH,OAAA,KAAgB,GAAG,SAAQ,KAAA,GAAG,eAAH,OAAA,KAAiB,GAAG,IAAK,QAAO;IACpE;AACA,WAAO;EACX;AAuBA,MAAM,gBAAgB,oBAAI,QAAiE;AAE3F,WAAS,gBACL,QACA,QACA,SACA,SACsB;AAtG1B,QAAA,IAAA;AAuGI,QAAI,SAAS,cAAc,IAAI,MAAM;AACrC,UAAM,WAAW,UAAA,OAAA,SAAA,OAAQ,IAAI,MAAA;AAC7B,QAAI,SAAU,QAAO;AACrB,UAAM,MAAK,KAAA,OAAO,eAAP,OAAA,KAAqB,OAAO;AACvC,UAAM,MAAK,KAAA,OAAO,cAAP,OAAA,KAAoB,OAAO;AACtC,UAAM,KAAa,CAAC,QAAQ,CAAC,KAAK,KAAK,GAAG,CAAC,IAAI,IAAI,QAAQ,CAAC,KAAK,KAAK,GAAG,CAAC,IAAI,EAAE;AAChF,UAAM,KAAa,CAAC,QAAQ,CAAC,KAAK,KAAK,GAAG,CAAC,IAAI,IAAI,QAAQ,CAAC,KAAK,KAAK,GAAG,CAAC,IAAI,EAAE;AAChF,UAAM,MAAM,sBAAsB,SAAS,IAAI,IAAI,OAAO;AAC1D,UAAM,QAAgC;MAClC,IAAI;MAAS;MAAI;MAAI,IAAI;MACzB;MACA,UAAU,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;IACtC;AACA,QAAI,CAAC,QAAQ;AAAE,eAAS,oBAAI,QAA4C;AAAG,oBAAc,IAAI,QAAQ,MAAM;IAAG;AAC9G,WAAO,IAAI,QAAQ,KAAK;AACxB,WAAO;EACX;AA+BO,WAAS,0BACZ,QACA,QACA,SACA,SACA,eACA,YACgB;AAChB,UAAM,MAAM,gBAAgB,QAAQ,QAAQ,SAAS,OAAO;AAC5D,UAAM,IAAI,IAAI,aAAa,IACrB,gBACA,iBAAiB,IAAI,KAAK,aAAa;AAC7C,UAAM,QAAQ,iBAAiB,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC;AAChE,QAAI,CAAC,WAAY,QAAO,EAAE,WAAW,MAAM;AAC3C,UAAM,MAAM,sBAAsB,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC;AACnE,UAAM,YAAY,KAAK,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,MAAM,KAAK;AAC1D,WAAO,EAAE,WAAW,OAAO,UAAU;EACzC;AAEA,WAAS,iBAAiB,KAAmB,SAAyB;AAClE,UAAM,QAAQ,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;AAEtC,UAAM,SAAS,UAAU;AACzB,UAAM,EAAE,IAAI,GAAG,IAAI;AACnB,UAAM,OAAO,GAAG,SAAS;AACzB,QAAI,UAAU,EAAU,QAAO,GAAG,CAAC;AACnC,QAAI,UAAU,GAAG,IAAI,EAAG,QAAO,GAAG,IAAI;AACtC,QAAI,KAAK,GAAG,KAAK;AACjB,WAAO,KAAK,IAAI;AACZ,YAAM,MAAO,KAAK,OAAQ;AAC1B,UAAI,GAAG,GAAG,IAAI,OAAQ,MAAK,MAAM;UACX,MAAK;IAC/B;AACA,UAAM,QAAQ,GAAG,KAAK,CAAC;AACvB,UAAM,OAAQ,GAAG,EAAE,IAAI;AACvB,UAAM,OAAQ,OAAO,KAAK,SAAS,SAAS,OAAO;AACnD,WAAO,GAAG,KAAK,CAAC,IAAI,QAAQ,GAAG,EAAE,IAAI,GAAG,KAAK,CAAC;EAClD;AAoBA,MAAM,uBAAuB;AAC7B,MAAM,uBAAuB;AAC7B,MAAM,sBAAuB;AAgBtB,WAAS,gCACZ,MACA,MACmB;AApOvB,QAAA,IAAA,IAAA,IAAA;AAqOI,QAAI,CAAC,qBAAqB,IAAI,EAAG,QAAO;AACxC,UAAM,OAAO,KAAA,KAAK,cAAL,OAAA,KAAkB,KAAK;AACpC,QAAI,CAAC,MAAM,QAAQ,GAAG,KAAK,IAAI,SAAS,EAAG,QAAO;AAElD,UAAM,aAAe,CAAC,CAAC,KAAK;AAC5B,UAAM,eAAe,KAAA,QAAA,OAAA,SAAA,KAAM,sBAAN,OAAA,KAA4B;AACjD,UAAM,eAAe,KAAA,QAAA,OAAA,SAAA,KAAM,sBAAN,OAAA,KAA4B;AACjD,UAAM,cAAe,KAAA,QAAA,OAAA,SAAA,KAAM,yBAAN,OAAA,KAA8B;AAEnD,UAAM,MAAyB,CAAC;AAKhC,UAAM,WAAW,eAAe,IAAI,CAAC,CAAC;AACtC,QAAI,CAAC,SAAU,QAAO;AACtB,UAAM,cAAc,aAAa,qBAAqB,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI;AACxE,QAAI,KAAK;MACL,UAAU,IAAI,CAAC,CAAC;MAChB,gBAAgB,gBAAgB,IAAI,CAAC,CAAC,GAAG,gBAAgB,IAAI,CAAC,CAAC,GAAG,GAAG,UAAU,aAAa,UAAU;IAC1G,CAAC;AAED,aAAS,IAAI,GAAG,IAAI,IAAI,SAAS,GAAG,KAAK;AACrC,YAAM,SAAS,IAAI,CAAC;AACpB,YAAM,SAAS,IAAI,IAAI,CAAC;AACxB,YAAM,UAAU,eAAe,MAAM;AACrC,YAAM,UAAU,eAAe,MAAM;AACrC,UAAI,CAAC,WAAW,CAAC,SAAS;AAEtB,YAAI,KAAK;UACL,UAAU,MAAM;UAChB,gBAAgB,gBAAgB,MAAM,GAAG,gBAAgB,MAAM,GAAG,GAAG,WAAA,OAAA,UAAW,CAAC,GAAG,CAAC,GAAG,QAAW,UAAU;QACjH,CAAC;AACD;MACJ;AAYA,UAAI,cAAc,IAAI,GAAG;AACrB,wCAAgC,KAAK,QAAQ,QAAQ,SAAS,SAAS,WAAW;MACtF;AAEA,yBAAmB,KAAK,QAAQ,QAAQ,SAAS,SAAS,YAAY,aAAa,aAAa,UAAU;IAC9G;AAKA,UAAM,UAAU,YAAY,IAAI,IAAI,SAAS,CAAC,CAAC;AAC/C,QAAI,QAAS,KAAI,IAAI,SAAS,CAAC,EAAE,IAAI;AAMrC,QAAI,WAAY,2BAA0B,GAAG;AAE7C,UAAM,SAA8B,EAAE,KAAK,IAAI;AAC/C,QAAI,KAAK,SAAS,OAAY,QAA8B,OAAO,KAAK;AACxE,WAAO;EACX;AAWO,WAAS,0BAA0B,KAA8B;AApTxE,QAAA;AAqTI,QAAI;AACJ,eAAW,MAAM,KAAK;AAClB,YAAM,KAAK,KAAA,GAAG,MAAH,OAAA,KAAQ,GAAG;AACtB,UAAI,CAAC,KAAK,OAAO,EAAE,WAAW,SAAU;AACxC,UAAI,SAAS,QAAW;AAAE,eAAO,EAAE;AAAQ;MAAU;AACrD,UAAI,IAAI,EAAE;AACV,aAAO,IAAI,OAAO,IAAM,MAAK;AAC7B,aAAO,IAAI,OAAO,KAAM,MAAK;AAC7B,QAAE,SAAS;AACX,aAAO;IACX;EACJ;AAGA,WAAS,UAAU,MAAc,OAAqC;AAClE,WAAO,EAAE,GAAG,MAAM,GAAG,MAAM;EAC/B;AAIA,WAAS,gBAAgB,IAA8C;AAzUvE,QAAA;AA0UI,UAAM,KAAI,KAAA,GAAG,UAAH,OAAA,KAAY,GAAG;AACzB,QAAI,CAAC,KAAK,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,EAAG,QAAO;AAC5D,WAAO;EACX;AAKA,WAAS,gBAAgB,MAAe,MAAe,GAAoB;AACvE,QAAI,SAAS,OAAW,QAAO;AAC/B,QAAI,SAAS,OAAW,QAAO;AAC/B,QAAI,OAAO,SAAS,YAAY,OAAO,SAAS,UAAU;AACtD,aAAO,QAAQ,OAAO,QAAQ;IAClC;AACA,QAAI,MAAM,QAAQ,IAAI,KAAK,MAAM,QAAQ,IAAI,KAAK,KAAK,WAAW,KAAK,QAAQ;AAC3E,YAAM,MAAqB,IAAI,MAAM,KAAK,MAAM;AAChD,eAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AAClC,cAAM,IAAI,OAAO,KAAK,CAAC,MAAM,WAAW,KAAK,CAAC,IAAI;AAClD,cAAM,IAAI,OAAO,KAAK,CAAC,MAAM,WAAW,KAAK,CAAC,IAAI;AAClD,YAAI,CAAC,IAAI,KAAK,IAAI,KAAK;MAC3B;AACA,aAAO;IACX;AACA,WAAO,IAAI,MAAM,OAAO;EAC5B;AAUA,WAAS,gBACL,OACA,OACA,GACA,WACA,yBACA,YACgB;AAChB,UAAM,QAAkC,EAAE,UAAU;AACpD,UAAM,OAAO,oBAAI,IAAY;AAC7B,QAAI,MAAO,YAAW,KAAK,OAAO,KAAK,KAAK,EAAG,MAAK,IAAI,CAAC;AACzD,QAAI,MAAO,YAAW,KAAK,OAAO,KAAK,KAAK,EAAG,MAAK,IAAI,CAAC;AACzD,eAAW,KAAK,MAAM;AAClB,UAAI,MAAM,YAAa;AACvB,UAAI,MAAM,YAAY,WAAY;AAClC,YAAM,KAAM,SAAA,OAAA,SAAA,MAAgD,CAAA;AAC5D,YAAM,KAAM,SAAA,OAAA,SAAA,MAAgD,CAAA;AAC5D,UAAI,OAAO,UAAa,OAAO,OAAW;AAC1C,YAAM,CAAC,IAAI,gBAAgB,IAAI,IAAI,CAAC;IACxC;AACA,QAAI,4BAA4B,QAAW;AAGvC,YAAM,SAAS,0BAA0B,iBAAiB,OAAO,OAAO,CAAC;IAC7E;AACA,WAAO;EACX;AAIA,WAAS,iBACL,OACA,OACA,GACM;AACN,UAAM,KAAK,QAAO,SAAA,OAAA,SAAA,MAAO,YAAW,WAAW,MAAM,SAAS;AAC9D,UAAM,KAAK,QAAO,SAAA,OAAA,SAAA,MAAO,YAAW,WAAW,MAAM,SAAS;AAC9D,QAAI,OAAO,UAAa,OAAO,OAAW,QAAO;AACjD,UAAM,IAAI,gBAAgB,IAAI,IAAI,CAAC;AACnC,WAAO,OAAO,MAAM,WAAW,IAAI;EACvC;AAMA,WAAS,qBAAqB,KAAiB,KAAyB;AACpE,UAAM,KAAK,eAAe,GAAG;AAC7B,UAAM,KAAK,eAAe,GAAG;AAC7B,QAAI,CAAC,MAAM,CAAC,GAAI,QAAO;AACvB,UAAM,MAAM,gBAAgB,KAAK,KAAK,IAAI,EAAE;AAC5C,UAAM,MAAM,sBAAsB,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC;AACnE,WAAO,KAAK,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,MAAM,KAAK;EACnD;AAIA,WAAS,kBAAkB,GAAW,GAAmB;AACrD,QAAI,IAAI,IAAI;AACZ,WAAO,IAAI,IAAM,MAAK;AACtB,WAAO,IAAI,KAAM,MAAK;AACtB,WAAO;EACX;AAiBA,WAAS,gCACL,KACA,QAAoB,QACpB,SAAiB,SACjB,aACI;AAhcR,QAAA;AAicI,UAAM,SAAS,IAAI,IAAI,SAAS,CAAC;AACjC,UAAM,SAAS,KAAA,OAAO,MAAP,OAAA,KAAY,OAAO;AAClC,UAAM,WAAW,SAAA,OAAA,SAAA,MAAO;AACxB,QAAI,OAAO,aAAa,SAAU;AAKlC,UAAM,YAAY,gBAAgB,MAAM;AACxC,UAAM,kBAAkB,WAAW,iBAAiB,WAAW,WAAW,CAAC;AAE3E,UAAM,MAAM,gBAAgB,QAAQ,QAAQ,SAAS,OAAO;AAC5D,UAAM,aAAa,sBAAsB,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC;AAC1E,UAAM,YAAY,KAAK,MAAM,WAAW,CAAC,GAAG,WAAW,CAAC,CAAC,IAAI,MAAM,KAAK;AACxE,UAAM,QAAQ,kBAAkB,WAAW,eAAe;AAC1D,QAAI,KAAK,IAAI,KAAK,KAAK,YAAa;AASpC,UAAM,WAAW,UAAU,MAAM;AACjC,UAAM,WAAW,KAAK,IAAI,WAAW,gCAAgC,WAAW,UAAU,MAAM,KAAK,CAAC;AACtG,UAAM,WAAW;MACb,gBAAgB,MAAM;MAAG,gBAAgB,MAAM;MAAG;MAClD;MAAS;MAAW;IACxB;AACA,QAAI,KAAK,UAAU,UAAU,QAAQ,CAAC;EAC1C;AAKA,MAAM,gCAAgC;AAMtC,WAAS,mBACL,KACA,QAAoB,QACpB,SAAiB,SACjB,YACA,aAAqB,aAAqB,YACtC;AACJ,UAAM,MAAM,gBAAgB,QAAQ,QAAQ,SAAS,OAAO;AAC5D,UAAM,WAAW,UAAU,MAAM;AACjC,UAAM,WAAW,UAAU,MAAM;AACjC,UAAM,aAAa,YAAY,MAAM;AACrC,UAAM,WAAW,aAAa,UAAU;AACxC,UAAM,QAAQ,gBAAgB,MAAM;AACpC,UAAM,QAAQ,gBAAgB,MAAM;AAGpC,UAAM,aAAa,gBAAgB,KAAK,YAAY,aAAa,aAAa,UAAU;AAOxF,UAAM,UAAyB,CAAC;AAChC,eAAW,KAAK,YAAY;AACxB,YAAM,MAAM,gBAAgB,IAAI,KAAK,CAAC;AACtC,YAAM,IAAI,MAAM,IAAI,WAAW,IAAI,MAAM,IAAI,WAAW,GAAG,GAAG,CAAC;AAC/D,YAAM,IAAI,MAAM,SAAS,CAAC,GAAG,GAAG,CAAC;AACjC,YAAM,MAAM,iBAAiB,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC;AAC9D,YAAM,SAAiB,EAAE,GAAG,GAAG,IAAI;AACnC,UAAI,YAAY;AACZ,cAAM,MAAM,sBAAsB,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC;AACnE,eAAO,YAAY,KAAK,MAAM,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,MAAM,KAAK;MAC/D;AACA,cAAQ,KAAK,MAAM;IACvB;AAKA,QAAI,YAAY;AAChB,QAAI,QAAQ;AACZ,UAAM,WAAW,IAAI,SAAS;AAC9B,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACrC,YAAM,IAAI,QAAQ,CAAC;AACnB,YAAM,QAAQ,QAAQ,IAAI,OAAO,EAAE,IAAI,UAAU,IAAI,QAAQ,GAAG,CAAC,IAAI;AACrE,YAAM,EAAE,MAAM,MAAM,IAAI,YAAY,WAAW,KAAK;AAKpD,YAAM,WAAW,MAAM,IAAI,WAAW,IAAI,SAAS;AACnD,UAAI,KAAM,KAAI,QAAQ,EAAE,IAAI;UACvB,QAAO,IAAI,QAAQ,EAAE;AAE1B,YAAM,UAAU,WAAW,EAAE,KAAK,WAAW;AAC7C,YAAM,QAAQ,gBAAgB,OAAO,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,WAAW,UAAU;AAC/E,UAAI,KAAK,UAAU,SAAS,KAAK,CAAC;AAElC,kBAAY;AACZ,cAAQ,EAAE;IACd;EACJ;AAQA,WAAS,gBACL,KAA6B,YAC7B,aAAqB,aAAqB,YAC7B;AAEb,UAAM,WAA0B,CAAC;AACjC,oBAAgB,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,QAAQ;AACpE,oBAAgB,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,QAAQ;AACpE,aAAS,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAE7B,UAAM,WAA0B,CAAC,CAAC;AAClC,eAAW,KAAK,UAAU;AACtB,UAAI,IAAI,SAAS,SAAS,SAAS,CAAC,IAAI,QAAQ,IAAI,IAAI,MAAM;AAC1D,iBAAS,KAAK,CAAC;MACnB;IACJ;AACA,aAAS,KAAK,CAAC;AAEf,UAAM,MAAqB,CAAC;AAC5B,UAAM,SAAS,EAAE,WAAW,aAAa,SAAS,OAAO;AACzD,aAAS,IAAI,GAAG,IAAI,SAAS,SAAS,GAAG,KAAK;AAC1C,aAAO,SAAS,CAAC,GAAG,SAAS,IAAI,CAAC,GAAG,KAAK,KAAK,YAAY,aAAa,aAAa,MAAM;IAC/F;AACA,WAAO;EACX;AAOA,WAAS,gBAAgB,IAAY,IAAY,IAAY,IAAY,KAA0B;AAC/F,UAAM,IAAI,KAAK;AACf,UAAM,IAAI,KAAK;AACf,UAAM,IAAI,KAAK;AACf,UAAM,IAAI,IAAI,IAAI,IAAI;AACtB,UAAM,IAAI,KAAK,IAAI;AACnB,UAAM,IAAI;AACV,QAAI,KAAK,IAAI,CAAC,IAAI,OAAO;AACrB,UAAI,KAAK,IAAI,CAAC,IAAI,OAAO;AACrB,cAAM,IAAI,CAAC,IAAI;AACf,YAAI,IAAI,QAAQ,IAAI,IAAI,KAAM,KAAI,KAAK,CAAC;MAC5C;AACA;IACJ;AACA,UAAM,OAAO,IAAI,IAAI,IAAI,IAAI;AAC7B,QAAI,OAAO,EAAG;AACd,UAAM,KAAK,KAAK,KAAK,IAAI;AACzB,UAAM,MAAM,CAAC,IAAI,OAAO,IAAI;AAC5B,UAAM,MAAM,CAAC,IAAI,OAAO,IAAI;AAC5B,QAAI,KAAK,QAAQ,KAAK,IAAI,KAAM,KAAI,KAAK,EAAE;AAC3C,QAAI,KAAK,QAAQ,KAAK,IAAI,KAAM,KAAI,KAAK,EAAE;EAC/C;AAWA,WAAS,OACL,IAAY,IACZ,KACA,KACA,YACA,aAAqB,aACrB,QACI;AACJ,UAAM,QAAQ,KAAK,MAAM;AACzB,UAAM,KAAK,iBAAiB,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE;AAC9D,UAAM,KAAK,iBAAiB,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE;AAC9D,UAAM,OAAO,KAAK;AAClB,UAAM,MAAM,iBAAiB,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,OAAO,IAAI;AAC7E,UAAM,MAAM,iBAAiB,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;AACjE,UAAM,MAAM,iBAAiB,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,OAAO,IAAI;AAE7E,UAAM,MAAM,KAAK;MACb,SAAS,KAAK,IAAI,EAAE;MACpB,SAAS,KAAK,IAAI,EAAE;MACpB,SAAS,KAAK,IAAI,EAAE;IACxB;AACA,QAAI,QAAQ;AACZ,QAAI,YAAY;AACZ,YAAM,OAAO,sBAAsB,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE;AACrE,YAAM,OAAO,sBAAsB,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE;AACrE,YAAM,OAAO,KAAK,MAAM,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,MAAM,KAAK;AACvD,YAAM,OAAO,KAAK,MAAM,KAAK,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,MAAM,KAAK;AACvD,UAAI,QAAQ,KAAK,IAAI,OAAO,IAAI;AAChC,UAAI,QAAQ,IAAK,SAAQ,MAAM;AAC/B,UAAI,QAAQ,YAAa,SAAQ;IACrC;AAEA,QAAK,OAAO,eAAe,SAAU,OAAO,aAAa,KAAK,OAAO,MAAM;AACvE,UAAI,KAAK,EAAE;AACX;IACJ;AAEA,WAAO,aAAa;AACpB,WAAO,IAAI,MAAM,KAAK,KAAK,YAAY,aAAa,aAAa,MAAM;AACvE,WAAO,MAAM,IAAI,KAAK,KAAK,YAAY,aAAa,aAAa,MAAM;EAC3E;AAGA,WAAS,SAAS,GAAW,IAAY,IAAoB;AACzD,UAAM,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC;AACvB,UAAM,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC;AACvB,UAAM,OAAO,KAAK,KAAK,KAAK;AAC5B,QAAI,OAAO,OAAO;AACd,YAAM,MAAM,EAAE,CAAC,IAAI,GAAG,CAAC;AACvB,YAAM,MAAM,EAAE,CAAC,IAAI,GAAG,CAAC;AACvB,aAAO,KAAK,KAAK,MAAM,MAAM,MAAM,GAAG;IAC1C;AACA,UAAM,SAAS,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK,MAAM,EAAE,CAAC,IAAI,GAAG,CAAC,KAAK;AACrD,WAAO,KAAK,IAAI,KAAK,IAAI,KAAK,KAAK,IAAI;EAC3C;AAWO,WAAS,6BACZ,MACA,MACM;AACN,UAAM,MAAM,mBAAmB,MAAM,IAAI;AACzC,WAAO,OAAA,OAAA,MAAO;EAClB;AAEA,WAAS,mBAAmB,MAAc,MAAwD;AAC9F,QAAI;AACJ,QAAI,KAAK,UAAU;AACf,eAAS,IAAI,GAAG,IAAI,KAAK,SAAS,QAAQ,KAAK;AAC3C,cAAM,KAAK,KAAK,SAAS,CAAC;AAC1B,cAAM,MAAM,mBAAmB,IAAI,IAAI;AACvC,YAAI,QAAQ,MAAM;AACd,cAAI,CAAC,YAAa,eAAc,KAAK,SAAS,MAAM;AACpD,sBAAY,CAAC,IAAI;QACrB;MACJ;IACJ;AAEA,QAAI;AACJ,UAAM,aAAa,KAAK;AACxB,QAAI,cAAc,OAAO,eAAe,YAAY,CAAC,MAAM,QAAQ,UAAU,GAAG;AAC5E,YAAM,UAAU;AAChB,YAAM,gBAAgB,QAAQ;AAC9B,UAAI,iBAAiB,OAAO,kBAAkB,YAAY,qBAAqB,aAAa,GAAG;AAC3F,cAAM,eAAe,gCAAgC,eAAe,IAAI;AACxE,YAAI,iBAAiB,eAAe;AAChC,uBAAaF,eAAAC,gBAAA,CAAA,GAAK,OAAA,GAAL,EAAc,WAAW,aAAa,CAAA;QACvD;MACJ;IACJ;AAEA,QAAI,CAAC,eAAe,CAAC,WAAY,QAAO;AACxC,UAAM,SAAiBA,gBAAA,CAAA,GAAK,IAAA;AAC5B,QAAI,YAAa,QAAO,WAAW;AACnC,QAAI,WAAa,QAAO,UAAW;AACnC,WAAO;EACX;ACjrBA,WAAS,kBAAkB,GAA+B;AACtD,UAAM,SAAS,EAAE,MAAM,qBAAqB,EAAE,IAAI,CAAA,MAAK,EAAE,KAAK,CAAC,EAAE,OAAO,CAAA,MAAK,KAAK,MAAM,GAAG;AAE3F,UAAM,WAA+B,CAAC;AACtC,QAAI,iBAAqC;AAEzC,eAAW,SAAS,QAAQ;AACxB,UAAI,aAAa,KAAK,KAAK,GAAG;AAC1B,yBAAiB,EAAE,MAAM,OAAO,QAAQ,CAAC,EAAE;AAC3C,iBAAS,KAAK,cAAc;MAChC,WAAW,gBAAgB;AACvB,cAAM,QAAQ,CAAC;AACf,uBAAe,OAAO,KAAK,OAAO,MAAM,KAAK,IAAI,IAAI,KAAK;MAC9D;IACJ;AAEA,WAAO;EACX;AAMO,WAAS,qBAAqB,GAAgC;AACjE,UAAM,MAA2B,CAAC;AAClC,QAAI;AAEJ,UAAM,WAAW,kBAAkB,CAAC;AAEpC,eAAW,WAAW,UAAU;AAC5B,YAAM,OAAO,QAAQ;AACrB,YAAM,SAAS,QAAQ;AAEvB,UAAI,SAAS,OAAO,SAAS,KAAK;AAC9B,cAAM,IAAI,OAAO,CAAC,KAAK;AACvB,cAAM,IAAI,OAAO,CAAC,KAAK;AACvB,sBAAc;UACV,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;UACV,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;UACV,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;UACV,GAAG;QACP;AACA,YAAI,KAAK,WAAW;AACpB;MACJ;AAGA,UAAI,CAAC,aAAa;AACd,sBAAc;UACV,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;UACV,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;UACV,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;UACV,GAAG;QACP;AACA,YAAI,KAAK,WAAW;MACxB;AAEA,UAAI,SAAS,KAAK;AACd,cAAM,IAAI,OAAO,CAAC,KAAK;AACvB,cAAM,IAAI,OAAO,CAAC,KAAK;AACvB,oBAAY,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;AACzB,oBAAY,EAAG,KAAK,CAAC,GAAG,CAAC,CAAC;AAC1B,oBAAY,EAAG,KAAK,CAAC,GAAG,CAAC,CAAC;MAE9B,WAAW,SAAS,KAAK;AACrB,cAAM,OAAO,OAAO,CAAC,KAAK;AAC1B,cAAM,OAAO,OAAO,CAAC,KAAK;AAC1B,cAAM,OAAO,OAAO,CAAC,KAAK;AAC1B,cAAM,OAAO,OAAO,CAAC,KAAK;AAC1B,cAAM,KAAK,OAAO,CAAC,KAAK;AACxB,cAAM,KAAK,OAAO,CAAC,KAAK;AAGxB,oBAAY,EAAG,YAAY,EAAG,SAAS,CAAC,IAAI,CAAC,MAAM,IAAI;AAGvD,oBAAY,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;AAC3B,oBAAY,EAAG,KAAK,CAAC,MAAM,IAAI,CAAC;AAChC,oBAAY,EAAG,KAAK,CAAC,IAAI,EAAE,CAAC;MAEhC,WAAW,SAAS,OAAO,SAAS,KAAK;AACrC,oBAAY,IAAI;MAEpB,OAAO;AACH,gBAAQ,KAAK,+BAA+B,OAAO,GAAG;MAC1D;IACJ;AAEA,WAAO;EACX;AAOA,WAAS,gBAAgBC,MAAiC;AACtD,QAAIA,KAAI,WAAW,OAAO,KAAKA,KAAI,SAAS,GAAG,GAAG;AAC9C,aAAOA,KAAI,MAAM,GAAG,EAAE;IAC1B;AAEA,QAAI,0BAA0B,KAAKA,IAAG,GAAG;AACrC,aAAOA;IACX;AACA,WAAO;EACX;AAKA,WAAS,aAAa,OAA6B;AAC/C,WAAO,OAAO,UAAU,YAAY,gBAAgB,KAAK,MAAM;EACnE;AAcA,WAAS,mBAAmB,OAAkD;AAE1E,QAAI,SAAS,OAAO,UAAU,YAAY,OAAO,MAAM,SAAS,UAAU;AACtE,YAAM,IAAI,gBAAgB,MAAM,IAAI;AACpC,aAAO,IAAI,EAAE,OAAO,qBAAqB,CAAC,EAAE,IAAI;IACpD;AAGA,QAAI,SAAS,OAAO,UAAU,YAAY,WAAW,OAAO;AACxD,YAAM,aAAa,MAAM;AACzB,UAAI,MAAM,QAAQ,UAAU,KAAK,WAAW,SAAS,GAAG;AAEpD,YAAI,aAAa,WAAW,CAAC,CAAC,GAAG;AAC7B,gBAAM,QAA6B,CAAC;AACpC,qBAAWC,YAAW,YAAY;AAC9B,kBAAM,IAAI,gBAAgBA,QAAO;AACjC,gBAAI,GAAG;AACH,oBAAM,KAAK,GAAG,qBAAqB,CAAC,CAAC;YACzC;UACJ;AACA,iBAAO,EAAE,MAAM;QACnB;MACJ;AAEA,aAAO;IACX;AAGA,QAAI,MAAM,QAAQ,KAAK,GAAG;AACtB,UAAI,MAAM,SAAS,KAAK,aAAa,MAAM,CAAC,CAAC,GAAG;AAC5C,cAAM,QAA6B,CAAC;AACpC,mBAAWA,YAAW,OAAO;AACzB,gBAAM,IAAI,gBAAgBA,QAAO;AACjC,cAAI,GAAG;AACH,kBAAM,KAAK,GAAG,qBAAqB,CAAC,CAAC;UACzC;QACJ;AACA,eAAO,EAAE,MAAM;MACnB;AAEA,aAAO,EAAE,OAAO,MAAM;IAC1B;AAGA,QAAI,aAAa,KAAK,GAAG;AACrB,YAAM,IAAI,gBAAgB,KAAK;AAC/B,aAAO,EAAE,OAAO,qBAAqB,CAAC,EAAE;IAC5C;AAEA,WAAO;EACX;AAaA,WAAS,cACL,QACA,MAC4C;AAvOhD,QAAA;AAwOI,QAAI,CAAC,OAAQ,QAAO;AAEpB,QAAI,MAAM,QAAQ,MAAM,GAAG;AACvB,aAAO;IACX;AAGA,SAAI,KAAA,QAAA,OAAA,SAAA,KAAM,YAAN,OAAA,SAAA,GAAgB,MAAA,GAAS;AACzB,aAAO,KAAK,QAAQ,MAAM;IAC9B;AAGA,YAAQ,KAAK,0BAA0B,MAAM;AAC7C,WAAO;EACX;AAQA,WAAS,iBACL,SACA,MACiC;AAjQrC,QAAA;AAkQI,QAAI,OAAO,YAAY,UAAU;AAE7B,YAAM,YAAW,KAAA,QAAA,OAAA,SAAA,KAAM,eAAN,OAAA,SAAA,GAAmB,OAAA;AACpC,UAAI,CAAC,UAAU;AACX,gBAAQ,KAAK,6BAA6B,OAAO;MACrD;AACA,aAAO;IACX;AAGA,WAAO;EACX;AAQA,WAAS,wBACL,SACA,MACuB;AACvB,QAAI,CAAC,QAAS,QAAO,CAAC;AAEtB,UAAM,UAAmC,CAAC;AAE1C,QAAI,OAAO,YAAY,UAAU;AAC7B,YAAM,WAAW,iBAAiB,SAAS,IAAI;AAC/C,UAAI,SAAU,SAAQ,KAAK,QAAQ;IACvC,WAAW,MAAM,QAAQ,OAAO,GAAG;AAC/B,iBAAW,QAAQ,SAAS;AACxB,cAAM,WAAW,iBAAiB,MAAM,IAAI;AAC5C,YAAI,SAAU,SAAQ,KAAK,QAAQ;MACvC;IACJ,OAAO;AAEH,cAAQ,KAAK,OAAO;IACxB;AAEA,WAAO;EACX;AAeO,WAAS,iBAAiB,UAAkB,GAAQ,GAAQ,GAAgB;AA1TnF,QAAA,IAAA;AA2TI,QAAI,aAAa,KAAK;AAClB,YAAM,UAAS,KAAA,KAAA,OAAA,SAAA,EAAG,UAAH,OAAA,KAAa,MAAM,QAAQ,CAAC,IAAI,IAAI,CAAC;AACpD,YAAM,UAAS,KAAA,KAAA,OAAA,SAAA,EAAG,UAAH,OAAA,KAAa,MAAM,QAAQ,CAAC,IAAI,IAAI,CAAC;AACpD,aAAO,EAAE,OAAO,mBAAmB,QAAQ,QAAQ,CAAC,EAAE;IAC1D;AACA,QAAI,kBAAkB,IAAI,QAAQ,GAAG;AACjC,aAAO,iBAAiB,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC;IACnE;AAKA,QAAI,aAAa,eACV,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC,KACvD,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC,GAC5D;AACE,aAAO,0BAA0B,GAAuB,GAAuB,CAAC;IACpF;AAKA,QAAI,aAAa,YAAY,OAAO,MAAM,YAAY,OAAO,MAAM,UAAU;AACzE,aAAO,eAAe,GAAG,GAAG,CAAC;IACjC;AACA,QAAI,mBAAmB,IAAI,QAAQ,KAAK,aAAa,sBAAsB,aAAa,mBAAmB;AACvG,aAAO,eAAe,KAAK,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC;IAC7C;AACA,WAAO,eAAe,EAAE,KAAK,IAAI,EAAE,KAAK,IAAI,CAAC;EACjD;AAIA,WAAS,0BAA0B,GAAqB,GAAqB,GAA6B;AACtG,UAAM,OAAO,oBAAI,IAAY,CAAC,GAAG,OAAO,KAAK,KAAA,OAAA,IAAK,CAAC,CAAC,GAAG,GAAG,OAAO,KAAK,KAAA,OAAA,IAAK,CAAC,CAAC,CAAC,CAAC;AAC/E,UAAM,MAAgC,CAAC;AACvC,eAAW,KAAK,MAAM;AAClB,YAAM,KAAM,KAAA,OAAA,SAAA,EAAiC,CAAA;AAC7C,YAAM,KAAM,KAAA,OAAA,SAAA,EAAiC,CAAA;AAC7C,UAAI,MAAM,YAAY,MAAM,QAAQ;AAChC,YAAI,CAAC,IAAI,eAAe,EAAE,MAAA,OAAA,KAAM,IAAI,EAAE,MAAA,OAAA,KAAM,IAAI,CAAC;MACrD,WAAW,MAAM,eAAe,MAAM,WAAW,MAAM,UAAU;AAC7D,cAAM,WAA0B,MAAM,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;AAC9D,YAAI,CAAC,IAAI,eAAgB,MAAwB,UAAW,MAAwB,UAAU,CAAC;MACnG,OAAO;AAEH,YAAI,CAAC,IAAI,MAAA,OAAA,KAAM;MACnB;IACJ;AACA,WAAO;EACX;AAgBA,WAAS,oBACL,UACA,WACA,MACA,UACY;AAlYhB,QAAA,IAAA,IAAA,IAAA,IAAA;AAmYI,UAAM,iBAAiB,UAAU,SAAS;AAC1C,UAAM,WAAW,OAAM,KAAA,KAAK,iBAAL,OAAA,KAAqB,gBAAgB,GAAG,cAAc;AAG7E,QAAI;AACJ,QAAI,KAAK,QAAQ;AACb,eAAS,UAAU,MAAM,GAAG,WAAW,CAAC;IAC5C,OAAO;AACH,eAAS,UAAU,MAAM,iBAAiB,QAAQ;IACtD;AAGA,UAAM,UAAS,KAAA,UAAU,CAAC,EAAE,MAAb,OAAA,KAAkB;AACjC,UAAM,SAAQ,KAAA,UAAU,UAAU,SAAS,CAAC,EAAE,MAAhC,OAAA,KAAqC;AAEnD,QAAI,WAAmB;AACvB,QAAI,KAAK,QAAQ;AACb,kBAAY;AACZ,gBAAU;IACd,OAAO;AACH,kBAAY;AACZ,gBAAU;IACd;AAEA,UAAM,eAAe,UAAU;AAC/B,QAAI,gBAAgB,EAAG,QAAO;AAG9B,UAAM,aAAY,KAAA,OAAO,CAAC,EAAE,MAAV,OAAA,KAAe;AACjC,UAAM,WAAU,KAAA,OAAO,OAAO,SAAS,CAAC,EAAE,MAA1B,OAAA,KAA+B;AAC/C,UAAM,cAAc,UAAU;AAC9B,QAAI,eAAe,EAAG,QAAO;AAG7B,UAAM,WAAgC,OAAO,IAAI,CAAA,OAAG;AAraxD,UAAAC,KAAAC;AAqa4D,aAAA;QACpD,OAAO,GAAG,IAAK,aAAa;QAC5B,GAAG,GAAG;QACN,GAAG,GAAG;QACN,YAAYD,MAAA,GAAG,cAAH,OAAAA,MAAgB,GAAG;QAC/B,aAAaC,MAAA,GAAG,eAAH,OAAAA,MAAiB,GAAG;MACrC;IAAA,CAAE;AAEF,UAAM,WAAW,KAAK,MAAM,eAAe,WAAW;AACtD,UAAM,YAAY,eAAe,WAAW;AAC5C,UAAM,kBAAkB,YAAY;AAEpC,UAAM,SAAuB,CAAC;AAG9B,aAAS,UAAU,UAAkB,YAAqB,SAAkB;AACxE,UAAI;AACJ,UAAI,YAAY;AAEZ,kBAAU,CAAC;AACX,iBAAS,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK;AAC3C,kBAAQ,KAAK;YACT,MAAM,IAAI,SAAS,CAAC,EAAE;YACtB,GAAG,SAAS,CAAC,EAAE;;YAEf,GAAG,IAAI,IAAI,cAAc,SAAS,IAAI,CAAC,EAAE,CAAC,IAAI;;;;YAI9C,WAAW,SAAS,CAAC,EAAE;YACvB,YAAY,SAAS,CAAC,EAAE;UAC5B,CAAC;QACL;MACJ,OAAO;AACH,kBAAU;MACd;AAEA,YAAM,UAAU,YAAY,SAAY,UAAU;AAElD,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACrC,cAAM,QAAQ,QAAQ,CAAC;AACvB,YAAI,MAAM,OAAO,UAAU,MAAM;AAE7B,gBAAM,OAAO,QAAQ,IAAI,CAAC;AAC1B,gBAAM,eAAe,MAAM,OAAO,KAAK;AACvC,gBAAM,aAAa,UAAU,KAAK,QAAQ;AAG1C,gBAAM,YAAY,KAAK,IAAI,YAAY,KAAK,CAAC,EAAE,SAAS,IAAI;AAC5D,gBAAM,WAAW,iBAAiB,UAAU,KAAK,GAAG,MAAM,GAAG,SAAS;AAGtE,gBAAM,EAAE,MAAM,WAAW,IAAI,YAAY,KAAK,GAAG,SAAS;AAG1D,cAAI,OAAO,SAAS,KAAK,KAAK,QAAQ,SAAS;AAC3C,mBAAO,OAAO,SAAS,CAAC,EAAE,IAAI;UAClC;AAEA,iBAAO,KAAK,EAAE,GAAG,WAAW,UAAU,aAAa,GAAG,UAAU,GAAG,OAAU,CAAC;AAC9E;QACJ;AAEA,cAAM,SAAqB;UACvB,GAAG,WAAW,MAAM,OAAO;UAC3B,GAAG,MAAM;UACT,GAAG,IAAI,QAAQ,SAAS,IAAI,MAAM,IAAI;QAC1C;AAGA,YAAI,MAAM,UAAW,QAAO,YAAY,MAAM;AAC9C,YAAI,MAAM,WAAY,QAAO,aAAa,MAAM;AAChD,eAAO,KAAK,MAAM;MACtB;IACJ;AASA,aAAS,cAAc,UAAkB,YAAqB,cAAsB;AAChF,UAAI;AACJ,UAAI,YAAY;AACZ,kBAAU,CAAC;AACX,iBAAS,IAAI,SAAS,SAAS,GAAG,KAAK,GAAG,KAAK;AAC3C,kBAAQ,KAAK;YACT,MAAM,IAAI,SAAS,CAAC,EAAE;YACtB,GAAG,SAAS,CAAC,EAAE;YACf,GAAG,IAAI,IAAI,cAAc,SAAS,IAAI,CAAC,EAAE,CAAC,IAAI;YAC9C,WAAW,SAAS,CAAC,EAAE;YACvB,YAAY,SAAS,CAAC,EAAE;UAC5B,CAAC;QACL;MACJ,OAAO;AACH,kBAAU;MACd;AAEA,YAAM,YAAY,IAAI;AAEtB,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACrC,cAAM,QAAQ,QAAQ,CAAC;AACvB,YAAI,MAAM,OAAO,YAAY,KAAM;AACnC,cAAM,OAAO,QAAQ,IAAI,CAAC;AAK1B,YAAI,QAAQ,KAAK,OAAO,YAAY,QAAQ,MAAM,OAAO,YAAY,MAAM;AACvE,gBAAM,eAAe,MAAM,OAAO,KAAK;AACvC,gBAAM,aAAa,YAAY,KAAK,QAAQ;AAC5C,gBAAM,YAAY,KAAK,IAAI,YAAY,KAAK,CAAC,EAAE,SAAS,IAAI;AAC5D,gBAAM,aAAa,iBAAiB,UAAU,KAAK,GAAG,MAAM,GAAG,SAAS;AACxE,gBAAM,EAAE,OAAO,YAAY,IAAI,YAAY,KAAK,GAAG,SAAS;AAC5D,iBAAO,KAAK,EAAE,GAAG,UAAU,GAAG,YAAY,GAAG,YAAY,CAAC;QAC9D;AAEA,cAAM,SAAqB;UACvB,GAAG,YAAY,MAAM,OAAO,aAAa;UACzC,GAAG,MAAM;UACT,GAAG,IAAI,QAAQ,SAAS,IAAI,MAAM,IAAI;QAC1C;AACA,YAAI,MAAM,UAAW,QAAO,YAAY,MAAM;AAC9C,YAAI,MAAM,WAAY,QAAO,aAAa,MAAM;AAChD,eAAO,KAAK,MAAM;MACtB;IACJ;AAMA,QAAI,KAAK,QAAQ;AAMb,UAAI,kBAAkB,MAAM;AACxB,cAAM,aAAa,CAAC,CAAC,KAAK,aAAc,WAAW,MAAM;AACzD,sBAAc,WAAW,YAAY,eAAe;MACxD;AACA,eAAS,MAAM,GAAG,MAAM,UAAU,OAAO;AACrC,cAAM,mBAAmB,WAAW,IAAI;AACxC,cAAM,aAAa,CAAC,CAAC,KAAK,aAAc,mBAAmB,MAAM;AACjE,cAAM,WAAW,YAAY,YAAY,MAAM;AAC/C,kBAAU,UAAU,UAAU;MAClC;IACJ,OAAO;AAEH,eAAS,MAAM,GAAG,MAAM,UAAU,OAAO;AACrC,cAAM,aAAa,CAAC,CAAC,KAAK,aAAc,MAAM,MAAM;AACpD,cAAM,WAAW,YAAY,MAAM;AACnC,kBAAU,UAAU,UAAU;MAClC;AACA,UAAI,kBAAkB,MAAM;AACxB,cAAM,aAAa,CAAC,CAAC,KAAK,aAAc,WAAW,MAAM;AACzD,cAAM,WAAW,YAAY,WAAW;AACxC,kBAAU,UAAU,YAAY,eAAe;MACnD;IACJ;AAIA,QAAI,KAAK,QAAQ;AACb,aAAO,CAAC,GAAG,QAAQ,GAAG,SAAS;IACnC,OAAO;AACH,aAAO,CAAC,GAAG,WAAW,GAAG,MAAM;IACnC;EACJ;AAiBA,WAAS,mBACL,UACA,UACA,UACA,MACY;AAtmBhB,QAAA,IAAA,IAAA,IAAA,IAAA,IAAA,IAAA;AAumBI,UAAM,YAAY,SAAS,aAAa,SAAS,OAAO,CAAC;AAEzD,UAAM,aAA2B,CAAC;AAElC,eAAW,MAAM,WAAW;AACxB,YAAM,WAAU,MAAA,KAAA,GAAG,SAAH,OAAA,KAAW,GAAG,MAAd,OAAA,KAAmB;AACnC,UAAI,SAAQ,KAAA,GAAG,UAAH,OAAA,KAAY,GAAG;AAC3B,YAAM,UAAS,KAAA,GAAG,WAAH,OAAA,KAAa,GAAG;AAG/B,UAAI,aAAa,KAAK;AAClB,gBAAQ,mBAAmB,KAAK;MACpC;AAQA,YAAM,gBAAgB,gBAAgB,QAAQ,IAAI,6BAA6B,QAAQ,IAAI;AAC3F,UAAI,kBAAkB,IAAI,aAAa,GAAG;AACtC,iBAAQ,KAAA,WAAW,KAAK,MAAhB,OAAA,KAAqB;MACjC;AAEA,YAAM,SAAqB;QACvB,GAAG;QACH,GAAG;QACH,GAAG,cAAc,QAAQ,IAAI;MACjC;AAKA,YAAM,OAAM,KAAA,GAAG,cAAH,OAAA,KAAgB,GAAG;AAC/B,YAAM,QAAO,KAAA,GAAG,eAAH,OAAA,KAAiB,GAAG;AACjC,UAAI,IAAK,QAAO,YAAY;AAC5B,UAAI,KAAM,QAAO,aAAa;AAE9B,iBAAW,KAAK,MAAM;IAC1B;AAGA,eAAW,KAAK,CAAC,GAAG,MAAG;AAlpB3B,UAAAD,KAAAC;AAkpB+B,eAAAD,MAAA,EAAE,MAAF,OAAAA,MAAO,OAAMC,MAAA,EAAE,MAAF,OAAAA,MAAO;IAAA,CAAE;AAGjD,UAAM,UAAU,SAAS;AACzB,UAAM,OAA2B,YAAY,OAAO,CAAC,IAAI,WAAW;AACpE,QAAI,QAAQ,WAAW,UAAU,GAAG;AAChC,aAAO,oBAAoB,UAAU,YAAY,MAAM,QAAQ;IACnE;AAEA,WAAO;EACX;AAMA,WAAS,0BACL,YACqB;AACrB,UAAM,SAAgC,CAAC;AAEvC,eAAW,QAAQ,YAAY;AAC3B,iBAAW,CAAC,MAAM,QAAQ,KAAK,OAAO,QAAQ,IAAI,GAAG;AACjD,eAAO,IAAI,IAAI;MACnB;IACJ;AAEA,WAAO;EACX;AAoBO,WAAS,mCACZ,UACA,UACA,UACmB;AAtsBvB,QAAA;AAusBI,UAAM,UAAU,SAAS;AACzB,QAAI,YAAY,UAAa,YAAY,QAAQ,YAAY,MAAO,QAAO;AAC3E,UAAM,OAAe,YAAY,OAAO,CAAC,IAAK;AAC9C,UAAM,UAAU,KAAA,SAAS,cAAT,OAAA,KAAsB,SAAS;AAC/C,QAAI,CAAC,MAAM,QAAQ,MAAM,KAAK,OAAO,SAAS,EAAG,QAAO;AAWxD,UAAM,gBAAgB,gBAAgB,QAAQ,IAAI,6BAA6B,QAAQ,IAAI;AAC3F,UAAM,WAAW,kBAAkB,IAAI,aAAa;AACpD,UAAM,MAAoB,OAAO,IAAI,CAAA,OAAM;AAxtB/C,UAAAD,KAAA,IAAA,IAAA,IAAA,IAAA,IAAA,IAAA;AAytBQ,YAAM,KAAIA,MAAA,GAAG,MAAH,OAAAA,MAAQ,GAAG;AACrB,UAAI,KAAa,KAAA,GAAG,MAAH,OAAA,KAAQ,GAAG;AAC5B,UAAI,aAAa,IAAK,KAAI,mBAAmB,CAAC;AAC9C,UAAI,SAAU,MAAI,KAAA,WAAW,CAAC,MAAZ,OAAA,KAAiB;AACnC,YAAM,KAAI,KAAA,GAAG,MAAH,OAAA,KAAQ,GAAG;AACrB,YAAME,OAAkB,EAAE,GAAG,GAAG,EAAE;AAClC,WAAI,KAAA,GAAG,cAAH,OAAA,KAAgB,GAAG,GAAIA,MAAI,aAAa,KAAA,GAAG,cAAH,OAAA,KAAgB,GAAG;AAC/D,WAAI,KAAA,GAAG,eAAH,OAAA,KAAiB,GAAG,GAAIA,MAAI,cAAc,KAAA,GAAG,eAAH,OAAA,KAAiB,GAAG;AAClE,aAAOA;IACX,CAAC;AAED,UAAM,WAAW,oBAAoB,UAAU,KAAK,MAAM,QAAQ;AAClE,UAAM,MAA2B,EAAE,KAAK,SAAS;AACjD,QAAI,SAAS,eAAe,OAAY,KAAiC,aAAa,SAAS;AAC/F,WAAO;EACX;AASO,WAAS,+BACZ,MACA,UACM;AACN,UAAM,MAAM,wBAAwB,MAAM,QAAQ;AAClD,WAAO,OAAA,OAAA,MAAO;EAClB;AAEA,WAAS,wBAAwB,MAAc,UAAiC;AAC5E,QAAI;AACJ,QAAI,KAAK,UAAU;AACf,eAAS,IAAI,GAAG,IAAI,KAAK,SAAS,QAAQ,KAAK;AAC3C,cAAM,MAAM,wBAAwB,KAAK,SAAS,CAAC,GAAG,QAAQ;AAC9D,YAAI,QAAQ,MAAM;AACd,cAAI,CAAC,YAAa,eAAc,KAAK,SAAS,MAAM;AACpD,sBAAY,CAAC,IAAI;QACrB;MACJ;IACJ;AACA,QAAI;AACJ,UAAM,aAAa,KAAK;AACxB,QAAI,cAAc,OAAO,eAAe,YAAY,CAAC,MAAM,QAAQ,UAAU,GAAG;AAC5E,YAAM,UAAU;AAChB,iBAAW,YAAY,OAAO,KAAK,OAAO,GAAG;AACzC,cAAM,WAAW,QAAQ,QAAQ;AACjC,cAAM,eAAe,mCAAmC,UAAU,UAAU,QAAQ;AACpF,YAAI,iBAAiB,UAAU;AAC3B,cAAI,CAAC,WAAY,cAAaL,gBAAA,CAAA,GAAK,OAAA;AACnC,qBAAW,QAAQ,IAAI;QAC3B;MACJ;IACJ;AACA,QAAI,CAAC,eAAe,CAAC,WAAY,QAAO;AACxC,UAAM,SAAiBA,gBAAA,CAAA,GAAK,IAAA;AAC5B,QAAI,YAAa,QAAO,WAAW;AACnC,QAAI,WAAa,QAAO,UAAW;AACnC,WAAO;EACX;AAMA,MAAI,oBAAoB;AACjB,WAAS,oBAA4B;AACxC,WAAO,YAAa,EAAE;EAC1B;AAcA,WAAS,6BACL,SACA,UACA,MACA,SAA2B,iBAAiB,QACvB;AACrB,UAAM,aAAoC,CAAC;AAE3C,eAAW,CAAC,UAAU,QAAQ,KAAK,OAAO,QAAQ,OAAO,GAAG;AACxD,YAAM,gBAAgB,mBAAmB,UAAU,UAAU,UAAU,IAAI;AAC3E,UAAI,cAAc,SAAS,GAAG;AAC1B,cAAM,MAA2B,EAAE,KAAK,cAAc;AAItD,YAAI,SAAS,eAAe,OAAW,KAAI,aAAa,SAAS;AACjE,YAAI,SAAS,SAAS,OAAW,KAAI,OAAO,SAAS;AAWrD,mBAAW,QAAQ,IAAK,WAAW,iBAAiB,UAAU,aAAa,cACrE,gCAAgC,GAAG,IACnC;MACV;IACJ;AAEA,WAAO;EACX;AAQO,WAAS,sBACZ,KACA,SAA2B,iBAAiB,QACjC;AACX,UAAM,iBAAiB,kBAAkB,GAAG,KAAK,CAAC;AAClD,UAAM,OAAO,QAAQ,GAAG;AACxB,UAAM,WAAW,eAAe,YAAY;AAE5C,UAAM,WAAwB,CAAC;AAG/B,UAAM,mBAAmB,CACrB,IACA,YACmB;AACnB,UAAI,CAAC,QAAS,QAAO;AAErB,YAAM,WAAW,wBAAwB,SAAS,IAAI;AACtD,UAAI,SAAS,WAAW,EAAG,QAAO;AAElC,YAAM,SAAS,0BAA0B,QAAQ;AACjD,YAAM,iBAAiB,6BAA6B,QAAQ,UAAU,MAAM,MAAM;AAElF,UAAI,OAAO,KAAK,cAAc,EAAE,WAAW,EAAG,QAAO;AAErD,aAAO;QACH;QACA,SAAS;MACb;IACJ;AAGA,UAAM,cAAc,YAAY,GAAG;AACnC,QAAI,aAAa;AACb,iBAAW,WAAW,aAAa;AAC/B,cAAM,aAAa,iBAAiB,QAAQ,IAAI,QAAQ,OAAO;AAC/D,YAAI,WAAY,UAAS,KAAK,UAAU;MAC5C;IACJ;AASA,UAAM,cAAc,CAAC,SAAiB;AAClC,YAAM,aAAa,KAAK;AACxB,UAAI,cAAc,OAAO,KAAK,UAAU,EAAE,SAAS,GAAG;AAClD,cAAM,SAAS,KAAK,MAAM,kBAAkB;AAC5C,aAAK,KAAK;AACV,cAAM,aAAa,iBAAiB,QAAQ,UAAU;AACtD,YAAI,WAAY,UAAS,KAAK,UAAU;MAC5C;AAGA,UAAI,KAAK,UAAU;AACf,iBAAS,IAAI,GAAG,IAAI,KAAK,SAAS,QAAQ,KAAK;AAC3C,sBAAY,KAAK,SAAS,CAAC,CAAC;QAChC;MACJ;IACJ;AAGA,QAAI,IAAI,UAAU;AACd,eAAS,IAAI,GAAG,IAAI,IAAI,SAAS,QAAQ,KAAK;AAC1C,oBAAY,IAAI,SAAS,CAAC,CAAC;MAC/B;IACJ;AAEA,WAAO;EACX;AAUA,WAAS,iBAAiB,WAAyB,UAAkB;AAz6BrE,QAAA,IAAA;AAg7BI,UAAM,OAAO,UAAU,SAAS;AAChC,QAAI,SAAS,UAAU,CAAC;AACxB,QAAI,SAAS,UAAU,OAAO,IAAI,IAAI,CAAC;AAEvC,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC3B,YAAM,QAAQ,KAAA,UAAU,CAAC,EAAE,MAAb,OAAA,KAAkB;AAChC,YAAM,QAAQ,KAAA,UAAU,IAAI,CAAC,EAAE,MAAjB,OAAA,KAAsB;AACpC,UAAI,QAAQ,YAAY,YAAY,MAAM;AACtC,iBAAS,UAAU,CAAC;AACpB,iBAAS,UAAU,IAAI,CAAC;AACxB;MACJ;AAEA,UAAI,WAAW,QAAQ,MAAM,OAAO,GAAG;AACnC,iBAAS,UAAU,OAAO,IAAI,OAAO,IAAI,CAAC;AAC1C,iBAAS,UAAU,IAAI;MAC3B;IACJ;AACA,WAAO,EAAE,QAAQ,OAAO;EAC5B;AAKA,WAAS,kBACL,UACA,UACA,UAC+B;AA58BnC,QAAA,IAAA,IAAA,IAAA,IAAA,IAAA,IAAA;AA68BI,UAAM,YAAY,SAAS,OAAO,SAAS,aAAa,CAAC;AACzD,QAAI,UAAU,WAAW,EAAG,QAAO;AAEnC,UAAM,EAAE,QAAQ,OAAO,IAAI,iBAAiB,WAAW,QAAQ;AAG/D,QAAI,gBAAiB,WAAW,SAAU,IAAI,MAAM,WAAU,KAAA,OAAO,MAAP,OAAA,KAAY,IAAG,KAAA,OAAO,MAAP,OAAA,KAAY,GAAG,GAAG,CAAC;AAChG,oBAAgB,MAAM,eAAe,GAAG,CAAC;AACzC,UAAM,UAAS,KAAA,OAAO,MAAP,OAAA,KAAY,OAAO;AAClC,QAAI,UAAU,MAAM,QAAQ,MAAM,GAAG;AACjC,UAAI;AACA,wBAAgB,YAAY,MAA0C,EAAE,aAAa;MACzF,SAAS,GAAG;MAEZ;IACJ;AAEA,QAAI,cAAc,gBAAgB,QAAQ,IAAI,6BAA6B,QAAQ,IAAI;AACvF,QAAI,WAAmC;AAEvC,UAAM,SAAQ,KAAA,UAAA,OAAA,SAAA,OAAQ,MAAR,OAAA,KAAa,UAAA,OAAA,SAAA,OAAQ;AACnC,UAAM,SAAQ,KAAA,UAAA,OAAA,SAAA,OAAQ,MAAR,OAAA,KAAa,UAAA,OAAA,SAAA,OAAQ;AAEnC,QAAI,gBAAgB,KAAK;AAErB,YAAM,aAAY,KAAA,SAAA,OAAA,SAAA,MAAO,UAAP,OAAA,KAAiB,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC;AACnE,YAAM,aAAY,KAAA,SAAA,OAAA,SAAA,MAAO,UAAP,OAAA,KAAiB,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC;AACnE,iBAAW;QACP;QACA;QACA;MACJ,EAAE,IAAI,CAAA,OAAM,gBAAgB,EAAE,CAAC,EAAE,KAAK,EAAE;IAC5C,WAAW,kBAAkB,IAAI,WAAW,GAAG;AAC3C,iBAAW,OAAO;QACd,SAAS,CAAC,GAAG,GAAG,GAAG,CAAC;QACpB,SAAS,CAAC,GAAG,GAAG,GAAG,CAAC;QACpB;MACJ,CAAC;AACD,oBAAc;IAClB,WAAW,gBAAgB,oBAAoB;AAC3C,iBAAW;QACP,SAAS,CAAC;QACV,SAAS,CAAC;QACV;MACJ,EAAE,KAAK,GAAG;AACV,oBAAc;IAClB,WACI,gBAAgB,eAChB,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GACrE;AAIE,YAAM,WAAW,oBAAI,IAAY;QAC7B,GAAI,QAAQ,OAAO,KAAK,KAAK,IAAI,CAAC;QAClC,GAAI,QAAQ,OAAO,KAAK,KAAK,IAAI,CAAC;MACtC,CAAC;AACD,YAAM,cAAgC,CAAC;AACvC,iBAAW,WAAW,UAAU;AAC5B,cAAM,WAAW,SAAA,OAAA,SAAA,MAAQ,OAAA;AACzB,cAAM,WAAW,SAAA,OAAA,SAAA,MAAQ,OAAA;AACzB,YAAI,YAAY,YAAY,YAAY,QAAQ;AAC5C,sBAAY,OAAO,IAAI,eAAe,EAAE,YAAA,OAAA,WAAY,IAAI,EAAE,YAAA,OAAA,WAAY,IAAI,aAAa;QAC3F,WAAW,YAAY,eAAe,YAAY,WAAW,YAAY,UAAU;AAC/E,gBAAM,WAAW,YAAY,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC;AACrD,gBAAM,SAAS,eAAe,YAAY,UAAU,YAAY,UAAU,aAAa;AACtF,sBAAoB,OAAO,IAAI;QACpC;MACJ;AAQA,UAAI,qBAAqB,QAAQ,GAAG;AAChC,cAAM,SAAU,MAA2C;AAC3D,cAAM,SAAU,MAA2C;AAC3D,YAAI,MAAM,QAAQ,MAAM,KAAK,MAAM,QAAQ,MAAM,GAAG;AAChD,gBAAM,SAAS;YACX;YAAQ;YACR,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACvB,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YACvB;YACA,CAAC,CAAC,SAAS;UACf;AACA,sBAAY,YAAY,CAAC,OAAO,UAAU,CAAC,GAAG,OAAO,UAAU,CAAC,CAAC;AACjE,cAAI,OAAO,cAAc,OAAW,aAAY,SAAS,OAAO;QACpE;MACJ;AACA,iBAAW,sBAAsB,aAAa,EAAE,WAAW,MAAM,CAAC;AAClE,oBAAc;IAClB,WAAW,gBAAgB,aAAa;AACpC,YAAM,IAAI;QACN,SAAS,CAAC,GAAG,CAAC;QACd,SAAS,CAAC,GAAG,CAAC;QACd;MACJ;AACA,iBAAW,eAAe,EAAE,KAAK,GAAG,IAAI;AACxC,oBAAc;IAClB,WAAW,gBAAgB,UAAU;AACjC,YAAM,IAAI;QACN,EAAE,SAAS;QACX,EAAE,SAAS;QACX;MACJ;AACA,iBAAW,YAAY,IAAI;AAC3B,oBAAc;IAClB,WAAW,gBAAgB,SAAS;AAChC,YAAM,IAAI;QACN,SAAS,CAAC,GAAG,CAAC;QACd,SAAS,CAAC,GAAG,CAAC;QACd;MACJ;AACA,iBAAW,WAAW,EAAE,KAAK,GAAG,IAAI;AACpC,oBAAc;IAClB,OAAO;AAEH,YAAMM,OAAM;QACR,EAAE,SAAS;QACX,EAAE,SAAS;QACX;MACJ;AACA,iBAAWA;IACf;AAEA,QAAI,qBAAqB,IAAI,WAAW,KAAK,OAAO,aAAa,UAAU;AACvE,iBAAY,WAAW,MAAO;IAClC;AAEA,WAAO,EAAE,GAAG,aAAa,GAAG,aAAa,OAAO,KAAK,KAAK,SAAS;EACvE;AAQO,WAAS,oBACZ,SACA,UACsB;AACtB,UAAM,SAAiC,CAAC;AAExC,eAAW,CAAC,UAAU,QAAQ,KAAK,OAAO,QAAQ,OAAO,GAAG;AACxD,YAAM,WAAW,kBAAkB,UAAU,UAAU,QAAQ;AAC/D,UAAI,UAAU;AACV,eAAO,SAAS,CAAC,IAAI,SAAS;MAClC;IACJ;AAEA,WAAO;EACX;AC5kCO,WAAS,gBAAmB,OAAa;AAC5C,QAAI,UAAU,QAAQ,OAAO,UAAU,SAAU,QAAO;AACxD,QAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,eAAe;AAC1D,UAAM,MAAgC,CAAC;AACvC,eAAW,KAAK,OAAO,KAAK,KAAe,EAAG,KAAI,CAAC,IAAI,gBAAiB,MAAmC,CAAC,CAAC;AAC7G,WAAO;EACX;AAeO,WAAS,4BACZ,MACAC,QACmB;AACnB,UAAM,WAAW,oBAAI,IAAoB;AAEzC,UAAM,aAAa,CAAC,MAAoB;AAtD5C,UAAA;AAuDQ,UAAI,OAAO,EAAE,OAAO,UAAU;AAC1B,cAAM,QAAQA,OAAM;AACpB,iBAAS,IAAI,EAAE,IAAI,KAAK;AACxB,UAAE,KAAK;MACX;AACA,OAAA,KAAA,EAAE,aAAF,OAAA,SAAA,GAAY,QAAQ,UAAA;IACxB;AACA,eAAW,IAAI;AAEf,UAAM,aAAa,CAAC,MAAsB,EAAE,QAAQ,oBAAoB,CAAC,GAAG,UAAU;AAClF,YAAM,QAAQ,SAAS,IAAI,KAAK;AAChC,aAAO,QAAQ,UAAU,QAAQ,MAAM;IAC3C,CAAC;AAED,UAAM,cAAc,CAAC,MAAoB;AArE7C,UAAA;AAsEQ,UAAI,OAAO,EAAE,SAAS,YAAY,EAAE,KAAK,WAAW,GAAG,GAAG;AACtD,cAAM,QAAQ,SAAS,IAAI,EAAE,KAAK,MAAM,CAAC,CAAC;AAC1C,YAAI,MAAO,GAAE,OAAO,MAAM;MAC9B;AACA,iBAAW,KAAK,OAAO,KAAK,CAAC,GAAG;AAC5B,YAAI,MAAM,cAAc,MAAM,aAAa,MAAM,UAAU,MAAM,aAAa,MAAM,UAAU,MAAM,KAAM;AAC1G,cAAM,IAAK,EAA+B,CAAC;AAC3C,YAAI,OAAO,MAAM,YAAY,EAAE,QAAQ,OAAO,MAAM,IAAI;AACnD,YAA+B,CAAC,IAAI,WAAW,CAAC;QACrD;MACJ;AACA,OAAA,KAAA,EAAE,aAAF,OAAA,SAAA,GAAY,QAAQ,WAAA;IACxB;AACA,gBAAY,IAAI;AAEhB,WAAO;EACX;AAGA,WAAS,YAAY,GAAoB;AACrC,UAAM,IAAI,OAAO,MAAM,WAAW,IAAI,OAAO,MAAM,WAAW,WAAW,CAAC,IAAI;AAC9E,WAAO,OAAO,SAAS,CAAC,IAAI,IAAI;EACpC;AAoBO,WAAS,kBAAkB,OAAuB;AAhHzD,QAAA;AAiHI,UAAM,IAAI,YAAa,MAA0B,CAAC;AAClD,UAAM,IAAI,YAAa,MAA0B,CAAC;AAClD,WAAQ,MAA0B;AAClC,WAAQ,MAA0B;AAClC,QAAI,CAAC,KAAK,CAAC,EAAG,QAAO;AAErB,UAAM,SAAS,eAAe,IAAI,MAAM,IAAI;AAK5C,UAAM,mBACD,MAAkC,cAAc,UAChD,MAAgC,YAAY;AAEjD,QAAI,kBAAkB;AAClB,YAAM,QAAgB,EAAE,MAAM,KAAK,WAAW,QAAQ,WAAU,KAAA,MAAM,aAAN,OAAA,KAAkB,CAAC,EAAE;AACrF,YAAM,WAAW,CAAC,KAAK;IAC3B,OAAO;AACF,YAAiC,YAAY;IAClD;AACA,WAAO;EACX;AChGO,WAAS,gCAAgC,MAAsB;AAvCtE,QAAA;AAwCI,UAAM,QAAQ,WAAW,IAAI;AAC7B,UAAM,cAAc,0BAA0B,MAAM,KAAK;AACzD,QAAI,YAAY,SAAS,EAAG,QAAO;AAEnC,QAAI,YAAY;AAChB,UAAMA,SAAQ,MAAc,iBAAkB,EAAE;AAMhD,UAAM,eAAe,iBAAiB,IAAI;AAI1C,UAAM,gBAA+B,CAAC;AACtC,UAAM,SAASC,oBAAmB,MAAM,OAAO,aAAaD,QAAO,eAAe,YAAY;AAC9F,QAAI,cAAc,WAAW,EAAG,QAAO;AAMvC,UAAM,WAAmB,EAAE,MAAM,QAAQ,UAAU,cAAc;AACjE,UAAM,cAAc,CAAC,IAAI,KAAA,OAAO,aAAP,OAAA,KAAmB,CAAC,GAAI,QAAQ;AACzD,WAAOR,eAAAC,gBAAA,CAAA,GAAK,MAAA,GAAL,EAAa,UAAU,YAAY,CAAA;EAC9C;AAOA,WAAS,iBAAiB,MAAgC;AACtD,UAAM,KAAK,aAAc,KAA+B,OAAO;AAC/D,QAAI,GAAI,QAAO,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;AAC5B,UAAM,IAAI,YAAa,KAA6B,KAAK;AACzD,UAAM,IAAI,YAAa,KAA8B,MAAM;AAC3D,QAAI,MAAM,UAAa,MAAM,OAAW,QAAO,CAAC,GAAG,CAAC;AAIpD,WAAO,CAAC,GAAG,CAAC;EAChB;AAEA,WAAS,YAAY,GAAgC;AACjD,QAAI,OAAO,MAAM,SAAU,QAAO;AAClC,QAAI,OAAO,MAAM,UAAU;AAKvB,YAAM,IAAI,WAAW,CAAC;AACtB,aAAO,OAAO,SAAS,CAAC,IAAI,IAAI;IACpC;AACA,WAAO;EACX;AAQA,WAAS,WAAW,MAAmC;AACnD,UAAM,MAAM,oBAAI,IAAoB;AACpC,UAAM,QAAQ,CAAC,MAAoB;AA1GvC,UAAA;AA2GQ,UAAI,OAAO,EAAE,OAAO,SAAU,KAAI,IAAI,EAAE,IAAI,CAAC;AAC7C,OAAA,KAAA,EAAE,aAAF,OAAA,SAAA,GAAY,QAAQ,KAAA;IACxB;AACA,UAAM,IAAI;AACV,WAAO;EACX;AAMA,WAAS,0BAA0B,MAAc,OAAyC;AACtF,UAAM,QAAQ,oBAAI,QAAyB;AAC3C,UAAM,SAAS,oBAAI,IAAY;AAE/B,UAAM,UAAU,CAAC,GAAW,aAAmC;AAC3D,YAAM,SAAS,MAAM,IAAI,CAAC;AAC1B,UAAI,WAAW,OAAW,QAAO;AACjC,UAAI,SAAS,IAAI,CAAC,EAAG,QAAO;AAC5B,eAAS,IAAI,CAAC;AAEd,UAAI,IAAI;AACR,UAAI,EAAE,WAAW,OAAO,EAAE,YAAY,YAAY,CAAC,MAAM,QAAQ,EAAE,OAAO,GAAG;AACzE,mBAAW,KAAK,EAAE,SAAS;AAAE,cAAI;AAAM;QAAO;MAClD;AACA,UAAI,CAAC,KAAK,EAAE,UAAU;AAClB,mBAAW,MAAM,EAAE,UAAU;AACzB,cAAI,QAAQ,IAAI,QAAQ,GAAG;AAAE,gBAAI;AAAM;UAAO;QAClD;MACJ;AACA,UAAI,CAAC,KAAK,EAAE,SAAS,SAAS,OAAO,EAAE,SAAS,UAAU;AACtD,cAAM,WAAW,UAAU,EAAE,IAAI;AACjC,cAAM,SAAS,WAAW,MAAM,IAAI,QAAQ,IAAI;AAChD,YAAI,OAAQ,KAAI,QAAQ,QAAQ,QAAQ;MAC5C;AAEA,eAAS,OAAO,CAAC;AACjB,YAAM,IAAI,GAAG,CAAC;AACd,aAAO;IACX;AAEA,eAAW,CAAC,IAAI,IAAI,KAAK,OAAO;AAC5B,UAAI,QAAQ,MAAM,oBAAI,IAAI,CAAC,EAAG,QAAO,IAAI,EAAE;IAC/C;AACA,WAAO;EACX;AAGA,WAAS,UAAU,MAAmC;AAClD,QAAI,OAAO,SAAS,SAAU,QAAO;AACrC,WAAO,KAAK,WAAW,GAAG,IAAI,KAAK,MAAM,CAAC,IAAI;EAClD;AAKA,WAAS,kBACL,SACA,QACA,OACA,aACAO,QACA,eACA,cACM;AA3KV,QAAA,IAAA,IAAA,IAAA;AA4KI,UAAME,SAAQ,gBAAgB,MAAM;AACpC,gCAA4BA,QAAOF,MAAK;AAQxC,UAAM,gBAAgBE,OAAM,SAAS,WAAW,aAAcA,OAAgC,OAAO,IAAI;AACzG,UAAM,QAAO,MAAA,KAAA,YAAa,QAAgC,KAAK,MAAlD,OAAA,KAAuD,iBAAA,OAAA,SAAA,cAAgB,CAAA,MAAvE,OAAA,KAA6E,aAAa,CAAC;AACxG,UAAM,QAAO,MAAA,KAAA,YAAa,QAAiC,MAAM,MAApD,OAAA,KAAyD,iBAAA,OAAA,SAAA,cAAgB,CAAA,MAAzE,OAAA,KAA+E,aAAa,CAAC;AAO1G,UAAM,iBAAiBA,OAAM,SAAS,WAChC,yBAAyBA,QAAOF,QAAO,eAAe,MAAM,IAAI,IAChEE;AAIN,UAAM,oBAAoBD,oBAAmB,gBAAgB,OAAO,aAAaD,QAAO,eAAe,YAAY;AAMnH,UAAM,UAAkBR,eAAAC,gBAAA,CAAA,GAAK,OAAA,GAAL,EAAc,MAAM,KAAK,UAAU,CAAC,iBAAiB,EAAE,CAAA;AAC/E,WAAQ,QAA8B;AAMtC,WAAQ,QAAgC;AACxC,WAAQ,QAAiC;AACzC,WAAO,kBAAkB,OAAO;EACpC;AAwBA,WAAS,yBACL,YACAO,QACA,eACA,MACA,MACM;AACN,UAAM,UAAU,aAAc,WAAqC,OAAO;AAC1E,UAAM,IAAYR,eAAAC,gBAAA,CAAA,GAAK,UAAA,GAAL,EAAiB,MAAM,IAAI,CAAA;AAE7C,WAAQ,EAA4B;AACpC,WAAQ,EAAwC;AAChD,WAAQ,EAA0B;AAClC,WAAQ,EAA2B;AAEnC,QAAI,CAAC,QAAS,QAAO;AAErB,UAAM,CAAC,KAAK,KAAK,KAAK,GAAG,IAAI;AAI7B,UAAM,QAAQ,MAAM,KAAK,MAAM,IAAI,KAAK,IAAI,OAAO,KAAK,OAAO,GAAG,IAAI;AACtE,UAAM,QAAQ,OAAO,MAAM,SAAS;AACpC,UAAM,QAAQ,OAAO,MAAM,SAAS;AAEpC,UAAM,QAAuB,CAAC;AAC9B,QAAI,SAAS,KAAK,SAAS,EAAG,OAAM,KAAK,eAAe,OAAO,MAAM,OAAO,GAAG;AAC/E,QAAI,UAAU,EAAG,OAAM,KAAK,WAAW,QAAQ,GAAG;AAClD,QAAI,QAAQ,KAAK,QAAQ,EAAG,OAAM,KAAK,eAAgB,CAAC,MAAO,MAAO,CAAC,MAAO,GAAG;AACjF,QAAI,MAAM,OAAS,GAA6B,YAAY,MAAM,KAAK,EAAE;AAEzE,UAAM,SAASO,OAAM;AACrB,kBAAc,KAAK;MACf,MAAM;MACN,IAAI;MACJ,UAAU,CAAC,EAAE,MAAM,QAAQ,GAAG,KAAK,GAAG,KAAK,OAAO,KAAK,QAAQ,IAAI,CAAC;IACxE,CAAW;AACV,MAA4B,WAAW,UAAU,SAAS;AAC3D,WAAO;EACX;AAGA,WAAS,aAAa,GAA0D;AAC5E,QAAI,OAAO,MAAM,SAAU,QAAO;AAClC,UAAM,QAAQ,EAAE,KAAK,EAAE,MAAM,QAAQ,EAAE,IAAI,MAAM;AACjD,QAAI,MAAM,SAAS,KAAK,MAAM,KAAK,CAAA,MAAK,CAAC,OAAO,SAAS,CAAC,CAAC,EAAG,QAAO;AACrE,WAAO,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC;EAClD;AAGA,WAASC,oBACL,MACA,OACA,aACAD,QACA,eACA,cACM;AACN,QAAI,KAAK,SAAS,SAAS,OAAO,KAAK,SAAS,UAAU;AACtD,YAAM,WAAW,UAAU,KAAK,IAAI;AACpC,UAAI,YAAY,YAAY,IAAI,QAAQ,GAAG;AACvC,cAAM,SAAS,MAAM,IAAI,QAAQ;AACjC,YAAI,OAAQ,QAAO,kBAAkB,MAAM,QAAQ,OAAO,aAAaA,QAAO,eAAe,YAAY;MAC7G;IACJ;AAEA,QAAI,CAAC,KAAK,SAAU,QAAO;AAC3B,QAAI,UAAU;AACd,UAAM,cAAc,KAAK,SAAS,IAAI,CAAA,OAAM;AACxC,YAAM,IAAIC,oBAAmB,IAAI,OAAO,aAAaD,QAAO,eAAe,YAAY;AACvF,UAAI,MAAM,GAAI,WAAU;AACxB,aAAO;IACX,CAAC;AACD,WAAO,UAAUR,eAAAC,gBAAA,CAAA,GAAK,IAAA,GAAL,EAAW,UAAU,YAAY,CAAA,IAAI;EAC1D;AC/QO,WAAS,YAAY,MAAqB,OAAY,QAA0B;AACnF,UAAM,MAAyF,CAAC;AAChG,QAAI,SAAS,YAAyB,KAAI,YAAY;aAC7C,SAAS,SAAsB,KAAI,SAAS;aAC5C,SAAS,OAAoB,KAAI,OAAO;QAC5C,KAAI,QAAQ;AACjB,QAAI,UAAU,SAAS,YAAyB,KAAI,SAAS;AAC7D,WAAO;EACX;AAYO,WAAS,eAAkB,KAA+C;AAC7E,QAAI,QAAQ,OAAW,QAAO;MAAE,MAAM;;IAAgB;AACtD,QAAI,MAAM,QAAQ,GAAG,EAAG,QAAO,EAAE,MAAM,UAAiB,OAAO,IAAoB;AACnF,QAAI,OAAO,QAAQ,UAAU;AACzB,YAAM,MAAM;AACZ,UAAI,IAAI,WAAW;AACf,eAAO,EAAE,MAAM,YAAmB,WAAW,IAAI,WAAW,YAAY,IAAI,YAAY,MAAM,IAAI,KAAK;MAC3G;AACA,UAAI,IAAI,UAAU,OAAW,QAAO,EAAE,MAAM,UAAiB,OAAO,IAAI,MAAM;IAClF;AACA,WAAO,EAAE,MAAM,UAAiB,OAAO,IAAS;EACpD;AAGO,WAAS,iBAAiB,KAAqC,KAAqC;AAzE3G,QAAA;AA0EI,UAAM,IAAI,eAAqB,GAAG;AAClC,QAAI,EAAE,SAAS,SAAiB,QAAO;AACvC,QAAI,EAAE,SAAS,SAAiB,QAAO,EAAE;AACzC,QAAI,SAAS,KAAK,2EAA2E;AAC7F,YAAO,KAAA,EAAE,UAAU,CAAC,MAAb,OAAA,SAAA,GAAgB;EAC3B;AAGO,WAAS,aAAa,IAAqB,OAA6B;AAC3E,UAAM,MAAuB,EAAE,MAAM;AACrC,QAAI,GAAG,SAAS,OAAW,KAAI,OAAO,GAAG;AACzC,QAAI,GAAG,WAAW,OAAW,KAAI,SAAS,GAAG;AAC7C,QAAI,GAAG,eAAe,OAAW,KAAI,aAAa,GAAG;AACrD,QAAI,GAAG,cAAc,OAAW,KAAI,YAAY,GAAG;AACnD,WAAO;EACX;AC3DO,WAAS,0BAA0B,MAAc,IAAwC,KAA2B;AACvH,QAAI,CAAC,GAAI,QAAO;AAIhB,WAAO,KAAK;AAOZ,QAAI,IAAI;AACR,QAAI;MAAW;MAAG,GAAG;;MAAmB;IAAI;AAC5C,QAAI,kBAAkB,GAAA,SAAwB,eAAe,GAAG,KAAK,GAAG,GAAG;AAC3E,QAAI,kBAAkB,GAAA,QAAuB,GAAG,MAAM,GAAG;AACzD,QAAI,kBAAkB,GAAA,UAAyB,GAAG,QAAQ,GAAG;AAC7D,QAAI;MAAW;MAAG,GAAG;;MAAmB;IAAK;AAE7C,QAAI,uBAAuB,GAAG,SAAS,GAAG;AAItC,UAAI;QAAW;QAAG,GAAG;;QAAmB;MAAI;AAC5C,UAAI,kBAAkB,GAAA,aAA4B,GAAG,WAAW,GAAG;AACnE,UAAI;QAAW;QAAG,GAAG;;QAAmB;MAAK;IACjD,OAAO;AACH,UAAI,kBAAkB,GAAA,aAA4B,GAAG,WAAW,GAAG;IACvE;AACA,WAAO;EACX;AAIA,WAAS,uBAAuB,WAAoD;AAChF,QAAI,CAAC,aAAa,OAAO,cAAc,SAAU,QAAO;AACxD,UAAM,MAAM;AACZ,QAAI,IAAI,WAAY,QAAO;AAC3B,WAAO,MAAM,QAAQ,IAAI,SAAS,KAAK,IAAI,UAAU,KAAK,CAAA,OAAM,GAAG,cAAc,GAAG,SAAS;EACjG;AAQA,WAAS,eAAe,KAAqE;AACzF,QAAI,QAAQ,OAAW,QAAO;AAC9B,QAAI,MAAM,QAAQ,GAAG,EAAG,QAAO,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,GAAG;AAC1D,WAAO;EACX;AAGA,WAAS,kBACL,OAAe,MACf,KAAoC,KAC9B;AACN,QAAI,QAAQ,OAAW,QAAO;AAE9B,UAAM,IAAI,eAAoB,GAAG;AACjC,QAAI,EAAE,SAAA,UAA0B;AAC5B,aAAO,EAAE,MAAM,KAAK,WAAW,EAAE,OAAO,YAAY,MAAM,EAAE,OAAO,MAAS,EAAE,GAAG,UAAU,CAAC,KAAK,EAAE;IACvG;AACA,QAAI,EAAE,SAAA,YAA4B;AAC9B,YAAM,SAAc,EAAE,WAAW,EAAE,UAAU,IAAI,CAAA,OAAM,aAAa,IAAI,YAAY,MAAM,GAAG,OAAO,MAAS,CAAC,CAAC,EAAE;AACjH,UAAI,EAAE,WAAY,QAAO,aAAa;AACtC,UAAI,EAAE,SAAS,OAAW,QAAO,OAAO,EAAE;AAC1C,aAAO;QACH,MAAM;QACN,SAAS,EAAE,WAAW,OAAO;QAC7B,UAAU,CAAC,KAAK;MACpB;IACJ;AACA,WAAO;EACX;AAWA,WAAS,WAAW,OAAe,KAAqC,QAAyB;AAC7F,QAAI,QAAQ,OAAW,QAAO;AAC9B,UAAM,IAAI,eAAqB,GAAG;AAClC,UAAM,OAAO,CAAC,UAAsB,SAAS,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI;AAEtE,QAAI,EAAE,SAAA,SAA0B,QAAO;AACvC,QAAI,EAAE,SAAA,UAA0B;AAC5B,UAAI,EAAE,MAAM,CAAC,MAAM,KAAK,EAAE,MAAM,CAAC,MAAM,EAAG,QAAO;AACjD,aAAO,EAAE,MAAM,KAAK,WAAW,EAAE,OAAO,EAAE,WAAW,KAAK,EAAE,KAAK,EAAE,EAAE,GAAG,UAAU,CAAC,KAAK,EAAE;IAC9F;AACA,QAAI,EAAE,SAAA,YAA4B;AAC9B,YAAM,SAAc,EAAE,WAAW,EAAE,UAAU,IAAI,CAAA,OAAM,aAAa,IAAI,EAAE,WAAW,KAAK,GAAG,KAAa,EAAE,CAAC,CAAC,EAAE;AAChH,UAAI,EAAE,SAAS,OAAW,QAAO,OAAO,EAAE;AAC1C,aAAO;QACH,MAAM;QACN,SAAS,EAAE,WAAW,OAAO;QAC7B,UAAU,CAAC,KAAK;MACpB;IACJ;AACA,WAAO;EACX;ACrFO,WAAS,0BAA0B,MAAc,KAAmB,WAA0C;AAnDrH,QAAA,IAAA,IAAA;AAoDI,QAAI,KAAK,SAAS,WAAS,MAAA,KAAA,KAAK,YAAL,OAAA,SAAA,GAAc,UAAd,OAAA,SAAA,GAAqB,UAAS,WAAW;AAChE,YAAM,SAAS,KAAK,QAAQ,MAAM;AAClC,UAAI,OAAO,WAAW,YAAY,UAAU,CAAC,IAAI,mBAAmB,IAAI,MAAM,GAAG;AAC7E,YAAI,mBAAmB,IAAI,QAAQ,UAAU,MAAM,CAAC;MACxD;IACJ;AACA,KAAA,KAAA,KAAK,aAAL,OAAA,SAAA,GAAe,QAAQ,CAAA,MAAK,0BAA0B,GAAG,KAAK,SAAS,CAAA;EAC3E;AAYO,WAAS,mBACZ,MACA,gBACA,YACA,SACA,KACM;AAON,UAAM,YAAY,kBAAkB,MAAM,cAAc;AAKxD,QAAI,OAAO,KAAK,OAAO,SAAU,QAAO,KAAK;AAI7C,UAAM,EAAE,OAAO,SAAS,OAAO,QAAQ,IAAI,0BAA0B,cAAc;AAKnF,QAAI,YAAoB;AACxB,gBAAY,0BAA0B,WAAW,SAAS,GAAG;AAC7D,UAAM,eAAuB,EAAE,MAAM,KAAK,IAAI,SAAS,UAAU,CAAC,SAAS,EAAE;AAK7E,QAAI,eAAuB,EAAE,MAAM,KAAK,IAAI,YAAY,UAAU,CAAC,YAAY,EAAE;AACjF,QAAI,UAAU,cAAc,OAAW,cAAa,YAAY,UAAU;AAC1E,QAAI,UAAU,YAAY,OAAW,cAAa,UAAU,UAAU;AACtE,QAAI,SAAS;AACT,aAAO,aAAa;AACpB,qBAAe,0BAA0B,cAAc,SAAS,GAAG;AACnE,mBAAa,KAAK;IACtB;AACA,WAAO;EACX;AAkBA,WAAS,kBAAkB,MAAc,gBAA+D;AApIxG,QAAA,IAAA,IAAA;AAqII,UAAM,MAAiB,CAAC;AAMxB,QAAI,iBAAiB;AAIrB,UAAM,UAAU,KAAA,KAAK,YAAL,OAAA,SAAA,GAAoD;AACpE,QAAI,UAAU,OAAO,WAAW,YAAY,MAAM,QAAQ,OAAO,SAAS,GAAG;AACzE,YAAM,MAA8B,OAAO;AAC3C,YAAM,eAAe,IAAI,KAAK,CAAA,OAAM,GAAG,SAAU,GAAG,MAAc,SAAS;AAC3E,UAAI,cAAc;AACd,cAAM,iBAAiB,mBAAmB,MAA4B;AACtE,cAAM,WAAW,IAAI,IAAI,CAAA,OAAM;AAC3B,gBAAM,IAAK,GAAG,SAAS,CAAC;AACxB,gBAAM,WAAgB,CAAC;AACvB,cAAI,EAAE,cAAc,OAAW,UAAS,YAAY,EAAE;AACtD,cAAI,kBAAkB,EAAE,WAAW,OAAW,UAAS,SAAS,EAAE;AAClE,gBAAM,UAAe,EAAE,OAAO,SAAS;AACvC,cAAI,GAAG,SAAS,OAAW,SAAQ,OAAO,GAAG;AAC7C,cAAI,GAAG,WAAW,OAAW,SAAQ,SAAS,GAAG;AACjD,cAAK,GAAW,eAAe,OAAW,SAAQ,aAAc,GAAW;AAC3E,cAAK,GAAW,cAAc,OAAW,SAAQ,YAAa,GAAW;AACzE,iBAAO;QACX,CAAC;AACD,cAAM,cAAmB,EAAE,WAAW,SAAS;AAC/C,YAAK,OAAe,WAAY,aAAY,aAAa;AAIzD,cAAM,UAAW,OAAe;AAChC,YAAI,YAAY,OAAW,aAAY,OAAO;AAC9C,YAAI,UAAU,EAAE,WAAW,YAAY;AAEvC,cAAM,sBAAsB,IAAI,KAAK,CAAA,OAAM;AACvC,gBAAM,IAAK,GAAG,SAAS,CAAC;AACxB,iBAAO,EAAE,WAAW,UAAa,EAAE,UAAU;QACjD,CAAC;AACD,cAAM,WAAW,IAAI,IAAI,CAAA,OAAM;AAC3B,gBAAM,IAAK,GAAG,SAAS,CAAC;AACxB,gBAAM,WAAgB,CAAC;AACvB,cAAI,EAAE,WAAW,OAAW,UAAS,SAAS,EAAE;AAChD,cAAI,EAAE,UAAU,OAAW,UAAS,QAAQ,EAAE;AAI9C,cAAI,EAAE,WAAW,WAAc,CAAC,kBAAkB,qBAAsB,UAAS,SAAS,EAAE;AAE5F,gBAAM,UAAe,EAAE,OAAO,SAAS;AACvC,cAAI,GAAG,SAAS,OAAW,SAAQ,OAAO,GAAG;AAC7C,cAAI,GAAG,WAAW,OAAW,SAAQ,SAAS,GAAG;AACjD,iBAAO;QACX,CAAC;AACD,cAAM,gBAAgB,SAAS,MAAM,CAAA,OAAM,OAAO,KAAK,GAAG,KAAe,EAAE,WAAW,CAAC;AACvF,YAAI,eAAe;AACf,iBAAQ,KAAK,QAAgB;AAC7B,cAAI,KAAK,WAAW,OAAO,KAAK,KAAK,OAAO,EAAE,WAAW,EAAG,QAAO,KAAK;QAC5E,OAAO;AAGH,gBAAM,cAAmB,EAAE,WAAW,SAAS;AAC/C,cAAI,YAAY,OAAW,aAAY,OAAO;AAC7C,eAAK,QAAgB,YAAY;QACtC;AACA,yBAAiB;MACrB;IACJ;AAKA,UAAM,8BAA6B,kBAAA,OAAA,SAAA,eAAgB,eAAc;AACjE,UAAM,yBAAyB,kBAAkB;AAOjD,UAAM,8BAA8B,kBAAkB,qBAAoB,KAAA,KAAK,YAAL,OAAA,SAAA,GAAoD,cAAoB,MAAS,KACpJ,kBAAkB,qBAAoB,KAAA,IAAI,YAAJ,OAAA,SAAA,GAAmD,cAAoB,MAAS;AAC7H,QAAI,OAAO,KAAK,cAAc,UAAU;AACpC,YAAM,QAAQ,qBAAqB,KAAK,SAAS;AACjD,UAAI,wBAAwB;AAIxB,YAAI,MAAM,cAAc,QAAW;AAC/B,cAAI,MAAM,KAAM,MAAK,YAAY,MAAM;cAClC,QAAO,KAAK;QACrB,WAAW,oBAAoB,KAAK,SAAS,GAAG;AAG5C,iBAAO,KAAK;QAChB,WAAW,+BAA+B,mBAAmB,KAAK,SAAS,GAAG;AAI1E,iBAAO,KAAK;QAChB;MACJ,WAAW,MAAM,WAAW;AACxB,YAAI,YAAY,MAAM;AACtB,YAAI,MAAM,KAAM,MAAK,YAAY,MAAM;YAClC,QAAO,KAAK;MACrB;IACJ;AAEA,WAAO;EACX;AAIA,WAAS,mBAAmB,GAAoB;AAC5C,UAAM,KAAK;AACX,QAAI,QAAQ;AACZ,QAAI,WAAW;AACf,QAAI;AACJ,WAAQ,IAAI,GAAG,KAAK,CAAC,GAAI;AACrB;AACA,UAAI,EAAE,CAAC,MAAM,SAAU,YAAW;IACtC;AACA,WAAO,UAAU,KAAK;EAC1B;AAKA,WAAS,oBAAoB,GAAoB;AAC7C,UAAM,KAAK;AACX,UAAM,MAA6C,CAAC;AACpD,QAAI;AACJ,WAAQ,IAAI,GAAG,KAAK,CAAC,EAAI,KAAI,KAAK,EAAE,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,CAAC;AAC5D,QAAI,IAAI,WAAW,EAAG,QAAO;AAC7B,QAAI,IAAI,CAAC,EAAE,SAAS,YAAa,QAAO;AACxC,QAAI,IAAI,CAAC,EAAE,SAAS,SAAU,QAAO;AACrC,UAAM,OAAO,oBAAoB,KAAK,IAAI,CAAC,EAAE,IAAI;AACjD,QAAI,CAAC,KAAM,QAAO;AAClB,UAAM,OAAO,KAAK,CAAC,EAAE,MAAM,QAAQ,EAAE,OAAO,OAAO,EAAE,IAAI,MAAM;AAC/D,WAAO,KAAK,UAAU,KAAK,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM;EAC9F;AAeA,WAAS,qBAAqB,GAAkD;AAC5E,UAAM,MAA6C,CAAC;AACpD,UAAM,KAAK;AACX,QAAI;AACJ,WAAQ,IAAI,GAAG,KAAK,CAAC,EAAI,KAAI,KAAK,EAAE,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE,CAAC;AAE5D,QAAI,CAAC,IAAI,OAAQ,QAAO,EAAE,MAAM,KAAK,OAAU;AAI/C,QAAI,IAAI,MAAM,CAAA,MAAK,EAAE,SAAS,WAAW,GAAG;AACxC,aAAO,EAAE,WAAW,IAAI,IAAI,CAAA,MAAK,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE;IACtD;AAEA,UAAM,UAAU,IAAI,CAAC;AACrB,UAAM,WAAW,IAAI,IAAI,SAAS,CAAC;AAMnC,QAAI,SAAS,SAAS,eAAe,QAAQ,SAAS,aAAa;AAC/D,YAAM,cAAc,mBAAmB,SAAS,IAAI;AACpD,YAAM,aAAa,mBAAmB,QAAQ,IAAI;AAClD,YAAM,KAAK,CAAC,YAAY,CAAC;AACzB,YAAM,KAAK,CAAC,YAAY,CAAC;AACzB,YAAM,SAAS,WAAW,CAAC,IAAI;AAC/B,YAAM,SAAS,WAAW,CAAC,IAAI;AAG/B,UAAI,WAAW,KAAK,WAAW,EAAG,QAAO,EAAE,MAAM,EAAE;AAInD,YAAM,oBAAoB,eAAe,KAAK,MAAM,KAAK,MAAM,IAAI,MAAM,CAAC,EAAE,IAAI,CAAA,MAAK,EAAE,IAAI,EAAE,KAAK,EAAE;AACpG,aAAO,EAAE,WAAW,eAAe,SAAS,MAAM,SAAS,KAAK,MAAM,kBAAkB;IAC5F;AAIA,QAAI,SAAS,SAAS,YAAa,QAAO,EAAE,MAAM,EAAE;AAGpD,UAAM,SAAwB,CAAC;AAC/B,QAAI,IAAI;AACR,WAAO,IAAI,IAAI,UAAU,IAAI,CAAC,EAAE,SAAS,aAAa;AAClD,aAAO,KAAK,IAAI,CAAC,EAAE,IAAI;AACvB;IACJ;AACA,QAAI,CAAC,OAAO,OAAQ,QAAO,EAAE,MAAM,EAAE;AAErC,UAAM,OAAO,IAAI,MAAM,CAAC,EAAE,IAAI,CAAA,MAAK,EAAE,IAAI,EAAE,KAAK,EAAE;AAClD,WAAO;MACH,WAAW,OAAO,KAAK,EAAE;MACzB,MAAM,QAAQ;IAClB;EACJ;AAEA,WAAS,mBAAmB,aAAuC;AAC/D,UAAM,IAAI,uBAAuB,KAAK,WAAW;AACjD,QAAI,CAAC,EAAG,QAAO,CAAC,GAAG,CAAC;AACpB,UAAM,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,EAAE,OAAO,OAAO,EAAE,IAAI,MAAM;AAC5D,WAAO,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;EACtC;AAOA,WAAS,0BAA0B,IAGjC;AACE,QAAI,CAAC,GAAI,QAAO,CAAC;AACjB,UAAM,gBAAgB,mBAAmB,GAAG,SAAS;AACrD,UAAM,sBAAsB,GAAG,WAAW,UAAa,GAAG,UAAU;AAEpE,UAAM,QAAgC,CAAC;AACvC,UAAM,QAAgC,CAAC;AAEvC,QAAI,GAAG,cAAc,OAAW,OAAM,YAAY,GAAG;AAGrD,QAAI,iBAAiB,GAAG,WAAW,OAAW,OAAM,SAAS,GAAG;AAEhE,QAAI,GAAG,WAAW,OAAW,OAAM,SAAS,GAAG;AAC/C,QAAI,GAAG,UAAU,OAAW,OAAM,QAAQ,GAAG;AAC7C,QAAI,GAAG,SAAS,OAAW,OAAM,OAAO,GAAG;AAI3C,QAAI,GAAG,WAAW,WAAc,CAAC,iBAAiB,qBAAsB,OAAM,SAAS,GAAG;AAE1F,WAAO;MACH,OAAO,OAAO,KAAK,KAAK,EAAE,SAAS,QAAQ;MAC3C,OAAO,OAAO,KAAK,KAAK,EAAE,SAAS,QAAQ;IAC/C;EACJ;AAUA,WAAS,mBAAmB,eAAwD;AAChF,QAAI,CAAC,iBAAiB,OAAO,kBAAkB,SAAU,QAAO;AAChE,UAAM,MAAM;AACZ,QAAI,IAAI,WAAY,QAAO;AAC3B,QAAI,MAAM,QAAQ,IAAI,SAAS,GAAG;AAC9B,aAAO,IAAI,UAAU,KAAK,CAAA,OAAM,GAAG,cAAc,GAAG,SAAS;IACjE;AACA,WAAO;EACX;ACzYO,WAAS,MAAM,KAAmB,QAAwB;AAC7D,WAAO,SAAS,SAAS,MAAO,IAAI;EACxC;AAEO,WAASU,WAAU,MAA+B;AACrD,WAAO,OAAO,SAAS,WAAW,KAAK,QAAQ,MAAM,EAAE,IAAI;EAC/D;AAUO,WAAS,UAAU,MAAc,KAAgC;AA7BxE,QAAA;AA8BI,QAAI,OAAO,KAAK,OAAO,SAAU,KAAI,IAAI,KAAK,IAAI,IAAI;AACtD,KAAA,KAAA,KAAK,aAAL,OAAA,SAAA,GAAe,QAAQ,CAAA,UAAS,UAAU,OAAO,GAAG,CAAA;EACxD;AAGO,WAAS,WAAW,MAAc,MAA2B;AAChE,QAAI,CAAC,KAAK,OAAQ;AAClB,UAAM,WAAW,KAAK,aAAa,KAAK,WAAW,CAAC;AACpD,aAAS,QAAQ,EAAE,MAAM,QAAQ,UAAU,KAAK,CAAC;EACrD;AAIO,MAAM,QAAQ;AAQd,WAAS,qBAAqB,MAAc,KAAwC;AACvF,WAAO,4BAA4B,MAAM,MAAM,MAAM,KAAK,SAAS,CAAC;EACxE;ACrBO,WAAS,wBAAwB,MAAc,IAAsC,KAA2B;AACnH,WAAO,cAAc,MAAM,IAAI,KAAK,MAAM;EAC9C;AAEO,WAAS,0BAA0B,MAAc,IAAwC,KAA2B;AACvH,WAAO,cAAc,MAAM,IAAI,KAAK,QAAQ;EAChD;AAOA,WAAS,cAAc,MAAc,IAAsC,KAAmB,MAAiC;AAC3H,QAAI,CAAC,GAAI,QAAO;AAEhB,UAAM,KAAK,MAAM,KAAK,MAAM;AAC5B,UAAM,MAAM,sBAAsB,IAAI,IAAI,GAAG;AAC7C,QAAI,KAAK,KAAK,GAAG;AACjB,SAAK,IAAI,IAAI,UAAU,KAAK;AAC5B,WAAO;EACX;AAEA,WAAS,sBAAsB,IAA0B,IAAY,KAA2B;AAC5F,UAAM,MAAc;MAChB,MAAM,GAAG,SAAS,eAAe,SAAS,mBAAmB;MAC7D;IACJ;AAGA,QAAI,GAAG,SAAS,eAAe,QAAQ;AACnC,UAAI,GAAG,IAAI;AAAE,YAAI,KAAK,OAAO,GAAG,GAAG,CAAC,CAAC;AAAG,YAAI,KAAK,OAAO,GAAG,GAAG,CAAC,CAAC;MAAG;AACnE,UAAI,GAAG,IAAI;AAAE,YAAI,KAAK,OAAO,GAAG,GAAG,CAAC,CAAC;AAAG,YAAI,KAAK,OAAO,GAAG,GAAG,CAAC,CAAC;MAAG;IACvE,OAAO;AACH,UAAI,GAAG,GAAI;AAAE,YAAI,KAAK,OAAO,GAAG,EAAE,CAAC,CAAC;AAAI,YAAI,KAAK,OAAO,GAAG,EAAE,CAAC,CAAC;MAAG;AAClE,UAAI,GAAG,MAAM,OAAW,KAAI,IAAI,OAAO,GAAG,CAAC;AAC3C,UAAI,GAAG,IAAI;AAAE,YAAI,KAAK,OAAO,GAAG,GAAG,CAAC,CAAC;AAAG,YAAI,KAAK,OAAO,GAAG,GAAG,CAAC,CAAC;MAAG;IACvE;AACA,QAAI,GAAG,cAAmB,KAAI,gBAAgB,GAAG;AACjD,QAAI,GAAG,aAAmB,KAAI,eAAe,GAAG;AAChD,QAAI,GAAG,kBAAmB,KAAI,oBAAoB,GAAG;AAQrD,UAAM,UAAW,GAAiC;AAClD,QAAI,SAAS;AACT,YAAM,SAAsB,CAAC;AAC7B,iBAAW,WAAW,OAAO,KAAK,OAAO,GAAG;AACxC,cAAM,OAAO,8BAA8B,OAAO;AAClD,YAAI,KAAM,QAAO,IAAI,IAAI,QAAQ,OAAO;MAC5C;AACA,UAAI,OAAO,KAAK,MAAM,EAAE,OAAQ,KAAI,UAAU;IAClD;AAEA,QAAI,WAAW,kBAAkB,GAAG,OAAO,GAAG;AAC9C,WAAO;EACX;AAGA,MAAM,gCAAwD;IAC1D,YAAY;IAAM,YAAY;IAAM,YAAY;IAAM,YAAY;IAClE,YAAY;IAAM,YAAY;IAAM,YAAY;IAAM,YAAY;IAAM,WAAW;EACvF;AAQA,WAAS,kBAAkB,OAAwD,KAAkC;AA1GrH,QAAA,IAAA,IAAA,IAAA;AA2GI,QAAI,CAAC,MAAO,QAAO,CAAC;AAGpB,QAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,cAAc;AACzD,QAAI,OAAO,UAAU,YAAY,MAAM,QAAS,MAA0B,KAAK,GAAG;AAC9E,aAAQ,MAA2C,MAAM,IAAI,cAAc;IAC/E;AAGA,UAAM,YAAY;AAClB,UAAM,MAAM,UAAU;AACtB,QAAI,CAAC,MAAM,QAAQ,GAAG,KAAK,CAAC,IAAI,OAAQ,QAAO,CAAC;AAOhD,UAAM,iBAAiB,UAAU;AAIjC,QAAI,YAAY;AAChB,eAAW,MAAM,KAAK;AAClB,YAAM,KAAK,KAAA,GAAG,UAAH,OAAA,KAAY,GAAG;AAC1B,UAAI,MAAM,QAAQ,CAAC,KAAK,EAAE,SAAS,UAAW,aAAY,EAAE;IAChE;AACA,QAAI,CAAC,UAAW,QAAO,CAAC;AAKxB,UAAM,gBAAgB,KAAA,IAAI,CAAC,EAAE,UAAP,OAAA,KAAgB,IAAI,CAAC,EAAE;AAC7C,UAAM,gBAAuC,CAAC;AAC9C,aAAS,IAAI,GAAG,IAAI,WAAW,KAAK;AAChC,YAAM,KAAI,MAAA,KAAA,gBAAA,OAAA,SAAA,aAAe,CAAA,MAAf,OAAA,KAAqB,gBAAgB,KAAK,GAAG,CAAC,MAA9C,OAAA,KAAmD,EAAE,QAAQ,IAAI,KAAK,IAAI,GAAG,YAAY,CAAC,GAAG,OAAO,UAAU;AACxH,oBAAc,KAAK,EAAE,QAAQ,EAAE,QAAQ,OAAO,EAAE,MAAM,CAAC;IAC3D;AAEA,WAAO,cAAc,IAAI,CAAC,IAAI,MAAM,iBAAiB,IAAI,KAAK,GAAG,KAAK,cAAc,CAAC;EACzF;AAEA,WAAS,eAAe,GAA2B;AAC/C,WAAO;MACH,MAAM;MACN,QAAQ,aAAa,EAAE,MAAM;MAC7B,WAAW,EAAE;IACjB;EACJ;AAEA,WAAS,iBAAiB,UAA0B,KAAwB,SAAiB,MAAoB,MAA4C;AA7J7J,QAAA,IAAA,IAAA,IAAA,IAAA;AA8JI,UAAM,WAA8B,CAAC;AACrC,UAAM,YAA+B,CAAC;AAItC,QAAI,eAAe;AACnB,eAAW,MAAM,KAAK;AAClB,YAAM,KAAI,MAAA,KAAA,GAAG,SAAH,OAAA,KAAW,GAAG,MAAd,OAAA,KAAmB;AAC7B,YAAM,OAAO,KAAA,GAAG,UAAH,OAAA,KAAY,GAAG;AAC5B,YAAM,UAAS,KAAA,OAAA,OAAA,SAAA,IAAM,OAAA,MAAN,OAAA,KAAkB,gBAAgB,KAAK,IAAI,QAAQ,EAAE,GAAG,OAAO;AAC9E,UAAI,CAAC,OAAQ;AACb,YAAM,UAAS,KAAA,GAAG,WAAH,OAAA,KAAa,GAAG;AAE/B,YAAM,WAAuB,EAAE,MAAM,GAAG,OAAO,OAAO,MAAM;AAC5D,UAAI,WAAW,OAAW,UAAS,SAAS;AAC5C,eAAS,KAAK,QAAQ;AAItB,YAAM,YAAwB,EAAE,MAAM,GAAG,OAAO,OAAO,OAAO;AAC9D,UAAI,WAAW,OAAW,WAAU,SAAS;AAC7C,gBAAU,KAAK,SAAS;AACxB,UAAI,OAAO,WAAW,SAAS,OAAQ,gBAAe;IAC1D;AAEA,UAAM,OAAe;MACjB,MAAM;MACN,QAAQ,aAAa,SAAS,MAAM;MACpC,WAAW,SAAS;IACxB;AACA,UAAM,UAAsF,CAAC;AAC7F,QAAI,SAAS,QAAQ;AACjB,cAAQ,YAAY,EAAE,WAAW,SAAS;AAC1C,UAAI,SAAS,OAAW,SAAQ,UAAU,OAAO;IACrD;AACA,QAAI,gBAAgB,UAAU,QAAQ;AAClC,cAAQ,SAAS,EAAE,WAAW,UAAU;AACxC,UAAI,SAAS,OAAW,SAAQ,OAAO,OAAO;IAClD;AACA,QAAI,OAAO,KAAK,OAAO,EAAE,OAAQ,MAAK,UAAU;AAChD,WAAO;EACX;AAMA,WAAS,gBAAgB,KAAwB,SAAiB,SAA6C;AA7M/G,QAAA,IAAA;AA8MI,aAAS,IAAI,SAAS,KAAK,GAAG,KAAK;AAC/B,YAAM,OAAO,KAAA,IAAI,CAAC,EAAE,UAAP,OAAA,KAAgB,IAAI,CAAC,EAAE;AACpC,UAAI,OAAA,OAAA,SAAA,IAAM,OAAA,EAAU,QAAO,IAAI,OAAO;IAC1C;AACA,aAAS,IAAI,UAAU,GAAG,IAAI,IAAI,QAAQ,KAAK;AAC3C,YAAM,OAAO,KAAA,IAAI,CAAC,EAAE,UAAP,OAAA,KAAgB,IAAI,CAAC,EAAE;AACpC,UAAI,OAAA,OAAA,SAAA,IAAM,OAAA,EAAU,QAAO,IAAI,OAAO;IAC1C;AACA,WAAO;EACX;AAIA,WAAS,aAAa,GAAmB;AACrC,UAAM,MAAM,KAAK,MAAM,IAAI,GAAI,IAAI;AACnC,WAAO,MAAM;EACjB;ACrMO,WAAS,oBACZ,MACA,IACA,KACM;AACN,QAAI,CAAC,MAAO,CAAC,GAAG,KAAK,CAAC,GAAG,QAAU,QAAO;AAE1C,UAAM,SAAS,MAAM,KAAK,MAAM;AAChC,UAAM,YAAoB,EAAE,MAAM,QAAQ,GAAG,GAAG,EAAE;AAClD,QAAI,GAAG,QAAS,WAAU,UAAU,EAAE,GAAG,GAAG,QAAQ;AACpD,QAAI,KAAK,KAAK,EAAE,MAAM,YAAY,IAAI,QAAQ,UAAU,CAAC,SAAS,EAAE,CAAC;AACrE,SAAK,WAAW,UAAU,SAAS;AACnC,WAAO;EACX;ACNO,WAAS,oBACZ,MACA,IACA,gBACA,KACM;AACN,QAAI,CAAC,GAAI,QAAO;AAChB,QAAI,CAAC,GAAG,MAAM;AAAE,UAAI,OAAO,KAAK,gDAA2C;AAAG,aAAO;IAAM;AAE3F,UAAM,SAAS,MAAM,KAAK,MAAM;AAEhC,QAAI,UAAkB,EAAE,MAAM,OAAO,MAAM,MAAM,GAAG,KAAK;AAQzD,QAAI,gBAAgB;AAChB,gBAAU,qBAAqB,SAAS,gBAAgB,GAAG;IAC/D,WAAW,oBAAoB,IAAI,GAAG;AAGlC,gBAAU,iCAAiC,SAAS,MAAM,GAAG;IACjE,OAAO;AACH,YAAM,aAAa,2BAA2B,IAAI;AAClD,UAAI,WAAY,WAAU,qBAAqB,SAAS,YAAY,GAAG;IAC3E;AAGA,UAAM,mBAAmB,mBAAmB,UAAa,CAAC,qBAAqB,IAAI;AACnF,cAAU,8BAA8B,SAAS,MAAM,GAAG,MAAM,KAAK,gBAAgB;AAErF,UAAM,OAAe,EAAE,MAAM,QAAQ,IAAI,QAAQ,UAAU,CAAC,OAAO,EAAE;AACrE,QAAI,GAAG,SAAU,MAAK,WAAW,GAAG;AACpC,QAAI,GAAG,UAAW,MAAK,YAAY,GAAG;AACtC,QAAI,GAAG,iBAAkB,MAAK,mBAAmB,GAAG;AACpD,QAAI,KAAK,KAAK,IAAI;AAElB,SAAK,OAAO,UAAU,SAAS;AAC/B,WAAO;EACX;AAMA,WAAS,qBAAqB,OAAe,IAAwC,KAA2B;AAC5G,QAAI,CAAC,GAAI,QAAO;AAChB,UAAM,SAAS,iBAAiB,GAAG,QAAQ,GAAG;AAE9C,QAAI,IAAI;AACR,QAAI,gBAAgB,GAAA,aAA4B,GAAG,WAAW,QAAW,GAAG;AAC5E,QAAI,gBAAgB,GAAA,UAAyB,GAAG,QAAQ,QAAQ,GAAG;AACnE,QAAI,gBAAgB,GAAA,SAAwB,GAAG,OAAO,QAAQ,GAAG;AACjE,WAAO;EACX;AAEA,WAAS,gBACL,OAAe,MACf,KAAoC,QAA0B,KACxD;AACN,QAAI,QAAQ,OAAW,QAAO;AAM9B,UAAM,gBAAgD,SAAA,WAAgC,MAAM,QAAQ,GAAG,IACjG,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,GAAG,IAC3B;AACN,UAAM,IAAI,eAAoB,aAAa;AAC3C,QAAI,EAAE,SAAA,UAA0B;AAC5B,aAAO,EAAE,MAAM,KAAK,WAAW,EAAE,OAAO,YAAY,MAAM,gBAAgB,MAAM,EAAE,KAAK,GAAG,MAAM,EAAE,GAAG,UAAU,CAAC,KAAK,EAAE;IAC3H;AACA,QAAI,EAAE,SAAA,YAA4B;AAC9B,YAAM,SAAc,EAAE,WAAW,EAAE,UAAU,IAAI,CAAA,OAAM;AACnD,cAAM,MAAM,aAAa,IAAI,YAAY,MAAM,gBAAgB,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;AACvF,eAAO,SAAA,cAAmCV,gBAAAA,gBAAA,CAAA,GAAK,GAAA,GAAQ,uBAAuB,EAAE,CAAA,IAAM;MAC1F,CAAC,EAAE;AACH,UAAI,EAAE,SAAS,OAAW,QAAO,OAAO,EAAE;AAC1C,aAAO;QACH,MAAM;QACN,SAAS,EAAE,WAAW,OAAO;QAC7B,UAAU,CAAC,KAAK;MACpB;IACJ;AACA,WAAO;EACX;AAEA,WAAS,gBAAgB,MAAqB,OAAiB;AAC3D,QAAI,SAAA,YAAkC,QAAO,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAClE,QAAI,SAAA,SAA+B,QAAO,CAAC;AAC3C,WAAO,CAAC,IAAI,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,CAAC;EACtC;AAUA,WAAS,uBAAuB,IAA8C;AAzI9E,QAAA,IAAA;AA0II,UAAM,MAA2B,CAAC;AAClC,UAAM,MAAK,KAAA,GAAG,eAAH,OAAA,KAAiB,GAAG;AAC/B,UAAM,MAAK,KAAA,GAAG,cAAH,OAAA,KAAgB,GAAG;AAC9B,QAAI,MAAM,QAAQ,EAAE,EAAG,KAAI,aAAa,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACvD,QAAI,MAAM,QAAQ,EAAE,EAAG,KAAI,YAAY,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AACtD,WAAO;EACX;AAsBA,WAAS,iCAAiC,OAAe,MAAc,MAA4B;AAtKnG,QAAA;AAuKI,UAAM,UAAU,KAAK,WAAW,OAAO,KAAK,YAAY,YAAY,CAAC,MAAM,QAAQ,KAAK,OAAO,IACxF,KAAK,UAAkC;AAC9C,UAAM,SAAS,WAAA,OAAA,SAAA,QAAS;AACxB,UAAM,MAAM,UAAU,OAAO,WAAW,YAAY,MAAM,QAAS,OAA+B,SAAS,IACnG,OAA+B,YACjC;AACN,QAAI,CAAC,OAAO,CAAC,IAAI,OAAQ,QAAO;AAEhC,UAAM,eAA2C,CAAC;AAClD,UAAM,YAAwC,CAAC;AAC/C,UAAM,WAAuC,CAAC;AAE9C,eAAW,MAAM,KAAK;AAClB,YAAM,MAAK,KAAA,GAAG,UAAH,OAAA,KAAY,GAAG,MAAM,CAAC;AACjC,YAAM,SAAS,aAAa,IAAW,MAAS;AAChD,UAAI,MAAM,QAAQ,EAAE,SAAS,GAAG;AAC5B,qBAAa,KAAKD,eAAAC,gBAAAA,gBAAA,CAAA,GAAK,MAAA,GAAW,uBAAuB,EAAE,CAAA,GAAzC,EAA4C,OAAO,EAAE,WAAW,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE,EAAE,CAAA,CAAC;MAC5H;AACA,UAAI,OAAO,EAAE,WAAW,UAAU;AAC9B,cAAM,MAA2B,EAAE,QAAQ,CAAC,EAAE,OAAO;AACrD,YAAI,MAAM,QAAQ,EAAE,MAAM,EAAG,KAAI,SAAS,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AACnE,kBAAU,KAAKD,eAAAC,gBAAA,CAAA,GAAK,MAAA,GAAL,EAAa,OAAO,IAAI,CAAA,CAAC;MAC5C;AACA,UAAI,MAAM,QAAQ,EAAE,KAAK,GAAG;AACxB,cAAM,MAA2B,EAAE,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,GAAG,IAAI,EAAE,MAAM,CAAC,CAAC,EAAE;AAC3E,YAAI,MAAM,QAAQ,EAAE,MAAM,EAAG,KAAI,SAAS,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AACnE,iBAAS,KAAKD,eAAAC,gBAAA,CAAA,GAAK,MAAA,GAAL,EAAa,OAAO,IAAI,CAAA,CAAC;MAC3C;IACJ;AAKA,UAAM,UAAW,UAAA,OAAA,SAAA,OAA4C;AAC7D,UAAM,WAAW,CAACW,SAAyD;AACvE,YAAM,QAA6B,EAAE,WAAWA,KAAI;AACpD,UAAI,YAAY,OAAW,OAAM,OAAO;AACxC,aAAO;IACX;AAEA,QAAI,IAAI;AAER,QAAI,aAAa,OAAQ,KAAI,EAAE,MAAM,KAAK,SAAS,EAAE,WAAW,SAAS,YAAY,EAAE,GAAG,UAAU,CAAC,CAAC,EAAE;AACxG,QAAI,UAAU,OAAW,KAAI,EAAE,MAAM,KAAK,SAAS,EAAE,WAAW,SAAS,SAAS,EAAK,GAAG,UAAU,CAAC,CAAC,EAAE;AACxG,QAAI,SAAS,OAAY,KAAI,EAAE,MAAM,KAAK,SAAS,EAAE,WAAW,SAAS,QAAQ,EAAM,GAAG,UAAU,CAAC,CAAC,EAAE;AACxG,WAAO;EACX;AAKA,WAAS,qBAAqB,MAAuB;AACjD,QAAI,OAAO,KAAK,cAAc,SAAU,QAAO;AAC/C,QAAI,KAAK,aAAa,OAAO,KAAK,cAAc,SAAU,QAAO;AACjE,WAAO,oBAAoB,IAAI;EACnC;AAIA,WAAS,oBAAoB,MAAuB;AAChD,UAAM,UAAU,KAAK,WAAW,OAAO,KAAK,YAAY,YAAY,CAAC,MAAM,QAAQ,KAAK,OAAO,IACxF,KAAK,UAAkC;AAC9C,WAAO,CAAC,EAAE,WAAW,QAAQ;EACjC;AAYA,WAAS,2BAA2B,MAAkD;AAClF,QAAI,OAAO,KAAK,cAAc,UAAU;AACpC,YAAM,QAAQ,4BAA4B,KAAK,SAAS;AACxD,UAAI,CAAC,MAAO,QAAO;AACnB,YAAM,MAA8B,CAAC;AACrC,UAAI,MAAM,UAAW,KAAI,YAAY,MAAM;AAC3C,UAAI,MAAM,WAAW,OAAW,KAAI,SAAS,MAAM;AAInD,UAAI,MAAM,MAAO,KAAI,QAAQ,EAAE,OAAO,MAAM,MAAM;AAClD,UAAI,MAAM,OAAQ,KAAI,SAAS,MAAM;AACrC,aAAO,OAAO,KAAK,GAAG,EAAE,SAAS,MAAM;IAC3C;AACA,WAAO;EACX;AAQA,WAAS,4BAA4B,GAA2F;AAzQhI,QAAA,IAAA,IAAA,IAAA,IAAA,IAAA,IAAA,IAAA,IAAA,IAAA,IAAA,IAAA,IAAA;AA2QI,UAAM,KAAK;AACX,QAAI;AACJ,UAAM,MAAiB,CAAC;AACxB,YAAQ,IAAI,GAAG,KAAK,CAAC,OAAO,MAAM;AAC9B,YAAM,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,EAAE,OAAO,CAAA,MAAK,EAAE,SAAS,CAAC,EAAE,IAAI,MAAM;AACtE,UAAI,KAAK,EAAE,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC;IACjC;AACA,QAAI,CAAC,IAAI,OAAQ,QAAO;AAIxB,UAAM,OAAO,IAAI,IAAI,SAAS,CAAC;AAC/B,QAAI,KAAK,SAAS,aAAa;AAC3B,eAAS,IAAI,IAAI,SAAS,GAAG,KAAK,GAAG,KAAK;AACtC,cAAM,OAAO,IAAI,CAAC;AAClB,YAAI,KAAK,SAAS,YAAa;AAC/B,cAAM,MAAK,KAAA,KAAK,KAAK,CAAC,MAAX,OAAA,KAAgB;AAC3B,cAAM,MAAK,KAAA,KAAK,KAAK,CAAC,MAAX,OAAA,KAAgB;AAC3B,cAAM,MAAK,KAAA,KAAK,KAAK,CAAC,MAAX,OAAA,KAAgB;AAC3B,cAAM,MAAK,KAAA,KAAK,KAAK,CAAC,MAAX,OAAA,KAAgB;AAC3B,YAAI,OAAO,CAAC,MAAM,OAAO,CAAC,GAAI;AAG9B,cAAMN,OAA0E,CAAC;AACjFA,aAAI,SAAS,CAAC,IAAI,EAAE;AACpB,iBAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AACxB,cAAI,IAAI,CAAC,EAAE,SAAS,aAAa;AAC7B,kBAAM,MAAK,KAAA,IAAI,CAAC,EAAE,KAAK,CAAC,MAAb,OAAA,KAAkB;AAC7B,kBAAM,MAAK,KAAA,IAAI,CAAC,EAAE,KAAK,CAAC,MAAb,OAAA,KAAkB;AAC7BA,iBAAI,YAAYA,KAAI,YAAY,CAACA,KAAI,UAAU,CAAC,IAAI,IAAIA,KAAI,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;UAC5F;QACJ;AACA,iBAAS,IAAI,IAAI,GAAG,IAAI,IAAI,SAAS,GAAG,KAAK;AACzC,gBAAM,KAAK,IAAI,CAAC;AAChB,cAAI,GAAG,SAAS,SAAUA,MAAI,WAAU,KAAAA,KAAI,WAAJ,OAAA,KAAc,OAAM,KAAA,GAAG,KAAK,CAAC,MAAT,OAAA,KAAc;mBACjE,GAAG,SAAS,SAAS;AAC1B,kBAAM,MAAK,KAAA,GAAG,KAAK,CAAC,MAAT,OAAA,KAAc;AACzB,kBAAM,KAAK,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,CAAC,IAAI;AAC7CA,iBAAI,QAAQA,KAAI,QAAQ,CAACA,KAAI,MAAM,CAAC,IAAI,IAAIA,KAAI,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;UAC5E;QACJ;AACA,eAAOA;MACX;IACJ;AAKA,QAAI;AACJ,QAAI;AACJ,QAAI;AACJ,eAAW,MAAM,KAAK;AAClB,UAAI,GAAG,SAAS,aAAa;AACzB,cAAM,MAAK,KAAA,GAAG,KAAK,CAAC,MAAT,OAAA,KAAc;AACzB,cAAM,MAAK,KAAA,GAAG,KAAK,CAAC,MAAT,OAAA,KAAc;AACzB,oBAAY,YAAY,CAAC,UAAU,CAAC,IAAI,IAAI,UAAU,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;MAC5E,WAAW,GAAG,SAAS,UAAU;AAC7B,kBAAU,UAAA,OAAA,SAAU,OAAM,KAAA,GAAG,KAAK,CAAC,MAAT,OAAA,KAAc;MAC5C,WAAW,GAAG,SAAS,SAAS;AAC5B,cAAM,MAAK,KAAA,GAAG,KAAK,CAAC,MAAT,OAAA,KAAc;AACzB,cAAM,KAAK,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,CAAC,IAAI;AAC7C,gBAAQ,QAAQ,CAAC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;MAC5D;IACJ;AACA,UAAM,MAA2D,CAAC;AAClE,QAAI,UAAW,KAAI,YAAY;AAC/B,QAAI,WAAW,OAAW,KAAI,SAAS;AACvC,QAAI,MAAO,KAAI,QAAQ;AACvB,WAAO,OAAO,KAAK,GAAG,EAAE,SAAS,MAAM;EAC3C;AAkBA,WAAS,8BAA8B,OAAe,YAAoB,UAAkB,KAAmB,kBAAmC;AAC9I,UAAM,aAAa,IAAI,MAAM,IAAI,QAAQ;AAOzC,UAAM,kBAAkB,IAAI,mBAAmB,IAAI,UAAU,KAAK,CAAC;AACnE,UAAM,YAAY,mBAAmB,qBAAqB,YAAY,GAAG,IAAI;AAC7E,UAAM,cAAc,YAAY,CAAC,GAAG,iBAAiB,SAAS,IAAI;AAClE,UAAM,cAAe,cAAc,IAAI,mBAAmB,IAAI,UAAU,KAAM,CAAC;AAE/E,QAAI,CAAC,YAAY,UAAU,CAAC,YAAY,OAAQ,QAAO;AAIvD,UAAM,QAAQ,oBAAI,IAAY;AAC9B,eAAW,KAAK,YAAa,KAAI,EAAE,mBAAoB,YAAW,MAAM,EAAE,mBAAoB,OAAM,IAAI,GAAG,IAAI;AAC/G,eAAW,KAAK,YAAa,KAAI,EAAE,mBAAoB,YAAW,MAAM,EAAE,mBAAoB,OAAM,IAAI,GAAG,IAAI;AAC/G,UAAM,WAAW,MAAM,OAAO;AAE9B,QAAI,CAAC,UAAU;AACX,YAAM,MAAM,mBAAmB,WAAW;AAC1C,YAAM,MAAM,mBAAmB,WAAW;AAC1C,YAAM,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC;AACzB,YAAM,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC;AACzB,UAAI,OAAO,KAAK,OAAO,EAAG,QAAO;AACjC,aAAO,EAAE,MAAM,KAAK,WAAW,eAAe,KAAK,MAAM,KAAK,KAAK,UAAU,CAAC,KAAK,EAAE;IACzF;AAEA,UAAM,cAAc,MAAM,KAAK,KAAK,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAC1D,UAAM,YAAY,YAAY,IAAI,CAAA,MAAK;AACnC,YAAM,MAAM,eAAe,aAAa,CAAC;AACzC,YAAM,MAAM,eAAe,aAAa,CAAC;AACzC,aAAO,EAAE,MAAM,GAAG,OAAO,EAAE,WAAW,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,EAAsB,EAAE;IACnG,CAAC;AACD,WAAO,EAAE,MAAM,KAAK,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,UAAU,CAAC,KAAK,EAAE;EACjF;AAGA,WAAS,mBAAmB,OAAuD;AAC/E,QAAI,IAAI,GAAG,IAAI;AACf,eAAW,KAAK,OAAO;AACnB,UAAI,EAAE,WAAW;AAAE,aAAK,EAAE,UAAU,CAAC;AAAG,aAAK,EAAE,UAAU,CAAC;MAAG;IACjE;AACA,WAAO,CAAC,GAAG,CAAC;EAChB;AAKA,WAAS,eAAe,OAAqC,GAA6B;AACtF,QAAI,IAAI,GAAG,IAAI;AACf,eAAW,KAAK,OAAO;AACnB,UAAI,EAAE,sBAAsB,EAAE,mBAAmB,QAAQ;AACrD,cAAM,IAAI,UAAU,EAAE,oBAAoB,CAAC;AAC3C,aAAK,EAAE,CAAC;AAAG,aAAK,EAAE,CAAC;MACvB,WAAW,EAAE,WAAW;AACpB,aAAK,EAAE,UAAU,CAAC;AAAG,aAAK,EAAE,UAAU,CAAC;MAC3C;IACJ;AACA,WAAO,CAAC,GAAG,CAAC;EAChB;AAEA,WAAS,UAAU,KAAuD,GAA6B;AACnG,QAAI,KAAK,IAAI,CAAC,EAAE,KAAM,QAAO,IAAI,CAAC,EAAE;AACpC,QAAI,KAAK,IAAI,IAAI,SAAS,CAAC,EAAE,KAAM,QAAO,IAAI,IAAI,SAAS,CAAC,EAAE;AAC9D,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACjC,UAAI,KAAK,IAAI,CAAC,EAAE,MAAM;AAClB,cAAM,OAAO,IAAI,IAAI,CAAC;AACtB,cAAM,MAAM,IAAI,CAAC;AACjB,cAAM,KAAK,IAAI,KAAK,SAAS,IAAI,OAAO,KAAK;AAC7C,eAAO,CAAC,KAAK,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,KAAK,GAAG,KAAK,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,KAAK,CAAC;MAClH;IACJ;AACA,WAAO,IAAI,IAAI,SAAS,CAAC,EAAE;EAC/B;AAiBO,WAAS,0BAA0B,MAAc,KAAyB;AAK7E,UAAM,mBAAmB,oBAAI,IAAY;AACzC,UAAM,0BAA0B,CAAC,MAAoB;AAtczD,UAAA,IAAA;AAucQ,YAAM,QAAO,MAAA,KAAA,EAAE,YAAF,OAAA,SAAA,GAAW,aAAX,OAAA,SAAA,GAAqB;AAClC,UAAI,OAAO,SAAS,UAAU;AAC1B,yBAAiB,IAAI,CAAC;AACtB,cAAM,aAAa,IAAI,MAAM,IAAI,IAAI;AACrC,YAAI,WAAY,kBAAiB,IAAI,UAAU;MACnD;AACA,UAAI,MAAM,QAAQ,EAAE,QAAQ,EAAG,YAAW,MAAM,EAAE,SAAU,yBAAwB,EAAE;IAC1F;AACA,4BAAwB,IAAI;AAC5B,QAAI,iBAAiB,SAAS,EAAG;AAEjC,UAAM,OAAO,CAAC,MAAc,UAA8C;AACtE,UAAI,iBAAiB,IAAI,IAAI,EAAG,KAAI,mBAAmB,IAAI,MAAM,KAAK;AACtE,UAAI,MAAM,QAAQ,KAAK,QAAQ,GAAG;AAC9B,cAAM,MAAM,qBAAqB,MAAM,GAAG;AAC1C,cAAM,OAAO,MAAM,CAAC,GAAG,OAAO,GAAG,IAAI;AACrC,mBAAW,MAAM,KAAK,SAAU,MAAK,IAAI,IAAI;MACjD;IACJ;AACA,SAAK,MAAM,CAAC,CAAC;EACjB;AAKA,WAAS,qBAAqB,MAAc,KAAsD;AAhelG,QAAA,IAAA,IAAA;AAieI,UAAM,KAAK,KAAK;AAChB,UAAM,eAAe,KAAK,WAAW,OAAO,KAAK,YAAY,YAAY,CAAC,MAAM,QAAQ,KAAK,OAAO,IAC7F,KAAK,QAAgC,YAAY;AACxD,QAAI,OAAO,UAAa,CAAC,aAAc,QAAO;AAE9C,UAAM,MAA6B,CAAC;AAEpC,QAAI,OAAO,OAAO,UAAU;AACxB,YAAM,QAAQ,6BAA6B,IAAI,GAAG;AAClD,UAAI,MAAO,KAAI,YAAY;IAC/B,WAAW,MAAM,OAAO,OAAO,UAAU;AACrC,YAAM,QAAS,GAA2B;AAC1C,UAAI,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,SAAS,GAAG;AACtE,YAAI,YAAY,CAAC,MAAM,UAAU,CAAC,KAAK,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC;MACrE;AACA,UAAI,UAAU,MAAM,WAAW,UAAa,MAAM,UAAU,UAAa,MAAM,SAAS,SAAY;AAChG,YAAI,SAAS,KAAK,2FAA2F;MACjH;IACJ;AAEA,QAAI,gBAAgB,MAAM,QAAS,aAAqC,SAAS,GAAG;AAChF,YAAM,MAAO,aAAqC;AAClD,YAAM,eAAiE,CAAC;AACxE,iBAAW,MAAM,KAAK;AAClB,cAAM,KAAI,KAAA,GAAG,UAAH,OAAA,KAAY,GAAG;AACzB,cAAM,KAAK,MAAA,KAAA,GAAG,SAAH,OAAA,KAAW,GAAG,MAAd,OAAA,KAAmB;AAC9B,YAAI,KAAK,OAAO,MAAM,YAAY,MAAM,QAAQ,EAAE,SAAS,GAAG;AAC1D,uBAAa,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,EAAE,UAAU,CAAC,KAAK,GAAG,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;AAChF,cAAI,EAAE,WAAW,UAAa,EAAE,UAAU,UAAa,EAAE,SAAS,QAAW;AACzE,gBAAI,SAAS,KAAK,yDAAyD;UAC/E;QACJ;MACJ;AACA,UAAI,aAAa,OAAQ,KAAI,qBAAqB;IACtD;AAEA,WAAQ,IAAI,aAAa,IAAI,qBAAsB,MAAM;EAC7D;AAMA,WAAS,6BAA6B,GAAW,KAAiD;AAC9F,UAAM,KAAK;AACX,QAAI;AACJ,QAAI,IAAI,GAAG,IAAI;AACf,QAAI,OAAO;AACX,QAAI,sBAAsB;AAC1B,YAAQ,IAAI,GAAG,KAAK,CAAC,OAAO,MAAM;AAC9B,YAAM,OAAO,EAAE,CAAC;AAChB,YAAM,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,EAAE,OAAO,CAAA,MAAK,EAAE,SAAS,CAAC,EAAE,IAAI,MAAM;AACtE,UAAI,SAAS,aAAa;AACtB,aAAK,KAAK,CAAC,KAAK;AAChB,aAAK,KAAK,CAAC,KAAK;AAChB,eAAO;MACX,OAAO;AACH,8BAAsB;MAC1B;IACJ;AACA,QAAI,oBAAqB,KAAI,SAAS,KAAK,mEAAmE,CAAC;AAC/G,WAAO,OAAO,CAAC,GAAG,CAAC,IAAI;EAC3B;AC1gBA,MAAM,iBAAiB;AAehB,WAAS,aACZ,MACAI,QACA,KACI;AACJ,QAAI,CAACA,OAAO;AACZ,UAAM,SAASA,OAAM;AACrB,QAAI,CAAC,QAAQ;AACT,UAAIA,OAAM,SAAS,eAAgB,KAAI,OAAO,KAAK,mCAAmC;AACtF;IACJ;AAIA,UAAM,WAAWA,OAAM,SAAS,iBACzB,IAAI,mBAAmB,IAAI,MAAM,KAAK,SACvC;AACN,SAAK,OAAO,MAAM;EACtB;AAEO,WAAS,gCACZ,MACAA,QACA,gBACA,KACM;AACN,iBAAa,MAAMA,QAAO,GAAG;AAC7B,WAAO,0BAA0B,MAAM,gBAAgB,GAAG;EAC9D;AC/BO,WAAS,oBAAoB,MAAc,IAAkC,KAA2B;AAjC/G,QAAA,IAAA;AAkCI,QAAI,CAAC,GAAI,QAAO;AAEhB,UAAM,UAAS,KAAA,GAAG,WAAH,OAAA,KAAa;AAC5B,QAAI,SAAS,GAAG;AAAE,UAAI,OAAO,KAAK,8BAA8B,GAAG,MAAM;AAAG,aAAO;IAAM;AAKzF,UAAM,kBAAkB,KAAK;AAG7B,UAAM,uBAAuB,KAAA,KAAK,YAAL,OAAA,SAAA,GAAoD;AAEjF,UAAM,OAAO,MAAM,IAAI;AACvB,WAAO,KAAK;AACZ,QAAI,KAAK,SAAS;AACd,aAAQ,KAAK,QAAkC;AAC/C,UAAI,OAAO,KAAK,KAAK,OAAO,EAAE,WAAW,EAAG,QAAO,KAAK;IAC5D;AAMA,WAAO,KAAK;AAEZ,UAAM,WAA0B,CAAC,IAAI;AACrC,aAAS,IAAI,GAAG,IAAI,QAAQ,KAAK;AAC7B,YAAM,YAAY,MAAM,IAAI;AAC5B,YAAM,UAAU,oBAAoB,IAAI,CAAC;AAGzC,YAAM,UAAU,UAAU,0BAA0B,WAAW,SAAS,GAAG,IAAI;AAC/E,eAAS,KAAK,OAAO;IACzB;AAEA,UAAM,UAAkB,EAAE,MAAM,KAAK,SAAS;AAC9C,QAAI,KAAK,GAAI,SAAQ,KAAK,KAAK;AAC/B,QAAI,oBAAoB,OAAW,SAAQ,YAAY;AACvD,QAAI,wBAAwB,OAAW,SAAQ,UAAU,EAAE,WAAW,oBAAoB;AAC1F,WAAO;EACX;AAQA,WAAS,oBAAoB,IAAsB,GAA+C;AAC9F,UAAM,MAA8B,CAAC;AAErC,QAAI,GAAG,cAAc,QAAW;AAC5B,UAAI,YAAY,kBAAkB,GAAG,WAAW,CAAA,MAAK,CAAC,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAC7E;AACA,QAAI,GAAG,WAAW,QAAW;AACzB,UAAI,SAAS,oBAAoB,GAAG,QAAQ,CAAA,MAAK,IAAI,CAAC;IAC1D;AACA,QAAI,GAAG,UAAU,QAAW;AACxB,UAAI,QAAQ,gBAAgB,GAAG,OAAO,CAAC;IAC3C;AACA,QAAI,GAAG,WAAW,QAAW;AAGzB,UAAI,SAAS,GAAG;IACpB;AAEA,WAAO,OAAO,KAAK,GAAG,EAAE,SAAS,MAAM;EAC3C;AAGA,WAAS,kBAAkB,KAAyB,IAA2C;AAC3F,QAAI,MAAM,QAAQ,GAAG,EAAG,QAAO,GAAG,GAAW;AAC7C,QAAI,OAAO,OAAO,QAAQ,UAAU;AAChC,YAAM,MAAM;AACZ,UAAI,MAAM,QAAQ,IAAI,SAAS,GAAG;AAC9B,eAAOV,eAAAC,gBAAA,CAAA,GACA,GAAA,GADA;UAEH,WAAW,IAAI,UAAU,IAAI,CAAA,OAAM,MAAM,GAAG,UAAU,SAAYD,eAAAC,gBAAA,CAAA,GAAK,EAAA,GAAL,EAAS,OAAO,GAAG,GAAG,KAAK,EAAE,CAAA,IAAI,EAAE;QACzG,CAAA;MACJ;AACA,UAAI,IAAI,UAAU,QAAW;AACzB,eAAOD,eAAAC,gBAAA,CAAA,GAAK,GAAA,GAAL,EAAU,OAAO,GAAG,IAAI,KAAK,EAAE,CAAA;MAC1C;IACJ;AACA,WAAO;EACX;AAGA,WAAS,oBAAoB,KAA2B,IAAiD;AACrG,QAAI,OAAO,QAAQ,SAAU,QAAO,GAAG,GAAG;AAC1C,QAAI,OAAO,OAAO,QAAQ,UAAU;AAChC,YAAM,MAAM;AACZ,UAAI,MAAM,QAAQ,IAAI,SAAS,GAAG;AAC9B,eAAOD,eAAAC,gBAAA,CAAA,GACA,GAAA,GADA;UAEH,WAAW,IAAI,UAAU,IAAI,CAAA,OAAM,MAAM,GAAG,UAAU,SAAYD,eAAAC,gBAAA,CAAA,GAAK,EAAA,GAAL,EAAS,OAAO,GAAG,GAAG,KAAK,EAAE,CAAA,IAAI,EAAE;QACzG,CAAA;MACJ;AACA,UAAI,IAAI,UAAU,QAAW;AACzB,eAAOD,eAAAC,gBAAA,CAAA,GAAK,GAAA,GAAL,EAAU,OAAO,GAAG,IAAI,KAAK,EAAE,CAAA;MAC1C;IACJ;AACA,WAAO;EACX;AAeA,WAAS,gBAAgB,KAAyB,GAA+B;AAC7E,UAAM,wBAAwB,CAAC,MAAkB,CAAC,KAAK,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC,IAAI,KAAK,CAAC,CAAC;AAClG,UAAM,sBAAsB,CAAC,MAAkB,CAAC,KAAK,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC;AAEpF,QAAI,MAAM,QAAQ,GAAG,GAAG;AAGpB,aAAO,EAAE,OAAO,sBAAsB,GAAW,EAAE;IACvD;AACA,QAAI,OAAO,OAAO,QAAQ,UAAU;AAChC,YAAM,MAAM;AACZ,UAAI,MAAM,QAAQ,IAAI,SAAS,GAAG;AAE9B,eAAOD,eAAAC,gBAAA,CAAA,GACA,GAAA,GADA;UAEH,WAAW,IAAI,UAAU,IAAI,CAAA,OAAM,MAAM,GAAG,UAAU,SAAYD,eAAAC,gBAAA,CAAA,GAAK,EAAA,GAAL,EAAS,OAAO,oBAAoB,GAAG,KAAK,EAAE,CAAA,IAAI,EAAE;QAC1H,CAAA;MACJ;AACA,UAAI,IAAI,UAAU,QAAW;AAEzB,eAAOD,eAAAC,gBAAA,CAAA,GAAK,GAAA,GAAL,EAAU,OAAO,sBAAsB,IAAI,KAAK,EAAE,CAAA;MAC7D;IACJ;AACA,WAAO;EACX;ACxIA,MAAM,uCAAuC;AAK7C,WAAS,SAAS,GAA2B;AA9C7C,QAAA,IAAA;AAiDI,QAAI,EAAE,UAAU;AACZ,cAAQ,KAAK,6DAA6D;IAC9E;AACA,WAAO,EAAE,QAAO,KAAA,EAAE,UAAF,OAAA,KAAW,GAAG,UAAS,KAAA,EAAE,YAAF,OAAA,KAAa,EAAE;EAC1D;AAGA,WAAS,aAAa,OAAe,QAAwB;AACzD,WAAO;MACH,OAAO,OAAO,QAAQ,OAAO,UAAU,MAAM;MAC7C,SAAS,OAAO,UAAU,MAAM;IACpC;EACJ;AAGA,WAAS,gBAAgB,GAAuC;AAhEhE,QAAA,IAAA;AAiEI,YAAO,MAAA,KAAA,EAAE,YAAF,OAAA,SAAA,GAAW,UAAX,OAAA,SAAA,GAAkB;EAC7B;AAGA,WAAS,iBAAiB,GAAiB;AArE3C,QAAA;AAsEI,UAAMS,UAAQ,KAAA,EAAE,YAAF,OAAA,SAAA,GAAW;AACzB,QAAI,CAACA,OAAO;AACZ,WAAOA,OAAM;AACb,QAAI,OAAO,KAAKA,MAAK,EAAE,WAAW,EAAG,QAAO,EAAE,QAAS;AACvD,QAAI,EAAE,WAAW,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAG,QAAO,EAAE;EACnE;AAMO,WAAS,sBAAsB,MAAc,KAAyB;AACzE,QAAI,MAAM,MAAM;AAChB,cAAU,MAAM,IAAI,KAAK;AAEzB,UAAM,QAAuB,CAAC;AAC9B,UAAM,UAAU,CAAC,MAAoB;AAtFzC,UAAA;AAuFQ,UAAI,gBAAgB,CAAC,EAAG,OAAM,KAAK,CAAC;AACpC,OAAA,KAAA,EAAE,aAAF,OAAA,SAAA,GAAY,QAAQ,OAAA;IACxB;AACA,YAAQ,IAAI;AAUZ,UAAM,aAAa,oBAAI,IAAoB;AAC3C,eAAW,QAAQ,OAAO;AACtB,UAAI,QAAQ;AACZ,YAAM,UAAU,oBAAI,IAAY;AAChC,YAAM,OAAO,CAAC,MAAgC;AAxGtD,YAAA;AAyGY,YAAI,CAAC,EAAG;AACR,YAAI,MAAM,QAAQ,gBAAgB,CAAC,EAAG;AACtC,YAAI,EAAE,SAAS,SAAS,EAAE,MAAM;AAC5B,gBAAM,KAAKC,WAAU,EAAE,IAAI;AAC3B,cAAI,MAAM,CAAC,QAAQ,IAAI,EAAE,GAAG;AAAE,oBAAQ,IAAI,EAAE;AAAG,iBAAK,IAAI,MAAM,IAAI,EAAE,CAAC;UAAG;QAC5E;AACA,SAAA,KAAA,EAAE,aAAF,OAAA,SAAA,GAAY,QAAQ,IAAA;MACxB;AACA,YAAM,SAASA,WAAU,KAAK,IAAI;AAClC,UAAI,QAAQ;AAAE,gBAAQ,IAAI,MAAM;AAAG,aAAK,IAAI,MAAM,IAAI,MAAM,CAAC;MAAG;AAChE,iBAAW,IAAI,MAAM,KAAK;IAC9B;AAEA,UAAM,KAAK,CAAC,GAAG,MAAG;AAtHtB,UAAA,IAAA;AAsH0B,eAAA,KAAA,WAAW,IAAI,CAAC,MAAhB,OAAA,KAAqB,OAAM,KAAA,WAAW,IAAI,CAAC,MAAhB,OAAA,KAAqB;IAAA,CAAE;AAExE,eAAW,WAAW,OAAO;AACzB,YAAM,SAAS,gBAAgB,OAAO;AACtC,UAAI,CAAC,OAAQ;AAOb,uBAAiB,OAAO;AACxB,wBAAkB,SAAS,SAAS,MAAM,GAAG,GAAG;IACpD;EACJ;AAKA,WAAS,kBAAkB,SAAiB,QAAgB,KAAyB;AACjF,UAAM,WAAWA,WAAU,QAAQ,IAAI;AACvC,QAAI,CAAC,UAAU;AAAE,UAAI,OAAO,KAAK,qCAAqC;AAAG;IAAQ;AAEjF,UAAM,cAAc,gBAAgB,UAAU,QAAQ,KAAK,oBAAI,IAAI,CAAC;AACpE,QAAI,CAAC,YAAa;AAElB,QAAI,sCAAsC;AACtC,YAAM,YAAY,IAAI,MAAM,IAAI,WAAW;AAC3C,cAAQ,OAAO;AACf,aAAO,QAAQ;AACf,cAAQ,WAAW,CAAC,SAAS;AAG7B,wBAAkB,OAAO;AACzB,UAAI,OAAO,IAAI,KAAK,OAAO,CAAA,MAAK,MAAM,SAAS;IACnD,OAAO;AACH,cAAQ,OAAO,MAAM;IACzB;EACJ;AAQA,WAAS,gBAAgB,UAAkB,OAAe,KAAmB,OAAwC;AACjH,QAAI,MAAM,IAAI,QAAQ,GAAG;AAAE,UAAI,OAAO,KAAK,uBAAuB,WAAW,GAAG;AAAG,aAAO;IAAW;AACrG,UAAM,SAAS,IAAI,MAAM,IAAI,QAAQ;AACrC,QAAI,CAAC,QAAQ;AAAE,UAAI,SAAS,KAAK,qBAAqB,WAAW,aAAa;AAAG,aAAO;IAAW;AAEnG,UAAM,YAAY,MAAM,MAAM;AAC9B,yBAAqB,WAAW,GAAG;AAKnC,QAAI,OAAO,SAAS,OAAO;AACvB,6BAAuB,WAAW,MAAM,OAAO,MAAM,OAAO;IAChE,OAAO;AACH,yBAAmB,WAAW,MAAM,OAAO,MAAM,OAAO;IAC5D;AAGA,qBAAiB,SAAS;AAI1B,QAAI,OAAO,SAAS,SAAS,OAAO,MAAM;AACtC,YAAM,QAAQA,WAAU,OAAO,IAAI;AACnC,UAAI,OAAO;AACP,cAAM,cAAc,gBAAgB,MAAM;AAC1C,cAAM,WAAW,cAAc,aAAa,SAAS,WAAW,GAAG,KAAK,IAAI;AAC5E,cAAM,WAAW,IAAI,IAAI,KAAK;AAAG,iBAAS,IAAI,QAAQ;AACtD,cAAM,SAAS,gBAAgB,OAAO,UAAU,KAAK,QAAQ;AAC7D,YAAI,OAAQ,WAAU,OAAO,MAAM;MACvC;IACJ,OAAO;AAQH,kCAA4B,WAAW,OAAO,KAAK,OAAO,QAAQ;IACtE;AAEA,QAAI,KAAK,KAAK,SAAS;AACvB,QAAI,OAAO,UAAU,OAAO,SAAU,KAAI,MAAM,IAAI,UAAU,IAAI,SAAS;AAC3E,WAAO,OAAO,UAAU,OAAO,WAAW,UAAU,KAAK;EAC7D;AASA,WAAS,4BAA4B,MAAc,OAAe,KAAmB,OAAoB,gBAA8B;AACnI,UAAM,QAAQ,CAAC,MAAoB;AA3NvC,UAAA;AA4NQ,YAAM,SAAS,gBAAgB,CAAC;AAChC,UAAI,EAAE,SAAS,SAAS,UAAU,EAAE,MAAM;AACtC,cAAM,QAAQA,WAAU,EAAE,IAAI;AAC9B,YAAI,OAAO;AACP,gBAAM,WAAW,aAAa,SAAS,MAAM,GAAG,KAAK;AACrD,gBAAM,WAAW,IAAI,IAAI,KAAK;AAAG,mBAAS,IAAI,cAAc;AAC5D,gBAAM,SAAS,gBAAgB,OAAO,UAAU,KAAK,QAAQ;AAC7D,cAAI,OAAQ,GAAE,OAAO,MAAM;QAC/B;AACA,yBAAiB,CAAC;MACtB;AACA,OAAA,KAAA,EAAE,aAAF,OAAA,SAAA,GAAY,QAAQ,KAAA;IACxB;AACA,UAAM,IAAI;EACd;AAIA,WAAS,mBAAmB,MAAc,OAAe,SAAuB;AA9OhF,QAAA;AA+OI,2BAAuB,MAAM,OAAO,OAAO;AAC3C,KAAA,KAAA,KAAK,aAAL,OAAA,SAAA,GAAe,QAAQ,CAAA,MAAK,mBAAmB,GAAG,OAAO,OAAO,CAAA;EACpE;AAEA,WAAS,uBAAuB,MAAc,OAAe,SAAuB;AAChF,UAAME,SAAQ,CAAC,QAA0B;AACrC,iBAAW,MAAM,IAAK,KAAI,OAAO,GAAG,SAAS,SAAU,IAAG,OAAO,QAAQ,GAAG,OAAO;IACvF;AACA,QAAI,KAAK,aAAa,OAAO,KAAK,cAAc,YAAY,MAAM,QAAS,KAAK,UAAkB,SAAS,GAAG;AAC1GA,aAAO,KAAK,UAAkB,SAAS;IAC3C;AACA,QAAI,KAAK,WAAW,OAAO,KAAK,YAAY,UAAU;AAClD,iBAAW,QAAQ,OAAO,KAAK,KAAK,OAAO,GAAG;AAC1C,cAAM,OAAQ,KAAK,QAAgB,IAAI;AACvC,YAAI,QAAQ,MAAM,QAAQ,KAAK,SAAS,EAAGA,QAAM,KAAK,SAAS;MACnE;IACJ;EACJ;AC9NA,MAAM,YAAY;AAClB,MAAM,SAAS;AAGf,WAAS,SAAS,GAA0B;AACxC,UAAM,SAAwB,CAAC;AAC/B,UAAM,KAAK;AACX,QAAI;AACJ,YAAQ,IAAI,GAAG,KAAK,CAAC,OAAO,KAAM,QAAO,KAAK,EAAE,CAAC,CAAC;AAClD,WAAO;EACX;AAEA,WAAS,YAAY,IAAQ,IAAQ,IAA4B;AAC7D,WAAO;MACH,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,EAAE;MACrE,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC,IAAI,IAAI,KAAK,GAAG,CAAC,IAAI,GAAG,CAAC,EAAE;IACzE;EACJ;AAGA,WAAS,YAAY,GAAgC;AACjD,UAAM,SAAS,SAAS,CAAC;AACzB,UAAM,OAAqB,CAAC;AAE5B,QAAI,IAAI;AACR,QAAI,KAAK,GAAG,KAAK;AACjB,QAAI,KAAK,GAAG,KAAK;AACjB,QAAI,MAAM,GAAG,MAAM;AACnB,QAAI,MAAM,GAAG,MAAM;AACnB,QAAI,UAAU;AAEd,UAAMN,OAAM,MAAc,WAAW,OAAO,GAAG,CAAC;AAChD,UAAM,OAAO,CAAC,IAAQ,IAAQ,OAAiB;AAC3C,YAAM,KAAS,CAAC,IAAI,EAAE;AACtB,YAAM,MAAM,sBAAsB,IAAI,IAAI,IAAI,IAAI,SAAS;AAC3D,WAAK,KAAK,EAAE,IAAI,IAAI,IAAI,IAAI,KAAK,KAAK,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC,EAAE,CAAC;AACjE,WAAK,GAAG,CAAC;AAAG,WAAK,GAAG,CAAC;IACzB;AAIA,UAAM,WAAW,CAAC,GAAW,MAAoB;AAC7C;QACI,CAAC,MAAM,IAAI,MAAM,GAAG,MAAM,IAAI,MAAM,CAAC;QACrC,CAAC,KAAK,KAAK,IAAI,MAAM,GAAG,KAAK,KAAK,IAAI,MAAM,CAAC;QAC7C,CAAC,GAAG,CAAC;MACT;IACJ;AAEA,WAAO,IAAI,OAAO,QAAQ;AACtB,UAAI,MAAM,OAAO,CAAC;AAClB,UAAI,OAAO,KAAK,GAAG,EAAG;UACjB,OAAM,YAAY,MAAM,MAAM,YAAY,MAAM,MAAM;AAC3D,YAAM,MAAM,OAAO;AACnB,YAAM,IAAI,IAAI,YAAY;AAE1B,UAAI,MAAM,KAAK;AAAE,iBAAS,IAAI,EAAE;AAAG,aAAK;AAAI,aAAK;AAAI,kBAAU;AAAK;MAAU;AAC9E,UAAI,MAAM,KAAK;AACX,cAAM,IAAIA,KAAI,KAAK,MAAM,KAAK,IAAI,IAAIA,KAAI,KAAK,MAAM,KAAK;AAC1D,aAAK;AAAG,aAAK;AAAG,aAAK;AAAG,aAAK;AAAG,kBAAU;AAAK;MACnD;AACA,UAAI,MAAM,KAAK;AACX,iBAASA,KAAI,KAAK,MAAM,KAAK,IAAIA,KAAI,KAAK,MAAM,KAAK,EAAE;MAC3D,WAAW,MAAM,KAAK;AAClB,iBAASA,KAAI,KAAK,MAAM,KAAK,IAAI,EAAE;MACvC,WAAW,MAAM,KAAK;AAClB,iBAAS,IAAIA,KAAI,KAAK,MAAM,KAAK,EAAE;MACvC,WAAW,MAAM,KAAK;AAClB,cAAM,KAAS,CAACA,KAAI,KAAK,MAAM,KAAK,IAAIA,KAAI,KAAK,MAAM,KAAK,EAAE;AAC9D,cAAM,KAAS,CAACA,KAAI,KAAK,MAAM,KAAK,IAAIA,KAAI,KAAK,MAAM,KAAK,EAAE;AAC9D,cAAM,KAAS,CAACA,KAAI,KAAK,MAAM,KAAK,IAAIA,KAAI,KAAK,MAAM,KAAK,EAAE;AAC9D,cAAM,GAAG,CAAC;AAAG,cAAM,GAAG,CAAC;AACvB,aAAK,IAAI,IAAI,EAAE;MACnB,WAAW,MAAM,KAAK;AAClB,cAAM,SAAU,QAAQ,YAAY,MAAM,OAAO,QAAQ,YAAY,MAAM;AAC3E,cAAM,KAAS,SAAS,CAAC,IAAI,KAAK,KAAK,IAAI,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE;AAC9D,cAAM,KAAS,CAACA,KAAI,KAAK,MAAM,KAAK,IAAIA,KAAI,KAAK,MAAM,KAAK,EAAE;AAC9D,cAAM,KAAS,CAACA,KAAI,KAAK,MAAM,KAAK,IAAIA,KAAI,KAAK,MAAM,KAAK,EAAE;AAC9D,cAAM,GAAG,CAAC;AAAG,cAAM,GAAG,CAAC;AACvB,aAAK,IAAI,IAAI,EAAE;MACnB,WAAW,MAAM,KAAK;AAClB,cAAM,KAAS,CAACA,KAAI,KAAK,MAAM,KAAK,IAAIA,KAAI,KAAK,MAAM,KAAK,EAAE;AAC9D,cAAM,KAAS,CAACA,KAAI,KAAK,MAAM,KAAK,IAAIA,KAAI,KAAK,MAAM,KAAK,EAAE;AAC9D,cAAM,GAAG,CAAC;AAAG,cAAM,GAAG,CAAC;AACvB,cAAM,EAAE,IAAI,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE;AAC/C,aAAK,IAAI,IAAI,EAAE;MACnB,WAAW,MAAM,KAAK;AAClB,cAAM,SAAU,QAAQ,YAAY,MAAM,OAAO,QAAQ,YAAY,MAAM;AAC3E,cAAM,KAAS,SAAS,CAAC,IAAI,KAAK,KAAK,IAAI,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE;AAC9D,cAAM,KAAS,CAACA,KAAI,KAAK,MAAM,KAAK,IAAIA,KAAI,KAAK,MAAM,KAAK,EAAE;AAC9D,cAAM,GAAG,CAAC;AAAG,cAAM,GAAG,CAAC;AACvB,cAAM,EAAE,IAAI,GAAG,IAAI,YAAY,CAAC,IAAI,EAAE,GAAG,IAAI,EAAE;AAC/C,aAAK,IAAI,IAAI,EAAE;MACnB,WAAW,MAAM,KAAK;AAElB,aAAK;AACL,iBAASA,KAAI,KAAK,MAAM,KAAK,IAAIA,KAAI,KAAK,MAAM,KAAK,EAAE;MAC3D,OAAO;AAAE;AAAK;MAAU;AAExB,gBAAU;IACd;AAEA,WAAO,KAAK,SAAS,OAAO;EAChC;AAEA,WAASO,OAAM,GAAW,IAAY,IAAoB;AACtD,WAAO,IAAI,KAAK,KAAK,IAAI,KAAK,KAAK;EACvC;AAEO,WAAS,kBAAkB,GAA+B;AAC7D,UAAM,OAAO,YAAY,CAAC;AAC1B,QAAI,CAAC,KAAM,QAAO;AAGlB,UAAM,MAAM,IAAI,aAAa,KAAK,SAAS,CAAC;AAC5C,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,IAAK,KAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE;AACpE,UAAM,cAAc,IAAI,KAAK,MAAM;AAKnC,UAAM,QAAQ,KAAK,CAAC,EAAE,IAAI,MAAM,KAAK,KAAK,SAAS,CAAC,EAAE;AACtD,UAAM,SAAS,KAAK,MAAM,IAAI,CAAC,IAAI,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,MAAM,CAAC,CAAC,IAAI;AAGlE,UAAM,WAAW,CAAC,SAA4B;AAC1C,UAAI,IAAI;AACR,aAAO,IAAI,KAAK,SAAS,KAAK,OAAO,IAAI,IAAI,CAAC,EAAG;AACjD,YAAM,MAAM,KAAK,CAAC;AAClB,YAAM,QAAQ,OAAO,IAAI,CAAC;AAC1B,YAAM,IAAI,IAAI,MAAM,IAAI,sBAAsB,IAAI,KAAK,KAAK,IAAI;AAChE,YAAM,CAAC,GAAG,CAAC,IAAI,iBAAiB,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC;AACjE,YAAM,CAAC,IAAI,EAAE,IAAI,sBAAsB,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,CAAC;AACxE,aAAO,EAAE,GAAG,GAAG,OAAO,KAAK,MAAM,IAAI,EAAE,EAAE;IAC7C;AAEA,WAAO;MACH;MACA;MACA,iBAAiB,MAAyB;AAKtC,YAAI,UAAU,cAAc,MAAM,OAAO,KAAK,OAAO,cAAc;AAC/D,iBAAO,UAAW,OAAO,cAAe,eAAe,WAAW;QACtE;AAKA,YAAI,CAAC,WAAW,OAAO,KAAK,OAAO,cAAc;AAC7C,gBAAM,OAAO,OAAO,IAAI,IAAI;AAC5B,gBAAM,IAAI,SAAS,IAAI;AACvB,gBAAM,OAAO,OAAO;AACpB,iBAAO,EAAE,GAAG,EAAE,IAAI,KAAK,IAAI,EAAE,KAAK,IAAI,MAAM,GAAG,EAAE,IAAI,KAAK,IAAI,EAAE,KAAK,IAAI,MAAM,OAAO,EAAE,MAAM;QAClG;AACA,eAAO,SAASA,OAAM,MAAM,GAAG,WAAW,CAAC;MAC/C;IACJ;EACJ;ACtLA,MAAM,qBAAqB;AAQ3B,WAAS,SAAS,GAAmE;AACjF,QAAI,OAAO,MAAM,SAAU,QAAO,EAAE,KAAK,GAAG,KAAK,EAAE;AACnD,QAAI,KAAK,OAAO,MAAM,UAAU;AAC5B,YAAM,IAAI;AACV,UAAI,OAAO,EAAE,UAAU,SAAU,QAAO,EAAE,KAAK,EAAE,OAAO,KAAK,EAAE,MAAM;AACrE,UAAI,MAAM,QAAQ,EAAE,SAAS,KAAK,EAAE,UAAU,QAAQ;AAClD,cAAM,OAAO,EAAE,UAAU,IAAI,CAAA,MAAK,OAAO,EAAE,KAAK,KAAK,CAAC;AACtD,eAAO,EAAE,KAAK,KAAK,IAAI,GAAG,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,IAAI,EAAE;MAC5D;IACJ;AACA,WAAO,EAAE,KAAK,GAAG,KAAK,EAAE;EAC5B;AAKA,WAAS,oBAAoB,MAAsB;AAC/C,QAAI,QAAQ,GAAG,UAAU;AACzB,UAAM,OAAO,CAAC,OAAqB;AAtCvC,UAAA,IAAA;AAuCQ,YAAM,KAAK,WAAW,QAAQ,KAAA,GAAW,aAAX,OAAA,KAAuB,EAAE,CAAC,KAAK;AAC7D,UAAI,GAAI,WAAU,KAAK,IAAI,SAAS,EAAE;AACtC,YAAM,KAAK,KAAA,GAAW,SAAX,OAAA,KAAoB,GAAW;AAC1C,UAAI,OAAO,MAAM,SAAU,UAAS,EAAE;AACtC,UAAI,GAAG,SAAU,YAAW,KAAK,GAAG,SAAU,MAAK,CAAC;IACxD;AACA,SAAK,IAAI;AACT,WAAO,QAAQ;EACnB;AAEA,MAAM,KAAK,CAAC,MAAsB,KAAK,MAAM,IAAI,GAAI,IAAI;AAuBlD,WAAS,gBAAgB,GAAqC,IAA8C;AAC/G,QAAI,CAAC,MAAM,MAAM,UAAa,MAAM,KAAM,QAAO;AACjD,QAAI,OAAO,MAAM,SAAU,QAAO,IAAI;AACtC,UAAM,IAAI;AACV,QAAI,OAAO,EAAE,UAAU,SAAU,QAAOd,eAAAC,gBAAA,CAAA,GAAK,CAAA,GAAL,EAAQ,OAAO,EAAE,QAAQ,GAAG,CAAA;AACpE,QAAI,MAAM,QAAQ,EAAE,SAAS,EAAG,QAAOD,eAAAC,gBAAA,CAAA,GAAK,CAAA,GAAL,EAAQ,WAAW,EAAE,UAAU,IAAI,CAAA,MAAMD,eAAAC,gBAAA,CAAA,GAAK,CAAA,GAAL,EAAQ,QAAQ,OAAO,EAAE,KAAK,KAAK,KAAK,GAAG,CAAA,CAAE,EAAE,CAAA;AAC/H,WAAO;EACX;AAQO,WAAS,uBAAuB,OAAe,MAAoC;AAvF1F,QAAA;AAwFI,QAAI,KAAK,iBAAiB,OAAQ,QAAO,EAAE,GAAG,OAAO,YAAY,EAAE;AACnE,UAAM,UAAU,kBAAkB,KAAK;AACvC,QAAI,CAAC,WAAW,QAAQ,UAAU,QAAQ,eAAe,EAAG,QAAO,EAAE,GAAG,OAAO,YAAY,EAAE;AAE7F,UAAM,IAAI,QAAQ;AAClB,UAAM,SAAS,qBAAqB;AACpC,UAAM,KAAK,SAAS,KAAK,WAAW;AACpC,UAAM,WAAW,SAAS,KAAK,UAAU,EAAE,SAAQ,KAAA,KAAK,YAAL,OAAA,KAAgB;AAKnE,UAAM,gBAAgB,KAAK,IAAI,GAAG,CAAC,GAAG,GAAG;AACzC,UAAM,cAAc,KAAK,IAAI,GAAG,GAAG,MAAM,WAAW,CAAC;AACrD,UAAM,WAAW,gBAAgB,IAAI,gBAAgB,SAAS;AAC9D,UAAM,SAAS,cAAc,IAAI,cAAc,SAAS;AACxD,QAAI,UAAU,KAAK,YAAY,EAAG,QAAO,EAAE,GAAG,OAAO,YAAY,EAAE;AAEnE,UAAM,IAAI,QAAQ,iBAAiB,CAAC;AACpC,UAAM,IAAI,QAAQ,iBAAiB,CAAC;AACpC,QAAI,IAAI;AACR,QAAI,WAAW,GAAG;AACd,YAAM,KAAK,EAAE,IAAI,KAAK,IAAI,EAAE,KAAK,IAAI,UAAU,KAAK,EAAE,IAAI,KAAK,IAAI,EAAE,KAAK,IAAI;AAG9E,YAAM,OAAO,MAAM,QAAQ,qCAAqC,EAAE;AAClE,UAAI,MAAM,GAAG,EAAE,IAAI,MAAM,GAAG,EAAE,IAAI,MAAM,GAAG,EAAE,CAAC,IAAI,MAAM,GAAG,EAAE,CAAC,IAAI;IACtE;AACA,QAAI,SAAS,GAAG;AACZ,YAAM,KAAK,EAAE,IAAI,KAAK,IAAI,EAAE,KAAK,IAAI,QAAQ,KAAK,EAAE,IAAI,KAAK,IAAI,EAAE,KAAK,IAAI;AAC5E,WAAK,MAAM,GAAG,EAAE,IAAI,MAAM,GAAG,EAAE;IACnC;AAEA,WAAO,EAAE,GAAG,YAAY,SAAS;EACrC;AAoBO,WAAS,oBACZ,MACA,IACA,KACM;AAlJV,QAAA;AAmJI,QAAI,CAAC,MAAM,OAAO,GAAG,SAAS,YAAY,CAAC,GAAG,KAAM,QAAO;AAE3D,UAAM,SAAS,MAAM,KAAK,OAAO;AACjC,UAAM,EAAE,GAAG,WAAW,IAAI,uBAAuB,GAAG,MAAM;MACtD,cAAc,GAAG;MAAc,aAAa,GAAG;MAC/C,YAAY,GAAG;MAAY,SAAS,oBAAoB,IAAI;IAChE,CAAC;AACD,QAAI,KAAK,KAAK,EAAE,MAAM,QAAQ,IAAI,QAAQ,EAAE,CAAC;AAE7C,UAAM,WAAmB;MACrB,MAAM;MACN,MAAM,MAAM;MACZ,WAAU,KAAA,KAAK,aAAL,OAAA,KAAiB,CAAC;IAChC;AACA,QAAI,GAAG,iBAAiB,OAAW,UAAS,eAAe,GAAG;AAC9D,QAAI,GAAG,WAAW,OAAiB,UAAS,SAAS,GAAG;AACxD,QAAI,GAAG,YAAY,OAAgB,UAAS,UAAU,GAAG;AAGzD,0BAAsB,UAAU,eAAe,gBAAgB,GAAG,aAAa,UAAU,CAAC;AAC1F,0BAAsB,UAAU,cAAe,GAAG,UAAU;AAE5D,SAAK,WAAW,CAAC,QAAQ;AACzB,WAAO;EACX;AAOA,WAAS,sBAAsB,MAAc,UAAkB,KAA6C;AACxG,QAAI,QAAQ,UAAa,QAAQ,KAAM;AAEvC,QAAI,OAAO,QAAQ,UAAU;AACzB,WAAK,QAAQ,IAAI,OAAO,GAAG;AAC3B;IACJ;AACA,QAAI,OAAO,QAAQ,YAAY,QAAQ,MAAM;AACzC,YAAM,MAAM;AACZ,UAAI,MAAM,QAAQ,IAAI,SAAS,GAAG;AAC9B,cAAM,cAAc,KAAK,WAAW,OAAO,KAAK,YAAY,YAAY,CAAC,MAAM,QAAQ,KAAK,OAAO,IAAI,KAAK,UAAU;AACtH,cAAM,UAA+BA,gBAAA,CAAA,GAAM,eAAe,CAAC,CAAA;AAC3D,cAAM,QAAuD,EAAE,WAAW,IAAI,UAAU;AACxF,YAAI,IAAI,SAAS,OAAW,OAAM,OAAO,IAAI;AAC7C,gBAAQ,QAAQ,IAAI;AACpB,aAAK,UAAU;AACf;MACJ;AACA,UAAI,OAAO,IAAI,UAAU,UAAU;AAC/B,aAAK,QAAQ,IAAI,OAAO,IAAI,KAAK;AACjC;MACJ;IACJ;EACJ;AC7KO,MAAM,qBAA2C,CAAC,MAAM,OAAO,aAAa;AAC/E,UAAM,OAA6B,EAAE,KAAK;AAC1C,eAAW,KAAK,MAAO,KAAI,MAAM,CAAC,MAAM,OAAW,MAAK,CAAC,IAAI,MAAM,CAAC;AACpE,UAAM,MAAM,MAAM,QAAQ,QAAQ,IAAI,SAAS,OAAO,CAAA,MAAK,KAAK,IAAI,IAAK,YAAY,OAAO,CAAC,QAAQ,IAAI,CAAC;AAC1G,QAAI,IAAI,OAAQ,MAAK,WAAW;AAChC,WAAO;EACX;ACfA,WAAS,IAAI,GAAW,UAA0B;AAE9C,WAAO,KAAK,MAAM,CAAC,MAAM,IAAI,KAAK,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,QAAQ;EACxE;AAIA,WAAS,KAAK,MAAqB,UAA0B;AACzD,QAAI,IAAI;AACR,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AAClC,YAAMC,OAAM,IAAI,KAAK,CAAC,GAAG,QAAQ;AACjC,UAAI,IAAI,KAAKA,KAAI,WAAW,CAAC,MAAM,GAAc,MAAK;AACtD,WAAKA;IACT;AACA,WAAO;EACX;AAEA,WAAS,MAAM,GAAW,GAAW,GAA6B;AAC9D,WAAO,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;EAClE;AAEA,MAAM,WAAW;AAMV,WAAS,kBAAkB,GAAW,GAAW,WAAmB,GAAW;AAClF,UAAM,SAAwB,CAAC;AAC/B,QAAI;AACJ,aAAS,YAAY;AACrB,YAAQ,QAAQ,SAAS,KAAK,CAAC,OAAO,KAAM,QAAO,KAAK,MAAM,CAAC,CAAC;AAEhE,QAAI,MAAM;AACV,QAAI,IAAI;AACR,UAAMK,OAAM,MAAc,WAAW,OAAO,GAAG,CAAC;AAEhD,WAAO,IAAI,OAAO,QAAQ;AACtB,YAAM,MAAM,OAAO,GAAG;AACtB,UAAI,QAAQ,OAAO,QAAQ,KAAK;AAC5B,cAAM,CAAC,GAAG,CAAC,IAAI,MAAM,GAAGA,KAAI,GAAGA,KAAI,CAAC;AACpC,eAAO,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,QAAQ;MACtC,WAAW,QAAQ,KAAK;AACpB,cAAM,CAAC,IAAI,EAAE,IAAI,MAAM,GAAGA,KAAI,GAAGA,KAAI,CAAC;AACtC,cAAM,CAAC,IAAI,EAAE,IAAI,MAAM,GAAGA,KAAI,GAAGA,KAAI,CAAC;AACtC,cAAM,CAAC,GAAG,CAAC,IAAI,MAAM,GAAGA,KAAI,GAAGA,KAAI,CAAC;AACpC,eAAO,MAAM,KAAK,CAAC,IAAI,IAAI,IAAI,IAAI,GAAG,CAAC,GAAG,QAAQ;MACtD,WAAW,QAAQ,KAAK;AACpB,cAAM,CAAC,IAAI,EAAE,IAAI,MAAM,GAAGA,KAAI,GAAGA,KAAI,CAAC;AACtC,cAAM,CAAC,GAAG,CAAC,IAAI,MAAM,GAAGA,KAAI,GAAGA,KAAI,CAAC;AACpC,eAAO,MAAM,KAAK,CAAC,IAAI,IAAI,GAAG,CAAC,GAAG,QAAQ;MAC9C,WAAW,QAAQ,OAAO,QAAQ,KAAK;AACnC,eAAO;MACX;IAEJ;AACA,WAAO;EACX;ACrCA,MAAM,oBAAoB;AAG1B,MAAM,iBAAwC;IAC1C;IAAc;IAAY;IAAc;IAAa;IACrD;IAAiB;IAAe;IAAkB;IAClD;IAAc;IAAK;IAAK;IAAM;IAAM;IACpC;IAAQ;IAAU;IAAe;IACjC;IAAW;IAAmB;EAClC;AAyBA,WAAS,SAAS,GAAgC;AAC9C,QAAI,OAAO,MAAM,SAAU,QAAO;AAClC,QAAI,OAAO,MAAM,UAAU;AAAE,YAAM,IAAI,WAAW,CAAC;AAAG,aAAO,MAAM,CAAC,IAAI,SAAY;IAAG;AACvF,WAAO;EACX;AAEA,WAAS,IAAI,GAAgC;AACzC,WAAO,OAAO,MAAM,WAAW,IAAI;EACvC;AAEA,WAASQ,cAAa,MAAc,QAAsB;AAnF1D,QAAA,IAAA,IAAA,IAAA,IAAA,IAAA,IAAA;AAoFI,WAAO;MACH,aAAY,KAAA,IAAI,KAAK,UAAU,MAAnB,OAAA,KAAwB,OAAO;MAC3C,WAAU,KAAA,SAAS,KAAK,QAAQ,MAAtB,OAAA,KAA2B,OAAO;MAC5C,OAAM,KAAA,KAAK,SAAL,OAAA,KAAa,OAAO;MAC1B,SAAQ,KAAA,KAAK,WAAL,OAAA,KAAe,OAAO;MAC9B,cAAa,KAAA,KAAK,gBAAL,OAAA,KAAoB,OAAO;MACxC,gBAAe,KAAA,SAAS,KAAK,aAAa,MAA3B,OAAA,KAAgC,OAAO;MACtD,cAAa,KAAA,SAAS,KAAK,WAAW,MAAzB,OAAA,KAA8B,OAAO;IACtD;EACJ;AAEA,WAAS,YAAY,MAAqB;AA/F1C,QAAA,IAAA,IAAA;AAgGI,WAAO;MACH,YAAY,IAAI,KAAK,UAAU;MAC/B,WAAU,KAAA,SAAS,KAAK,QAAQ,MAAtB,OAAA,KAA2B;MACrC,MAAM,KAAK;MACX,QAAQ,KAAK;MACb,aAAa,KAAK;MAClB,gBAAe,KAAA,SAAS,KAAK,aAAa,MAA3B,OAAA,KAAgC;MAC/C,cAAa,KAAA,SAAS,KAAK,WAAW,MAAzB,OAAA,KAA8B;IAC/C;EACJ;AAEA,WAAS,QAAQ,GAAiB;AAC9B,UAAM,IAAW,CAAC;AAClB,QAAI,EAAE,SAAS,OAAW,GAAE,OAAO,EAAE;AACrC,QAAI,EAAE,WAAW,OAAW,GAAE,SAAS,EAAE;AACzC,QAAI,EAAE,gBAAgB,OAAW,GAAE,cAAc,EAAE;AACnD,WAAO;EACX;AAEA,WAAS,aAAa,GAAU,QAAqC,UAAmC,UAAmD;AAnH3J,QAAA;AAoHI,UAAM,KAAK,EAAE,aAAa,OAAO,EAAE,UAAU,IAAI;AACjD,QAAI,CAAC,GAAI,aAAA,OAAA,SAAA,SAAU,KAAK,uCAAsC,KAAA,EAAE,eAAF,OAAA,KAAgB,MAAM,GAAA;AACpF,WAAO;EACX;AAEA,WAAS,WAAW,QAA8D;AAC9E,UAAM,QAAQ,OAAO,KAAK,MAAM;AAChC,WAAO,MAAM,WAAW,IAAI,OAAO,MAAM,CAAC,CAAC,IAAI;EACnD;AAKA,MAAM,2BAA2B;AASjC,WAAS,kBAAkB,WAAmB,UAA0B;AACpE,QAAI,aAAa,KAAK,YAAY,EAAG,QAAO;AAC5C,UAAM,QAAQ;AACd,UAAM,KAAK,YAAY,OAAO,KAAK,aAAa,IAAI;AACpD,UAAM,KAAK,CAAC,YAAY,IAAI;AAC5B,UAAM,KAAK,KAAK,IAAI,KAAK,CAAC;AAC1B,UAAM,IAAI,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,EAAE,IAAI,IAAI;AAC7C,UAAM,QAAQ,MAAM,KAAK,QAAQ,KAAK,QAAQ,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK;AACpF,QAAI,MAAM,IAAI,KAAK,MAAM,IAAI,EAAG,QAAO;AACvC,UAAM,MAAM,KAAK,GAAG,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,MAAM,KAAK;AAEvD,WAAO,QAAQ,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM,MAAM;EACnH;AAKO,WAAS,+BAAwC,MAAc,MAAkC;AA3JxG,QAAA,IAAA,IAAA,IAAA;AA4JI,UAAM,EAAE,QAAQ,SAAS,oBAA0C,SAAS,IAAI;AAChF,UAAM,WAAW,WAAW,MAAM;AAElC,UAAM,MAAM,EAAE,IAAG,KAAA,SAAS,KAAK,CAAC,MAAf,OAAA,KAAoB,GAAG,IAAG,KAAA,SAAS,KAAK,CAAC,MAAf,OAAA,KAAoB,EAAE;AACjE,UAAM,aAAuF,CAAC;AAC9F,UAAM,QAA+C,CAAC,EAAE,OAAO,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;AAClF,QAAI,OAAO;AAEX,UAAM,cAAc,CAAC,SAAiB,MAAmB;AApK7D,UAAAX;AAqKQ,YAAM,KAAK,aAAa,GAAG,QAAQ,UAAU,QAAQ;AACrD,YAAM,OAAM,MAAA,OAAA,SAAA,GAAI,eAAc;AAC9B,YAAM,QAAQ,EAAE,WAAW;AAC3B,YAAM,YAAWA,MAAA,MAAA,OAAA,SAAA,GAAI,WAAJ,OAAAA,MAAc,MAAM;AACrC,YAAM,QAAQ,QAAQ,CAAC;AACvB,eAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACrC,cAAM,KAAK,QAAQ,OAAO,CAAC;AAC3B,cAAM,IAAI,MAAA,OAAA,SAAA,GAAI,OAAO,EAAA;AACrB,YAAI,KAAK,EAAE,GAAG;AACV,qBAAW,KAAK,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC,OAAO,GAAG,GAAG,OAAO,IAAI,GAAG,IAAI,CAAC,GAAG,OAAO,MAAM,GAAG,IAAI,GAAG,GAAG,IAAI,GAAG,MAAM,CAAC;AAC9G,cAAI,KAAK,EAAE,QAAQ;QACvB,WAAW,KAAK,KAAK,EAAE,GAAG;AAGtB,gBAAM,QAAS,KAAK,EAAE,QAAQ,IAAK,EAAE,QAAQ,2BAA2B;AACxE,qBAAW,KAAK,EAAE,QAAQ,kBAAkB,OAAO,QAAQ,GAAG,GAAG,CAAC,OAAO,GAAG,GAAG,OAAO,IAAI,GAAG,IAAI,CAAC,GAAG,OAAO,MAAM,GAAG,IAAI,GAAG,GAAG,IAAI,GAAG,MAAM,CAAC;AAC7I,cAAI,KAAK,QAAQ;QACrB,OAAO;AACH,cAAI,MAAM,IAAI,EAAE,QAAQ,KAAK;QACjC;AACA,YAAI,KAAK,EAAE,iBAAiB,OAAO,MAAM,EAAE,cAAc;AACzD,cAAM,IAAI,EAAE,MAAM,IAAI;MAC1B;IACJ;AAEA,UAAM,OAAO,CAAC,IAAY,gBAA6B;AA9L3D,UAAAA,KAAAC,KAAAW,KAAAC;AA+LQ,YAAM,IAAIF,cAAa,IAAI,WAAW;AACtC,YAAM,IAAI,SAAS,GAAG,CAAC;AACvB,YAAM,IAAI,SAAS,GAAG,CAAC;AACvB,UAAI,MAAM,QAAW;AAAE,YAAI,IAAI;AAAG,eAAO,MAAM;AAAQ,cAAM,KAAK,EAAE,OAAO,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;MAAG;AACjG,UAAI,MAAM,OAAW,KAAI,IAAI;AAC7B,UAAI,MAAKX,MAAA,SAAS,GAAG,EAAE,MAAd,OAAAA,MAAmB;AAC5B,UAAI,MAAKC,MAAA,SAAS,GAAG,EAAE,MAAd,OAAAA,MAAmB;AAC5B,YAAM,WAAUW,MAAA,IAAI,GAAG,SAAS,CAAC,MAAjB,OAAAA,MAAsB,IAAI,GAAG,iBAAiB,CAAC;AAK/D,UAAI,WAAW,GAACC,MAAA,GAAG,aAAH,OAAA,SAAAA,IAAa,QAAQ,aAAY,SAAS,CAAC;AAC3D,UAAI,GAAG,SAAU,YAAW,MAAM,GAAG,SAAU,MAAK,IAAI,CAAC;IAC7D;AAEA,UAAM,YAAY,YAAY,IAAI;AAClC,QAAI,KAAK,SAAU,YAAW,MAAM,KAAK,SAAU,MAAK,IAAI,SAAS;AACrE,UAAM,eAAc,KAAA,IAAI,KAAK,SAAS,CAAC,MAAnB,OAAA,KAAwB,IAAI,KAAK,iBAAiB,CAAC;AACvE,QAAI,eAAe,GAAC,KAAA,KAAK,aAAL,OAAA,SAAA,GAAe,QAAQ,aAAY,aAAa,SAAS;AAG7E,UAAM,SAAS,IAAI,KAAK,UAAU;AAClC,QAAI,WAAW,YAAY,WAAW,OAAO;AACzC,iBAAW,KAAK,YAAY;AACxB,cAAM,IAAI,MAAM,EAAE,IAAI,EAAE,MAAM,MAAM,EAAE,IAAI,EAAE;AAC5C,cAAM,QAAQ,WAAW,WAAW,CAAC,IAAI,IAAI,CAAC;AAC9C,UAAE,IAAI,CAAC,EAAE,OAAO,GAAG,GAAG,EAAE,OAAO,EAAE,IAAI,OAAO,EAAE,CAAC;MACnD;IACJ;AAEA,WAAO,QAAQ,MAAM,WAAW,YAAY,QAAQ,QAAQ,GAAG,MAAM;EACzE;AAsLA,WAAS,sBAAsB,MAAc,QAAqC,UAAmC,UAAsE;AACvL,UAAM,QAA0B,CAAC;AACjC,QAAI,MAAM;AACV,UAAM,OAAO,CAAC,IAAY,gBAA6B;AAxZ3D,UAAA,IAAA,IAAA;AAyZQ,YAAM,IAAIC,cAAa,IAAI,WAAW;AACtC,YAAM,WAAU,KAAA,IAAI,GAAG,SAAS,CAAC,MAAjB,OAAA,KAAsB,IAAI,GAAG,iBAAiB,CAAC;AAG/D,UAAI,WAAW,GAAC,KAAA,GAAG,aAAH,OAAA,SAAA,GAAa,SAAQ;AACjC,cAAM,KAAK,aAAa,GAAG,QAAQ,UAAU,QAAQ;AACrD,YAAI,IAAI;AACJ,gBAAM,QAAQ,EAAE,WAAW,GAAG;AAC9B,gBAAM,YAAW,KAAA,GAAG,WAAH,OAAA,KAAa,MAAM,GAAG;AACvC,gBAAM,QAAQ,QAAQ,CAAC;AACvB,mBAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACrC,kBAAM,KAAK,QAAQ,OAAO,CAAC;AAC3B,kBAAM,IAAI,GAAG,OAAO,EAAE;AACtB,gBAAI,KAAK,EAAE,GAAG;AACV,oBAAM,WAAW,EAAE,QAAQ;AAC3B,oBAAM,KAAK,EAAE,QAAQ,EAAE,GAAG,SAAS,EAAE,OAAO,OAAO,OAAO,SAAS,MAAM,WAAW,EAAE,CAAC;AACvF,qBAAO;YACX,WAAW,KAAK,KAAK,EAAE,GAAG;AAEtB,oBAAM,MAAO,KAAK,EAAE,QAAQ,IAAK,EAAE,QAAQ,2BAA2B,GAAG;AACzE,oBAAM,SAAS,MAAM;AACrB,oBAAM,KAAK,EAAE,QAAQ,kBAAkB,KAAK,QAAQ,GAAG,SAAS,KAAK,OAAO,OAAO,SAAS,MAAM,SAAS,EAAE,CAAC;AAC9G,qBAAO;YACX,OAAO;AACH,sBAAQ,IAAI,EAAE,QAAQ,KAAK;YAC/B;AACA,mBAAO,EAAE,iBAAiB,OAAO,MAAM,EAAE,cAAc;UAC3D;QACJ;MACJ;AACA,UAAI,GAAG,SAAU,YAAW,MAAM,GAAG,SAAU,MAAK,IAAI,CAAC;IAC7D;AACA,SAAK,MAAM,YAAY,IAAI,CAAC;AAC5B,WAAO,EAAE,OAAO,OAAO,IAAI;EAC/B;AAMA,WAAS,YAAY,SAAsB,MAAc,OAAe,SAAiB,OAAO,GAAW;AACvG,UAAM,EAAE,GAAG,GAAG,MAAM,IAAI,QAAQ,iBAAiB,IAAI;AACrD,UAAM,MAAM,KAAK,IAAI,KAAK,GAAG,MAAM,KAAK,IAAI,KAAK,GAAG,KAAK,UAAU;AACnE,WAAO,CAAC,QAAQ,KAAK,QAAQ,KAAK,CAAC,QAAQ,KAAK,QAAQ,KAAK,IAAI,QAAQ,MAAM,KAAK,OAAO,KAAK,IAAI,QAAQ,MAAM,KAAK,OAAO,GAAG;EACrI;AAQA,WAAS,qBAAqB,MAA+C;AA7c7E,QAAA,IAAA,IAAA;AA8cI,WAAO;MACH,SAAQ,KAAA,SAAS,KAAK,CAAC,MAAf,OAAA,KAAoB,OAAM,KAAA,SAAS,KAAK,EAAE,MAAhB,OAAA,KAAqB;MACvD,OAAM,KAAA,SAAS,KAAK,EAAE,MAAhB,OAAA,KAAqB;IAC/B;EACJ;AAEO,WAAS,8BACZ,MACA,OACA,aACA,MACA,YACA,cACQ;AACR,UAAM,EAAE,QAAQ,SAAS,oBAA0C,SAAS,IAAI;AAChF,UAAM,UAAU,QAAQ,kBAAkB,KAAK,IAAI;AACnD,QAAI,CAAC,SAAS;AAAE,kBAAA,OAAA,SAAA,SAAU,KAAK,4CAAA;AAA+C,aAAO;IAAM;AAE3F,UAAM,WAAW,WAAW,MAAM;AAClC,UAAM,EAAE,OAAO,MAAM,IAAI,sBAAsB,MAAM,QAAQ,UAAU,QAAQ;AAC/E,QAAI,CAAC,MAAM,OAAQ,QAAO,QAAQ,MAAM,CAAC,GAAG,MAAM;AAGlD,UAAM,EAAE,OAAO,aAAa,KAAK,IAAI,qBAAqB,IAAI;AAK9D,UAAM,UAAU,WAAW,WAAW;AACtC,UAAM,UAAU,WAAW,UAAU;AACrC,UAAM,MAAM,CAAC,OAAwB,KAAK,KAAK,QAAQ,IAAK,KAAK,QAAQ;AAKzE,UAAM,SAAS,iBAAiB,UAAU,CAAC,QAAQ;AAEnD,QAAI,QAAQ,YAAY,QAAQ,UAAU;AAItC,YAAM,QAAQ,gBAAgB,QAAQ,OAAO,QAAQ,KAAK;AAC1D,YAAM,SAAS,CAAC,GAAc,MAAsB,cAAc,QAAQ,GAAG,CAAC,IAAI,IAAI,QAAQ,GAAG,CAAC,CAAC,IAAI,EAAE;AACzG,YAAM,OAAO,QAAQ,WAAW,QAAQ,OAAO,QAAQ;AACvD,aAAO,QAAQ,MAAM,uBAAuB,OAAO,SAAS,QAAQ,OAAO,MAAM,QAAQ,QAAQ,IAAI,GAAG,MAAM;IAClH;AAGA,UAAM,IAAI,IAAI,QAAQ,GAAG,CAAC,CAAC;AAC3B,UAAM,OAAO,cAAc,QAAQ,GAAG,CAAC;AACvC,UAAM,aAAa,SACb,MAAM,OAAO,CAAA,MAAK;AAAE,YAAM,IAAI,OAAO,EAAE,UAAU;AAAG,aAAO,KAAK,KAAK,KAAK,QAAQ;IAAa,CAAC,IAChG;AACN,UAAM,aAA+B,WAAW,IAAI,CAAA,OAAM;MACtD,QAAQ,EAAE;MAAQ,OAAO,EAAE;MAC3B,GAAG,YAAY,SAAS,OAAO,EAAE,UAAU,GAAG,EAAE,OAAO,EAAE,SAAS,IAAI;IAC1E,EAAE;AACF,WAAO,QAAQ,MAAM,WAAW,YAAY,QAAQ,QAAQ,GAAG,MAAM;EACzE;AAOA,WAAS,WAAW,KAAiD;AA/gBrE,QAAA;AAghBI,UAAM,IAAI,eAAuB,GAAG;AACpC,QAAI,EAAE,SAAA,cAA8B,EAAE,UAAU,UAAU,GAAG;AACzD,YAAM,MAAM,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,IAAI,QAAQ,OAAO,GAAG,IAAI,KAAK,MAAM,OAAO,GAAG,IAAI,KAAK,EAAE;AAC7F,YAAM,QAAQ,IAAI,IAAI,CAAA,OAAM,OAAO,GAAG,IAAI,KAAK,CAAC;AAChD,YAAM,OAAO,IAAI,IAAI,CAAA,OAAM,OAAO,GAAG,KAAK,KAAK,CAAC;AAChD,aAAO;QACH,UAAU;QAAM;QAAO,MAAM,EAAE;QAC/B,GAAG,GAAmB;AAClB,cAAI,KAAK,MAAM,CAAC,EAAG,QAAO,KAAK,CAAC;AAChC,mBAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,gBAAI,KAAK,MAAM,CAAC,GAAG;AACf,oBAAM,OAAO,MAAM,CAAC,IAAI,MAAM,IAAI,CAAC;AACnC,oBAAM,IAAI,OAAO,KAAK,IAAI,MAAM,IAAI,CAAC,KAAK,OAAO;AACjD,qBAAO,KAAK,IAAI,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;YAClD;UACJ;AACA,iBAAO,KAAK,KAAK,SAAS,CAAC;QAC/B;MACJ;IACJ;AACA,UAAM,IAAI,EAAE,SAAA,aAA8B,QAAO,KAAA,EAAE,UAAU,CAAC,MAAb,OAAA,SAAA,GAAgB,KAAK,KAAK,IACrE,EAAE,SAAA,WAA4B,OAAO,EAAE,KAAK,KAAK,IAAK;AAC5D,WAAO,EAAE,UAAU,OAAO,OAAO,CAAC,GAAG,IAAI,MAAM,EAAE;EACrD;AAGA,WAAS,gBAAgB,GAAkB,GAAiC;AACxE,UAAM,MAAM,CAAC,GAAG,GAAG,GAAG,CAAC,EAAE,KAAK,CAAC,IAAI,OAAO,KAAK,EAAE;AACjD,UAAM,MAAqB,CAAC;AAC5B,eAAW,KAAK,IAAK,KAAI,CAAC,IAAI,UAAU,MAAM,IAAI,IAAI,SAAS,CAAC,EAAG,KAAI,KAAK,CAAC;AAC7E,WAAO;EACX;AAKA,MAAM,uBAAuB;AAC7B,MAAM,mCAAmC;AAEzC,WAAS,OAAO,GAAW,GAAmB;AAC1C,UAAM,IAAI,MAAA,IAAM,CAAA;AAChB,WAAO,KAAK,MAAM,IAAI,CAAC,IAAI;EAC/B;AASA,WAAS,uBACL,OACA,SACA,QACA,OACA,MACA,QACA,QACA,OAAO,GACC;AACR,UAAM,OAAO,KAAK,IAAI,QAAQ,cAAc,sBAAsB,GAAG;AACrE,UAAM,SAAS,CAAC,SAA0B,QAAQ,KAAK,QAAQ,QAAQ;AAEvE,UAAM,MAAgB,CAAC;AACvB,eAAW,KAAK,OAAO;AACnB,YAAM,UAAkB,CAAC,EAAE,OAAO,GAAG,GAAG,EAAE,OAAO,CAAC,EAAE,SAAS,EAAE,UAAU,IAAI,CAAC;AAC9E,YAAM,IAAI,kBAAkB,EAAE,QAAQ,OAAO;AAE7C,YAAM,WAAW,CAAC,MAAc,SAAoC;AAChE,cAAM,EAAE,GAAG,GAAG,MAAM,IAAI,QAAQ,iBAAiB,IAAI;AACrD,cAAM,MAAM,KAAK,IAAI,KAAK,GAAG,MAAM,KAAK,IAAI,KAAK;AAEjD,eAAO;UACH;UACA,OAAO;YACH;cAAA;;YAAwB,GAAG,CAAC,OAAO,IAAI,OAAO,KAAK,CAAC,GAAG,OAAO,IAAI,OAAO,KAAK,CAAC,CAAC;YAChF;cAAA;;YAAqB,GAAG,OAAO,QAAQ,MAAM,KAAK,IAAI,CAAC;UAC3D;QACJ;MACJ;AAEA,YAAM,MAAgC,CAAC;AAIvC,YAAM,QAA0C,CAAC;AACjD,YAAM,SAAS,CAAC,MAAc,SAAuB;AACjD,YAAI,KAAK,SAAS,MAAM,IAAI,CAAC;AAC7B,YAAI,OAAQ,OAAM,KAAK,EAAE,MAAM,OAAO,OAAO,IAAI,IAAI,IAAI,EAAE,CAAC;MAChE;AAEA,aAAO,OAAO,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;AACpC,eAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACnC,cAAM,KAAK,MAAM,IAAI,CAAC,GAAG,KAAK,MAAM,CAAC;AACrC,cAAM,KAAK,OAAO,GAAG,EAAE,GAAG,KAAK,OAAO,GAAG,EAAE;AAC3C,cAAM,IAAI,KAAK,IAAI,kCAAkC,KAAK,IAAI,GAAG,KAAK,KAAK,KAAK,IAAI,KAAK,EAAE,IAAI,IAAI,CAAC,CAAC;AACrG,iBAAS,IAAI,GAAG,KAAK,GAAG,KAAK;AACzB,gBAAM,IAAI,IAAI;AACd,gBAAM,IAAI,KAAK,KAAK,KAAK;AACzB,iBAAO,OAAO,GAAG,CAAC,GAAG,CAAC;QAC1B;MACJ;AAKA,gCAA0B,GAAG;AAE7B,YAAM,YAAqE,EAAE,WAAW,IAAI;AAC5F,UAAI,SAAS,OAAW,WAAU,OAAO;AACzC,YAAM,UAAgC,EAAE,UAAU;AAGlD,UAAI,UAAU,MAAM,KAAK,CAAA,MAAK,EAAE,UAAU,CAAC,GAAG;AAC1C,cAAM,KAAsE,EAAE,WAAW,MAAM;AAC/F,YAAI,SAAS,OAAW,IAAG,OAAO;AAClC,gBAAQ,UAAU;MACtB;AAEA,UAAI,KAAK,OAAO,QAAQC,eAAAC,gBAAA,EAAE,EAAA,GAAM,WAAW,EAAE,KAAK,CAAA,GAA1B,EAA6B,QAAQ,CAAA,GAAG,CAAC,CAAC,CAAC;IACvE;AACA,WAAO;EACX;AAKA,WAAS,WAAW,OAAoC;AACpD,UAAM,IAA0B,CAAC;AACjC,QAAI,MAAM,SAAS,OAAW,GAAE,OAAO,MAAM;AAC7C,QAAI,MAAM,WAAW,OAAW,GAAE,SAAS,MAAM;AACjD,QAAI,MAAM,gBAAgB,OAAW,GAAE,cAAc,MAAM;AAC3D,WAAO;EACX;AAGA,WAAS,WAAc,YAA8B,QAA4B,UAAoC;AAzpBrH,QAAA,IAAA,IAAA;AA0pBI,QAAI,CAAC,WAAW,QAAQ;AAAE,kBAAA,OAAA,SAAA,SAAU,KAAK,+BAAA;AAAkC,aAAO,CAAC;IAAG;AAEtF,UAAM,UAAU,oBAAI,IAAyC;AAC7D,eAAW,KAAK,YAAY;AAExB,YAAM,MAAM,KAAK,UAAU,EAAC,KAAA,EAAE,MAAM,SAAR,OAAA,KAAgB,OAAM,KAAA,EAAE,MAAM,WAAR,OAAA,KAAkB,OAAM,KAAA,EAAE,MAAM,gBAAR,OAAA,KAAuB,IAAI,CAAC;AACtG,YAAM,QAAQ,kBAAkB,EAAE,QAAQ,EAAE,CAAC;AAC7C,YAAM,QAAQ,QAAQ,IAAI,GAAG;AAC7B,UAAI,MAAO,OAAM,KAAK;UACjB,SAAQ,IAAI,KAAK,EAAE,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC;IACtD;AAEA,UAAM,MAAgB,CAAC;AACvB,eAAW,EAAE,OAAO,EAAE,KAAK,QAAQ,OAAO,EAAG,KAAI,KAAK,OAAO,QAAQA,gBAAA,EAAE,EAAA,GAAM,WAAW,KAAK,CAAA,GAAK,CAAC,CAAC,CAAC;AACrG,WAAO;EACX;AAIA,WAAS,QAAW,MAAc,UAAoB,QAA+B;AACjF,UAAM,SAA+B,CAAC;AACtC,eAAW,KAAK,OAAO,KAAK,IAAI,GAAG;AAC/B,UAAI,MAAM,UAAU,MAAM,cAAc,eAAe,QAAQ,CAAC,MAAM,GAAI;AAC1E,aAAO,CAAC,IAAK,KAA8B,CAAC;IAChD;AACA,QAAI,OAAO,SAAS,OAAO,OAAO,UAAU,UAAU;AAClD,YAAM,QAAQA,gBAAA,CAAA,GAAM,OAAO,KAAA;AAC3B,aAAO,MAAM,aAAa;AAC1B,UAAI,OAAO,KAAK,KAAK,EAAE,OAAQ,QAAO,QAAQ;UAAY,QAAO,OAAO;IAC5E;AACA,WAAO,OAAO,KAAK,QAAQ,QAAQ;EACvC;AAgBO,WAAS,sBAAsB,MAAc,IAA8B,KAA2B;AACzG,QAAI,EAAC,MAAA,OAAA,SAAA,GAAI,WAAW,QAAO;AAC3B,QAAI,CAAC,IAAI,QAAQ;AAAE,UAAI,SAAS,KAAK,gEAA2D;AAAG,aAAO;IAAM;AAChH,WAAO,+BAAuC,MAAM,EAAE,QAAQ,IAAI,QAAQ,UAAU,IAAI,SAAS,CAAC;EACtG;AAGO,WAAS,yBAAyB,MAAc,KAAmB,OAA2B,aAA+C,YAAmC,cAAsC;AACzN,QAAI,CAAC,IAAI,QAAQ;AAAE,UAAI,SAAS,KAAK,mCAAmC;AAAG,aAAO;IAAM;AACxF,WAAO,8BAAsC,MAAM,OAAO,aAAa,EAAE,QAAQ,IAAI,QAAQ,UAAU,IAAI,SAAS,GAAG,YAAY,YAAY;EACnJ;ACjrBO,WAAS,oBACZ,MACA,UACA,iBACA,KACM;AACN,QAAI,CAAC,SAAU,QAAO;AAEtB,UAAM,eAAe,CAAC,CAAC,SAAS;AAGhC,UAAM,cAAgC,CAAC;AACvC,UAAM,UAAU,CAAC,MAAoB;AACjC,UAAI,MAAM,QAAQ,EAAE,QAAQ,KAAK,EAAE,SAAS,SAAS,GAAG;AACpD,mBAAW,MAAM,EAAE,SAAU,SAAQ,EAAE;AACvC;MACJ;AACA,YAAM,IAAI,OAAO,EAAE,MAAM,WAAW,EAAE,IAAI,aAAa,CAAC;AACxD,UAAI,MAAM,OAAW;AACrB,YAAM,WAAW,qBAAqB,CAAC;AACvC,UAAI,CAAC,SAAS,OAAQ;AACtB,YAAM,QAAmB,EAAE,MAAM,GAAG,UAAU,CAAC,EAAE;AACjD,iBAAW,MAAM,UAAU;AACvB,cAAM,WAAW,mBAAmB,EAAE;AACtC,cAAM,SAAS,KAAK,EAAE,SAAS,IAAI,UAAU,eAAe,EAAE,CAAC;MACnE;AACA,kBAAY,KAAK,KAAK;IAC1B;AACA,YAAQ,IAAI;AAEZ,QAAI,CAAC,YAAY,OAAQ,QAAO;AAUhC,QAAI,MAAM;AACV,UAAM,YAAY,eAAe,CAAC,GAAG,WAAW,EAAE,QAAQ,IAAI;AAC9D,eAAW,SAAS,WAAW;AAC3B,iBAAW,MAAM,MAAM,UAAU;AAC7B,YAAI,CAAC,aAAc,OAAM;AACzB,WAAG,gBAAgB;AACnB,eAAO,GAAG;MACd;IACJ;AAEA,UAAM,gBAAgB;AACtB,QAAI,gBAAgB,gBAAgB,KAAO,QAAO;AAWlD,UAAM,gBAAgB,eAAuB,SAAS,MAAM;AAC5D,UAAM,aAA+B,cAAc,SAAA,WAC7C,EAAE,MAAA,UAAuB,OAAO,EAAE,IAClC;AACN,UAAM,eAAe,uBAAuB,SAAS,KAAK;AAC1D,UAAM,YAA4B,aAAa,SAAA,WACzC,EAAE,MAAA,UAAuB,OAAO,CAAC,GAAG,CAAC,EAAE,IACvC;AAEN,UAAM,eAAe,iBAAiB,UAAU;AAChD,UAAM,YAAY,aAAa,SAAS,KAAK,IAAI,GAAG,YAAY,IAAI;AACpE,UAAM,YAAY,aAAa,SAAS,KAAK,IAAI,GAAG,YAAY,IAAI;AACpE,UAAM,eAAiC,CAAC,WAAW,SAAS;AAK5D,QAAI,YAAY,WAAW,KAAK,YAAY,CAAC,EAAE,SAAS,QAAQ,YAAY,CAAC,EAAE,SAAS,WAAW,GAAG;AAClG,YAAM,QAAQ,YAAY,CAAC;AAC3B,YAAM,KAAK,MAAM,SAAS,CAAC;AAC3B,YAAM,eAAe,eAAe,gBAAgB,GAAG;AACvD,UAAI,eAAe,KAAO,QAAO;AACjC,YAAM,iBAAiB,eAAe,GAAG,gBAAgB,eAAe;AACxE,aAAO,qBAAqB,MAAM,MAAM,cAAc,gBAAgB,cAAc,YAAY,SAAS;IAC7G;AAIA,UAAM,eAAe,oBAAI,IAAoB;AAC7C,eAAW,SAAS,aAAa;AAC7B,YAAM,cAA6B,CAAC;AACpC,iBAAW,MAAM,MAAM,UAAU;AAC7B,cAAM,eAAe,eAAe,gBAAgB,GAAG;AACvD,YAAI,eAAe,KAAO;AAC1B,cAAM,iBAAiB,eAAe,GAAG,gBAAgB,eAAe;AACxE,oBAAY,KAAK,GAAG,kBAAkB,MAAM,MAAM,GAAG,SAAS,cAAc,gBAAgB,cAAc,YAAY,WAAW,GAAG,CAAC;MACzI;AACA,mBAAa,IAAI,MAAM,MAAM,gBAAgB,MAAM,MAAM,WAAW,CAAC;IACzE;AAEA,UAAM,OAAO,CAAC,MAAsB;AAChC,YAAM,IAAI,aAAa,IAAI,CAAC;AAC5B,UAAI,EAAG,QAAO;AACd,UAAI,MAAM,QAAQ,EAAE,QAAQ,KAAK,EAAE,SAAS,SAAS,GAAG;AACpD,eAAOC,eAAAC,gBAAA,CAAA,GAAK,CAAA,GAAL,EAAQ,UAAU,EAAE,SAAS,IAAI,IAAI,EAAE,CAAA;MAClD;AACA,aAAO;IACX;AACA,WAAO,KAAK,IAAI;EACpB;AAeA,WAAS,gBAAgB,MAAc,UAAiC;AACpE,UAAM,UAAkBD,eAAAC,gBAAA,CAAA,GAAK,IAAA,GAAL,EAAW,MAAM,KAAK,SAAS,CAAA;AACvD,WAAO,QAAQ;AACf,WAAO,QAAQ;AACf,WAAO,QAAQ;AACf,WAAO,QAAQ;AACf,WAAO;EACX;AAOA,WAAS,kBACL,MACA,SACA,cACA,gBACA,cACA,YACA,WACA,KACa;AACb,UAAM,qBAAqB,uBAAuB,gBAAgB,cAAc,YAAY;AAC5F,UAAM,mBAAmB,qBAAqB,cAAc,YAAY;AAExE,UAAM,iBAAiB,gBAAgB,YAAY,kBAAkB;AACrE,UAAM,gBAAgB,gBAAgB,WAAW,gBAAgB;AACjE,UAAM,oBAAoB,wBAAwB,SAAS;AAE3D,UAAM,OAAO,gBAAgB,OAAO;AAKpC,UAAM,OAAO,gBAAgB,IAAI;AACjC,cAAU,MAAM,mBAAmB,aAAa;AAChD,cAAU,MAAM,oBAAoB,cAAc;AAClD,cAAU,MAAM,iBAAiB,iBAAiB;AAElD,WAAO,CAAC,IAAI;EAChB;AAKA,WAAS,qBACL,MACA,cACA,gBACA,cACA,YACA,WACM;AACN,UAAM,qBAAqB,uBAAuB,gBAAgB,cAAc,YAAY;AAC5F,UAAM,mBAAmB,qBAAqB,cAAc,YAAY;AAExE,UAAM,OAAeA,gBAAA,CAAA,GAAK,IAAA;AAC1B,WAAO,KAAK;AACZ,cAAU,MAAM,mBAAmB,gBAAgB,WAAW,gBAAgB,CAAC;AAC/E,cAAU,MAAM,oBAAoB,gBAAgB,YAAY,kBAAkB,CAAC;AACnF,cAAU,MAAM,iBAAiB,wBAAwB,SAAS,CAAC;AACnE,WAAO;EACX;AAKA,WAAS,gBAAgB,MAAsB;AAC3C,WAAO,EAAE,MAAM,QAAQ,GAAG,KAAK;EACnC;AAOA,MAAM,mBAAmB;AAGzB,WAAS,uBACL,gBACA,cACA,cAC6B;AAC7B,UAAM,CAAC,MAAM,IAAI,oBAAoB,YAAY;AACjD,WAAO,CAAA,cAAa,gBAAgB,CAAC,YAAY,SAAS,kBAAkB;EAChF;AAIA,WAAS,qBACL,cACA,cACiC;AACjC,UAAM,CAAC,QAAQ,MAAM,IAAI,oBAAoB,YAAY;AACzD,UAAM,UAAU,SAAS,SAAS;AAClC,WAAO,CAAC,aAAmB;AACvB,YAAM,IAAI,MAAM,SAAS,CAAC,GAAG,GAAG,CAAC;AACjC,YAAM,IAAI,MAAM,SAAS,CAAC,GAAG,GAAG,CAAC;AACjC,YAAM,OAAO,KAAK,IAAI,GAAG,CAAC;AAC1B,YAAM,OAAO,KAAK,IAAI,GAAG,CAAC;AAC1B,YAAM,MAAqB,CAAC,CAAC;AAC7B,UAAI,MAAM;AACV,eAAS,IAAI,GAAG,IAAI,SAAS,KAAK;AAC9B,YAAI,KAAK,MAAM,OAAO,YAAY;AAClC,YAAI,MAAM,OAAO,QAAQ,YAAY;AACrC,eAAO,IAAI,QAAQ;MACvB;AACA,UAAI,KAAK,MAAM,gBAAgB;AAC/B,aAAO;IACX;EACJ;AAGA,WAAS,oBAAoB,cAAkD;AAC3E,WAAO;MACH,KAAK,MAAM,KAAK,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;MACvD,KAAK,KAAK,KAAK,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;IAC1D;EACJ;AAYA,WAAS,iBAAiB,GAAoC;AArS9D,QAAA;AAsSI,QAAI,EAAE,SAAA,SAA0B,QAAO,CAAC;AACxC,QAAI,EAAE,SAAA,SAA0B,QAAO,CAAC,EAAE,KAAK;AAC/C,UAAM,MAAqB,CAAC;AAC5B,eAAW,MAAM,EAAE,WAAW;AAC1B,YAAM,KAAI,KAAA,GAAG,UAAH,OAAA,KAAY,GAAG;AACzB,UAAI,OAAO,MAAM,SAAU,KAAI,KAAK,CAAC;IACzC;AACA,WAAO;EACX;AAEA,WAAS,gBAA2B,MAAqB,KAA6C;AAClG,QAAI,KAAK,SAAA,SAA0B,QAAO;AAC1C,QAAI,KAAK,SAAA,SAA0B,QAAO,EAAE,MAAA,UAAuB,OAAO,IAAI,KAAK,KAAK,EAAE;AAC1F,WAAO;MACH,MAAA;MACA,WAAW,KAAK,UAAU,IAAI,CAAA,OAAG;AArTzC,YAAA,IAAA,IAAA,IAAA;AAqT6C,eAAA;UACjC,OAAM,MAAA,KAAA,GAAG,SAAH,OAAA,KAAW,GAAG,MAAd,OAAA,KAAmB;UACzB,OAAO,KAAK,KAAA,GAAG,UAAH,OAAA,KAAY,GAAG,CAAS;UACpC,SAAQ,KAAA,GAAG,WAAH,OAAA,KAAa,GAAG;QAC5B;MAAA,CAAE;MACF,MAAM,KAAK;IACf;EACJ;AAEA,WAAS,UAAa,MAAc,UAAkB,MAA+B;AA9TrF,QAAA,IAAA;AA+TI,QAAI,CAAC,KAAM;AACX,QAAI,KAAK,SAAA,UAA0B;AAC/B,WAAK,QAAQ,IAAI,KAAK;AACtB;IACJ;AACA,UAAM,cAAc,KAAK,WAAW,OAAO,KAAK,YAAY,YAAY,CAAC,MAAM,QAAQ,KAAK,OAAO,IAAI,KAAK,UAAU;AACtH,UAAM,UAA+BA,gBAAA,CAAA,GAAM,eAAe,CAAC,CAAA;AAC3D,UAAM,QAAmE,EAAE,WAAW,KAAK,UAAU;AACrG,QAAI,KAAK,SAAS,OAAW,OAAM,OAAO,KAAK;AAC/C,YAAQ,QAAQ,IAAI;AACpB,SAAK,UAAU;AASf,UAAM,UAAU,KAAK,UAAU,CAAC;AAChC,QAAI,aAAY,KAAA,QAAQ,UAAR,OAAA,KAAkB,QAAgB,OAAO,QAAW;AAChE,WAAK,QAAQ,KAAI,KAAA,QAAQ,UAAR,OAAA,KAAkB,QAAgB;IACvD;EACJ;AAIA,MAAM,kBAAkB;AAOxB,WAAS,wBAAwB,WAAmD;AAjWpF,QAAA,IAAA,IAAA,IAAA,IAAA,IAAA;AAkWI,UAAM,OAAO,CAAC,MAAqB,EAAE,CAAC,MAAM,EAAE,CAAC;AAE/C,QAAI,UAAU,SAAA,SAA0B,QAAO;AAC/C,QAAI,UAAU,SAAA,SAA0B,QAAO,KAAK,UAAU,KAAK,IAAI,EAAE,MAAA,UAAuB,OAAO,EAAE,IAAI;AAE7G,UAAM,MAAM,UAAU;AACtB,QAAI,UAAU;AACd,QAAI,UAAU;AACd,eAAW,MAAM,KAAK;AAClB,UAAI,MAAM,KAAA,GAAG,UAAH,OAAA,KAAY,GAAG,CAAU,EAAG,WAAU;UAC3C,WAAU;IACnB;AACA,QAAI,CAAC,QAAS,QAAO;AACrB,QAAI,QAAS,QAAO,EAAE,MAAA,UAAuB,OAAO,EAAE;AAItD,UAAM,MAAyB,CAAC;AAChC,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACjC,YAAM,KAAK,IAAI,CAAC;AAChB,YAAM,SAAS,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI;AACpC,YAAM,SAAS,IAAI,IAAI,SAAS,IAAI,IAAI,IAAI,CAAC,IAAI;AACjD,YAAM,KAAI,MAAA,KAAA,GAAG,SAAH,OAAA,KAAW,GAAG,MAAd,OAAA,KAAmB;AAC7B,YAAM,WAAW,MAAM,KAAA,GAAG,UAAH,OAAA,KAAY,GAAG,CAAU;AAChD,YAAM,WAAW,SAAS,YAAY,MAAM,KAAA,OAAO,UAAP,OAAA,KAAgB,OAAO,CAAU,IAAI;AACjF,YAAM,WAAW,SAAS,YAAY,MAAM,KAAA,OAAO,UAAP,OAAA,KAAgB,OAAO,CAAU,IAAI;AAEjF,UAAI,YAAY,CAAC,UAAU;AACvB,YAAI,KAAK,EAAE,MAAM,GAAG,OAAO,EAAE,CAAC;AAC9B,YAAI,KAAK,EAAE,MAAM,IAAI,iBAAiB,OAAO,EAAE,CAAC;MACpD,WAAW,CAAC,YAAY,UAAU;AAC9B,YAAI,KAAK,EAAE,MAAM,IAAI,iBAAiB,OAAO,EAAE,CAAC;AAChD,YAAI,KAAK,EAAE,MAAM,GAAG,OAAO,EAAE,CAAC;MAClC;IACJ;AACA,QAAI,IAAI,UAAU,EAAG,QAAO;AAC5B,WAAO,EAAE,MAAA,YAAyB,WAAW,IAAI;EACrD;AAYA,WAAS,uBAAuB,KAAqD;AACjF,UAAM,IAAI,eAAqB,GAAG;AAClC,QAAI,EAAE,SAAA,WAA4B,QAAO;AAEzC,UAAM,MAAuB,EAAE,UAAU,IAAI,CAAA,OAAG;AAvZpD,UAAA,IAAA,IAAA,IAAA;AAuZwD,aAAA;QAChD,OAAM,MAAA,KAAA,GAAG,SAAH,OAAA,KAAW,GAAG,MAAd,OAAA,KAAmB;QACzB,QAAQ,KAAA,GAAG,UAAH,OAAA,KAAY,GAAG;QACvB,SAAQ,KAAA,GAAG,WAAH,OAAA,KAAa,GAAG;MAC5B;IAAA,CAAE;AAEF,UAAM,aAAa,IAAI,KAAK,CAAA,OAAM,GAAG,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;AAC3D,QAAI,CAAC,YAAY;AACb,aAAO;QACH,MAAA;QACA,WAAW,IAAI,IAAI,CAAA,QAAO,EAAE,MAAM,GAAG,MAAM,OAAO,GAAG,OAAO,QAAQ,GAAG,OAAO,EAAE;MACpF;IACJ;AAEA,UAAM,gBAA+B,CAAC;AACtC,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACjC,YAAM,OAAO,IAAI,IAAI,CAAC;AACtB,YAAM,MAAM,IAAI,CAAC;AACjB,YAAM,QAAQ,KAAK,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC;AAC1C,YAAM,OAAO,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC;AACvC,UAAI,QAAQ,OAAO,GAAG;AAClB,cAAM,IAAI,0BAA0B,MAAM,GAAG;AAC7C,YAAI,MAAM,QAAQ,IAAI,KAAK,QAAQ,IAAI,IAAI,MAAM;AAC7C,wBAAc,KAAK,KAAK,MAAM,CAAC,CAAC;QACpC;MACJ;IACJ;AACA,UAAM,WAAW,MAAM,KAAK,IAAI,IAAI,aAAa,CAAC,EAAE,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC;AAExE,UAAM,MAAuB,CAAC;AAC9B,QAAI,IAAI;AACR,eAAW,MAAM,KAAK;AAClB,aAAO,IAAI,SAAS,UAAU,SAAS,CAAC,IAAI,GAAG,MAAM;AACjD,cAAM,IAAI,SAAS,GAAG;AACtB,cAAMC,KAAI,mBAAmB,KAAK,CAAC;AACnC,cAAM,KAAKA,GAAE,CAAC,IAAIA,GAAE,CAAC,KAAK;AAC1B,YAAI,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;MACvC;AACA,YAAM,IAAU,GAAG,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,CAAC,IAAI,GAAG;AAC5E,UAAI,KAAK,EAAE,MAAM,GAAG,MAAM,OAAO,GAAG,QAAQ,GAAG,OAAO,CAAC;IAC3D;AACA,WAAO,IAAI,SAAS,QAAQ;AACxB,YAAM,IAAI,SAAS,GAAG;AACtB,YAAM,IAAI,mBAAmB,KAAK,CAAC;AACnC,YAAM,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK;AAC1B,UAAI,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;IACvC;AAEA,WAAO,EAAE,MAAA,YAAyB,WAAW,IAAI;EACrD;AAEA,WAAS,0BAA0B,MAAgB,KAA8B;AAC7E,UAAM,IAAI,CAAC,MAAsB;AAC7B,YAAM,KAAK,IAAI,KAAK,SAAS,IAAI,OAAO,KAAK;AAC7C,YAAM,KAAK,KAAK,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,KAAK;AAC5D,YAAM,KAAK,KAAK,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,KAAK;AAC5D,aAAO,KAAK;IAChB;AACA,QAAI,KAAK,KAAK,MAAM,KAAK,IAAI;AAC7B,QAAI,MAAM,EAAE,EAAE;AACd,QAAI,QAAQ,EAAG,QAAO;AACtB,UAAM,MAAM,EAAE,EAAE;AAChB,QAAI,QAAQ,EAAG,QAAO;AACtB,QAAI,MAAM,MAAM,EAAG,QAAO;AAC1B,aAAS,IAAI,GAAG,IAAI,KAAK,KAAK;AAC1B,YAAM,OAAO,KAAK,MAAM;AACxB,YAAM,OAAO,EAAE,GAAG;AAClB,UAAI,SAAS,KAAK,KAAK,IAAI,KAAK,EAAE,IAAI,KAAQ,QAAO;AACrD,UAAI,MAAM,OAAO,GAAG;AAAE,aAAK;MAAK,OAC3B;AAAE,aAAK;AAAK,cAAM;MAAM;IACjC;AACA,YAAQ,KAAK,MAAM;EACvB;AAEA,WAAS,mBAAmB,KAAsB,GAAiB;AAC/D,QAAI,KAAK,IAAI,CAAC,EAAE,KAAM,QAAO,IAAI,CAAC,EAAE;AACpC,QAAI,KAAK,IAAI,IAAI,SAAS,CAAC,EAAE,KAAM,QAAO,IAAI,IAAI,SAAS,CAAC,EAAE;AAC9D,aAAS,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;AACjC,UAAI,KAAK,IAAI,CAAC,EAAE,MAAM;AAClB,cAAM,OAAO,IAAI,IAAI,CAAC;AACtB,cAAM,MAAM,IAAI,CAAC;AACjB,cAAM,KAAK,IAAI,KAAK,SAAS,IAAI,OAAO,KAAK;AAC7C,eAAO;UACH,KAAK,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,KAAK;UACjD,KAAK,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,KAAK;QACrD;MACJ;IACJ;AACA,WAAO,IAAI,IAAI,SAAS,CAAC,EAAE;EAC/B;AAQA,WAAS,mBAAmB,MAA4B;AACpD,UAAM,IAAI,KAAK;AACf,QAAI,CAAC,KAAK,EAAE,SAAS,EAAG,QAAO;AAC/B,QAAI,QAAQ;AACZ,aAAS,IAAI,GAAG,IAAI,EAAE,SAAS,GAAG,KAAK;AACnC,eAAS,cAAc,MAAM,GAAG,IAAI,CAAC;IACzC;AACA,QAAI,KAAK,KAAK,EAAE,SAAS,GAAG;AACxB,eAAS,cAAc,MAAM,EAAE,SAAS,GAAG,CAAC;IAChD;AACA,WAAO;EACX;AAEA,WAAS,cAAc,MAAoB,MAAc,IAAoB;AArgB7E,QAAA,IAAA,IAAA,IAAA;AAsgBI,UAAM,IAAI,KAAK;AACf,UAAM,KAAK,EAAE,IAAI;AACjB,UAAM,KAAK,EAAE,EAAE;AACf,UAAM,MAAM,MAAA,KAAA,KAAK,MAAL,OAAA,SAAA,GAAS,IAAA,MAAT,OAAA,KAAkB;AAC9B,UAAM,MAAM,MAAA,KAAA,KAAK,MAAL,OAAA,SAAA,GAAS,EAAA,MAAT,OAAA,KAAgB;AAC5B,UAAM,MAAM,sBAAsB,IAAI,IAAI,IAAI,EAAE;AAChD,WAAO,IAAI,GAAG,IAAI,GAAG,SAAS,CAAC;EACnC;AAMA,MAAM,YAAY;AAgBlB,WAAS,aAAa,MAAkC;AAniBxD,QAAA,IAAA,IAAA,IAAA,IAAA,IAAA,IAAA,IAAA,IAAA,IAAA;AAoiBI,QAAI,KAAK,SAAS,QAAQ;AACtB,YAAM,IAAI,QAAO,KAAA,KAAK,MAAL,OAAA,KAAU,CAAC,GAAG,IAAI,QAAO,KAAA,KAAK,MAAL,OAAA,KAAU,CAAC;AACrD,YAAM,IAAI,QAAO,KAAA,KAAK,UAAL,OAAA,KAAc,CAAC,GAAG,IAAI,QAAO,KAAA,KAAK,WAAL,OAAA,KAAe,CAAC;AAC9D,aAAO,OAAO,IAAI,KAAK,MAAM,IACzB,OAAO,IAAI,KAAK,OAAO,IAAI,KAC3B,MAAM,IAAI,OAAO,IAAI,KACrB,MAAM,IAAI,MAAM,IAChB,OAAO,IAAI,KAAK,MAAM,IAAI;IAClC;AAEA,QAAI,KAAK,SAAS,aAAa,KAAK,SAAS,UAAU;AACnD,YAAM,KAAK,QAAO,KAAA,KAAK,OAAL,OAAA,KAAW,CAAC,GAAG,KAAK,QAAO,KAAA,KAAK,OAAL,OAAA,KAAW,CAAC;AACzD,YAAM,KAAK,KAAK,SAAS,WAAW,QAAO,KAAA,KAAK,MAAL,OAAA,KAAU,CAAC,IAAI,QAAO,KAAA,KAAK,OAAL,OAAA,KAAW,CAAC;AAC7E,YAAM,KAAK,KAAK,SAAS,WAAW,QAAO,KAAA,KAAK,MAAL,OAAA,KAAU,CAAC,IAAI,QAAO,KAAA,KAAK,OAAL,OAAA,KAAW,CAAC;AAC7E,UAAI,EAAE,KAAK,MAAM,EAAE,KAAK,GAAI,QAAO;AACnC,YAAM,KAAK,KAAK,WAAW,KAAK,KAAK;AACrC,YAAM,IAAI,CAAC,IAAY,IAAY,IAAY,IAAY,GAAW,MAClE,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,KAAK,MAAM,IAAI,MAAM;AAChE,aAAO,OAAO,KAAK,MAAM,MAAM,KAC3B,EAAE,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,KAAK,EAAE,IACjD,EAAE,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,EAAE,IACjD,EAAE,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,IAAI,KAAK,EAAE,IACjD,EAAE,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,IAAI,EAAE,IAAI;IAC7D;AAEA,WAAO;EACX;ACvgBO,WAAS,mBAAmB,MAA2B;AAvD9D,QAAA,IAAA;AAwDI,UAAM,MAAoB;MACtB,MAAM,CAAC;MAAG,UAAU,CAAC;MAAG,QAAQ,CAAC;MACjC,OAAO,oBAAI,IAAI;MAAG,QAAQ;MAC1B,oBAAoB,oBAAI,IAAI;MAC5B,oBAAoB,oBAAI,IAAI;;;MAG5B,UAAQ,KAAA,kBAAkB,IAAI,MAAtB,OAAA,SAAA,GAAyB,UAAS,eAAe,SACnD,iBAAiB,SACjB,iBAAiB;MACvB,SAAQ,KAAA,QAAQ,IAAI,MAAZ,OAAA,SAAA,GAAe;IAC3B;AAEA,UAAM,UAAU,MAAM,IAAI;AAC1B,cAAU,SAAS,IAAI,KAAK;AAC5B,8BAA0B,SAAS,KAAK,MAAM,MAAM,KAAK,OAAO,CAAC;AACjE,8BAA0B,SAAS,GAAG;AAEtC,UAAM,aAAa,gCAAgC,SAAS,GAAG;AAC/D,UAAM,MAAM,0BAA0B,YAAY,GAAG;AACrD,eAAW,KAAK,IAAI,IAAI;AAExB,WAAO,EAAE,MAAM,KAAK,MAAM,IAAI,MAAM,UAAU,IAAI,UAAU,QAAQ,IAAI,OAAO;EACnF;AAeA,WAAS,gCAAgC,MAAc,KAA2B;AAC9E,QAAI,KAAK,SAAU,MAAK,WAAW,KAAK,SAAS,IAAI,CAAA,UAAS,gCAAgC,OAAO,GAAG,CAAC;AAEzG,UAAM,KAAK,KAAK;AAChB,UAAM,aAAa,OAAO,KAAK,OAAO,WAAW,KAAK,KAAK;AAC3D,UAAM,uBAAuB,aAAa,IAAI,mBAAmB,IAAI,UAAU,IAAI;AAEnF,QAAI,CAAC,MAAM,CAAC,qBAAsB,QAAO;AAEzC,UAAM,EAAE,gBAAgB,UAAU,UAAU,UAAU,UAAU,OAAO,SAAS,cAAc,gBAAgB,UAAU,KAAK,IAAI,MAAA,OAAA,KAAM,CAAC;AACxI,UAAM,kBAAkB,MAAA,OAAA,SAAA,GAAI;AAC5B,QAAI,GAAI,QAAO,KAAK;AAEpB,QAAI,IAAI;AAIR,QAAI,mBAAmB;AACvB,QAAI,QAAA,OAAA,SAAA,KAAM,WAAW;AACjB,UAAI,UAAU;AAEV,cAAM,QAAQ,OAAO,SAAS,SAAS,WAAW,SAAS,OAAO;AAIlE,cAAM,UAAU,yBAAyB,GAAG,KAAK,OAAO,SAAS,aAAa,SAAS,YAAY,SAAS,YAAY;AACxH,YAAI,SAAS;AAAE,cAAI;AAAS,6BAAmB;QAAM;MACzD,OAAO;AACH,YAAI,sBAAsB,GAAG,MAAM,GAAG;AACtC,2BAAmB;MACvB;IACJ;AAIA,QAAI,CAAC,iBAAkB,KAAI,oBAAoB,GAAG,UAAU,GAAG;AAM/D,QAAI,wBAAwB,GAAG,cAAc,GAAG;AAChD,QAAI,0BAA0B,GAAG,gBAAgB,GAAG;AACpD,QAAI,oBAAoB,GAAG,UAAU,iBAAiB,GAAG;AACzD,QAAI,oBAAoB,GAAG,UAAU,GAAG;AACxC,QAAI,oBAAoB,GAAG,UAAU,gBAAgB,GAAG;AACxD,QAAI,oBAAoB,GAAG,UAAU,GAAG;AAExC,QAAI,sBAAsB;AAOtB,mBAAa,GAAG,SAAS,GAAG;AAC5B,UAAI,mBAAmB,GAAG,gBAAgB,YAAa,sBAAsB,GAAG;IACpF,OAAO;AACH,UAAI,gCAAgC,GAAG,SAAS,gBAAgB,GAAG;IACvE;AAIA,QAAI,WAAA,OAAA,SAAA,QAAS,OAAQ,MAAK,UAAU,EAAE,OAAO,EAAE,QAAQ,QAAQ,OAAO,EAAE;AACxE,QAAI,WAAY,KAAI,MAAM,IAAI,YAAY,CAAC;AAC3C,WAAO;EACX;AAIA,WAAS,0BAA0B,MAAc,KAA2B;AACxE,0BAAsB,MAAM,GAAG;AAC/B,WAAO;EACX;ACpHO,WAAS,qBACZ,KACA,QACA,MACqB;AAvDzB,QAAA,IAAA;AAyDI,QAAI,OAAO,mBAAmB,GAAG,EAAE;AAKnC,UAAM,YAAW,MAAA,KAAA,kBAAkB,IAAI,MAAtB,OAAA,SAAA,GAAyB,aAAzB,OAAA,KAAqC;AACtD,WAAO,+BAA+B,MAAM,QAAQ;AAEpD,QAAI,WAAW,iBAAiB,QAAQ;AAIpC,aAAO,6BAA6B,MAAM,QAAA,OAAA,SAAA,KAAM,UAAU;AAM1D,aAAO,gCAAgC,IAAI;AAM3C,aAAO,sBAAsB,IAAI;IACrC;AAEA,WAAO;EACX;AAkBA,WAAS,sBAAsB,MAAoD;AAC/E,UAAMC,aAAY,CAAC,MAAuB,EAAE,WAAW,GAAG,IAAI,EAAE,MAAM,CAAC,IAAI;AAC3E,UAAM,OAAO,CAAC,GAAW,OAAkC;AAzG/D,UAAA;AAyGiE,SAAG,CAAC;AAAG,OAAA,KAAA,EAAE,aAAF,OAAA,SAAA,GAAY,QAAQ,CAAA,MAAK,KAAK,GAAG,EAAE,CAAA;IAAI;AAE3G,QAAI,UAAU;AACd,WAAO,SAAS;AACZ,gBAAU;AACV,YAAM,aAAa,oBAAI,IAAY;AACnC,WAAK,MAAM,CAAA,MAAK;AACZ,YAAI,EAAE,SAAS,SAAS,OAAO,EAAE,SAAS,SAAU,YAAW,IAAIA,WAAU,EAAE,IAAI,CAAC;MACxF,CAAC;AACD,WAAK,MAAM,CAAA,MAAK;AACZ,YAAI,CAAC,EAAE,SAAU;AACjB,YAAI,OAAO,EAAE;AAEb,YAAI,EAAE,SAAS,QAAQ;AACnB,iBAAO,KAAK,OAAO,CAAA,MACf,GAAG,EAAE,SAAS,OAAO,EAAE,SAAS,aAAa,OAAO,EAAE,OAAO,YAAY,CAAC,WAAW,IAAI,EAAE,EAAE,EAAE;QACvG;AAEA,eAAO,KAAK,OAAO,CAAA,MAAK,EAAE,EAAE,SAAS,WAAW,CAAC,EAAE,YAAY,EAAE,SAAS,WAAW,GAAG;AACxF,YAAI,KAAK,WAAW,EAAE,SAAS,QAAQ;AAAE,YAAE,WAAW;AAAM,oBAAU;QAAM;MAChF,CAAC;IACL;AACA,WAAO;EACX;ACnHA,WAAS,aAAa,IAAwB;AAC1C,UAAM,IAAS;AACf,QAAI,OAAO,EAAE,0BAA0B,WAAY,QAAO,EAAE,sBAAsB,EAAE;AACpF,WAAO,EAAE,WAAW,IAAI,EAAE;EAC9B;AAEA,WAAS,YAAY,QAAsB;AACvC,UAAM,IAAS;AACf,QAAI,OAAO,EAAE,yBAAyB,YAAY;AAAE,QAAE,qBAAqB,MAAM;AAAG;IAAQ;AAC5F,MAAE,aAAa,MAAM;EACzB;AAsBO,WAAS,6BACZ,KACA,SACA,WACa;AAjDjB,QAAA;AAmDI,UAAM,SAAS,kBAAkB,GAAG,KAAK,CAAC;AAE1C,UAAM,WAAW,sBAAsB,KAAK,iBAAiB,MAAM;AAGnE,UAAM,cAAc,OAAO;AAC3B,QAAI,aAAqB;AACzB,QAAI,OAAO,gBAAgB,SAAU,cAAa,eAAe;AACjE,QAAI,gBAAgB,WAAY,cAAa;AAC7C,QAAI,aAAa,EAAG,cAAa;AAEjC,UAAM,WAAW,EAAE,OAAO,YAAY;AACtC,UAAM,gBAAgB,YAAY,aAC9B,YAAY,eAAe,WAAW,WAAW,cAChD,YAAY,cAAA,OAAA,aAAc,KAAK,WAAW;AAG/C,UAAM,YAAY,OAAO,aAAa;AAKtC,UAAM,QAAO,KAAA,OAAO,SAAP,OAAA,KAAe;AAC5B,UAAM,gBAAgB,SAAS,cAAc,SAAS;AACtD,UAAM,iBAAiB,SAAS,eAAe,SAAS;AAIxD,QAAI,UAAyB;AAC7B,QAAI,UAAU;AAOd,QAAI,wBAAwB,EAAE,OAAO,SAAS;AAC9C,QAAI,gBAAgB;AACpB,QAAI,eAAe;AAEnB,QAAI,eAAe;AAGnB,UAAM,YAAY,OAAO;AACzB,UAAM,qBAAqB,aAAa,YAAY,IAAI,MAAO,YAAY;AAC3E,QAAI,eAAe;AAInB,UAAM,iBAAiB,MAAM;AAEzB,YAAM,iBAAiB,iBAAiB,KAAK,IAAI,IAAI,iBAAiB,eAAe;AACrF,aAAO,wBAAwB;IACnC;AAEA,UAAM,qBAAqB,MAAM;AAC7B,UAAI,OAAO,eAAe;AAG1B,UAAI,OAAO,SAAS,aAAa,KAAK,OAAQ,cAA0B,QAAO;AAC/E,UAAI,OAAO,EAAG,QAAO;AACrB,aAAO;IACX;AAOA,aAAS,YAAY,eAAuB;AAExC,eAAS,uBAAuB;AAE5B,cAAM,eAAe,WAAW,IAAI,WAAW;AAE/C,YAAI,cAAc;AAClB,YAAI,YAAY;AAChB,YAAI,WAAW,GAAG;AAad,0BAAgB,MAAM,eAAe,GAAG,aAAa,YAAY;AAEjE,sBAAY,KAAK,IAAI,GAAG,KAAK,KAAK,gBAAgB,YAAY,IAAI,CAAC;AACnE,sBAAY,KAAK,IAAI,WAAW,aAAa,CAAC;AAG9C,gBAAM,gBAAgB,gBAAgB,YAAY;AAGlD,wBAAc,MAAM,gBAAgB,cAAc,GAAG,CAAC;QAC1D,OAAO;AACH,wBAAc;QAClB;AAMA,YAAI,eAAe;AAMnB,cAAM,MAAM,aAAa;AACzB,YAAIC,qBAAoB;AACxB,YAAI,QAAQ,WAAW;AACnBA,+BAAoB,IAAI;QAC5B,WAAW,QAAQ,aAAa;AAC5B,cAAI,YAAY,MAAM,EAAGA,sBAAoB,IAAI;QACrD,WAAW,QAAQ,qBAAqB;AAEpC,cAAI,YAAY,MAAM,EAAGA,sBAAoB,IAAI;QACrD;AACA,eAAOA;MACX;AACA,UAAI,oBAAoB,qBAAqB;AAM7C,iBAAW,WAAW,YAAY,CAAC,GAAG;AAClC,cAAM,UAAU,QAAQ;AACxB,YAAI,CAAC,WAAW,OAAO,YAAY,YAAY,MAAM,QAAQ,OAAO,GAAG;AACnE,kBAAQ,KAAK,+BAA+B,OAAO;AACnD;QACJ;AAGA,cAAM,iBAAiB,oBAAoB,SAAS,oBAAoB,QAAQ;AAGhF,mBAAW,CAAC,UAAU,KAAK,KAAK,OAAO,QAAQ,cAAc,GAAG;AAC5D,kBAAQ,aAAa,QAAQ,IAAI,UAAU,KAAK;QACpD;MACJ;IACJ;AAKA,UAAM,OAAO,MAAM;AA3MvB,UAAAC,KAAA;AA8MQ,UAAI,CAAC,QAAQ,YAAY,GAAG;AAGxB,kBAAU;AACV;MACJ;AAEA,YAAM,cAAc,mBAAmB;AAMvC,YAAM,UAAU,eAAe;AAC/B,UAAI,UAAU,KAAK,eAAe,GAAG;AACjC,YAAI,eAAgB,aAAY,CAAC;AACjC;MACJ;AAMA,UAAI,eAAe,KAAK,WAAW,GAAG;AAClC,kBAAU;AACV,oBAAY,CAAC;AACb,YAAI,CAAC,cAAc;AACf,yBAAe;AACf,WAAAA,MAAA,aAAA,OAAA,SAAA,UAAW,aAAX,OAAA,SAAAA,IAAA,KAAA,SAAA;QACJ;AACA;MACJ;AAGA,UAAI,eAAe,KAAK,iBAAiB,OAAO,SAAS,aAAa,KAAK,eAAgB,eAA0B;AACjH,kBAAU;AAIV,oBAAY,gBAAiB,gBAA2B,CAAC;AAEzD,YAAI,CAAC,cAAc;AACf,yBAAe;AACf,WAAA,KAAA,aAAA,OAAA,SAAA,UAAW,aAAX,OAAA,SAAA,GAAA,KAAA,SAAA;QACJ;AACA;MACJ;AAKA,UAAI,qBAAqB,GAAG;AACxB,cAAM,MAAM,KAAK,IAAI;AACrB,YAAI,gBAAiB,MAAM,eAAgB,oBAAoB;AAE3D;QACJ;AACA,uBAAe;MACnB;AAGA,kBAAY,WAAW;IAC3B;AAMA,QAAI,OAAO,OAAO;AACd,UAAI,OAAO,QAAQ,GAAG;AAElB,oBAAY,mBAAmB,CAAC;MACpC,WAAW,gBAAgB;AAGvB,oBAAY,CAAC;MACjB;IACJ;AAIA,UAAM,aAAa,MAAM;AACrB,UAAI,CAAC,QAAS,QAAO;AACrB,UAAI,CAAC,QAAQ,YAAY,GAAG;AAAE,eAAO;MAAO;AAC5C,UAAI,eAAe,GAAG;AAElB,eAAO,eAAe,IAAI;MAC9B;AACA,UAAI,OAAO,SAAS,aAAa,KAAK,mBAAmB,KAAM,cAA0B,QAAO;AAChG,aAAO;IACX;AAEA,UAAM,WAAW,CAAC,YAAsB;AACpC,UAAI,YAAY,MAAM;AAClB,oBAAY,OAAO;AACnB,kBAAU;MACd;AAEA,UAAI,EAAE,WAAW,WAAW,IAAI;AAE5B;MACJ;AAEA,gBAAU,aAAa,MAAM;AACzB,kBAAU;AACV,aAAK;AACL,iBAAS;MACb,CAAC;IACL;AAEA,UAAM,YAAY,MAAM;AACpB,UAAI,QAAS;AAOb,UAAI,gBAAgB,GAAG;AACnB,YAAI,OAAO,SAAS,aAAa,KAAK,yBAA0B,eAA0B;AACtF,kCAAwB;QAC5B;MACJ,OAAO;AAEH,YAAI,yBAAyB,GAAG;AAC5B,cAAI,CAAC,OAAO,SAAS,aAAa,GAAG;AAGjC,oBAAQ,KAAK,0EAA0E;AACvF;UACJ;AACA,kCAAwB;QAC5B;MACJ;AAIA,qBAAe;AAEf,gBAAU;AACV,sBAAgB,KAAK,IAAI;AACzB,eAAS,IAAI;IACjB;AAEA,UAAM,YAAY,MAAM;AACpB,UAAI,CAAC,QAAS;AAId,UAAI,MAAM,eAAe;AACzB,UAAI,OAAO,SAAS,aAAa,KAAK,MAAO,cAA0B,OAAM;AAC7E,8BAAwB;AACxB,sBAAgB;AAChB,gBAAU;AAEV,UAAI,YAAY,MAAM;AAClB,oBAAY,OAAO;AACnB,kBAAU;MACd;AAIA,UAAI,OAAO,GAAG;AACV,oBAAY,GAAG;MACnB,WAAW,gBAAgB;AACvB,oBAAY,CAAC;MACjB;IACJ;AAEA,UAAM,aAAa,MAAM;AAvX7B,UAAAA;AAwXQ,gBAAU;AAEV,8BAAwB;AACxB,sBAAgB;AAChB,gBAAU;AACV,qBAAe;AAEf,kBAAY,qBAAqB;AAEjC,OAAAA,MAAA,aAAA,OAAA,SAAA,UAAW,aAAX,OAAA,SAAAA,IAAA,KAAA,SAAA;IACJ;AAEA,UAAM,aAAa,CAAC,eAAe,SAAS;AApYhD,UAAAA;AAsYQ,UAAI,OAAO,SAAS,aAAa,GAAG;AAChC,gCAAwB;MAC5B,OAAO;AAEH,gCAAwB,mBAAmB;MAC/C;AACA,sBAAgB;AAChB,gBAAU;AAGV,UAAI,YAAY,MAAM;AAClB,oBAAY,OAAO;AACnB,kBAAU;MACd;AAIA,kBAAY,gBAAgB,wBAAwB,CAAC;AAErD,UAAI,gBAAgB,CAAC,cAAc;AAC/B,uBAAe;AACf,SAAAA,MAAA,aAAA,OAAA,SAAA,UAAW,aAAX,OAAA,SAAAA,IAAA,KAAA,SAAA;MACJ;IACJ;AAIA,UAAM,MAAqB;MAEvB,WAAW,MAAM;MAEjB,kBAAkB,MAAM;MAExB,aAAa,MAAe;AAAE,eAAO,WAAW;MAAG;MAEnD,QAAQ,MAAM;AAzatB,YAAAA;AA0aY,kBAAU;AACV,SAAAA,MAAA,aAAA,OAAA,SAAA,UAAW,WAAX,OAAA,SAAAA,IAAA,KAAA,SAAA;MACJ;MACA,SAAS,MAAM;AA7avB,YAAAA;AA8aY,kBAAU;AACV,SAAAA,MAAA,aAAA,OAAA,SAAA,UAAW,YAAX,OAAA,SAAAA,IAAA,KAAA,SAAA;MACJ;MACA,UAAU,MAAM;AACZ,mBAAW;MAEf;MACA,UAAU,MAAM;AACZ,mBAAW,IAAI;MACnB;MAEA,mBAAmB,CAAC,SAAiB;AACjC,YAAI,CAAC,SAAS,IAAI,KAAK,SAAS,GAAG;AAC/B,kBAAQ,KAAK,mDAAmD;AAChE;QACJ;AAIA,YAAI,UAAU,eAAe;AAC7B,YAAI,OAAO,SAAS,aAAa,KAAK,UAAW,cAA0B,WAAU;AAErF,YAAK,OAAO,MAAQ,eAAe,EAAI,gBAAe;AACtD,uBAAe;AACf,gCAAwB;AACxB,YAAI,QAAS,iBAAgB,KAAK,IAAI;MAC1C;MAEA,kBAAkB,MAAqB;AAAE,eAAO,mBAAmB;MAAG;MAEtE,kBAAkB,CAAC,YAAoB;AAEnC,YAAI,UAAU,EAAG,WAAU;AAC3B,YAAI,OAAO,SAAS,aAAa,KAAK,UAAW,cAA0B,WAAU;AAErF,gCAAwB;AACxB,YAAI,QAAS,iBAAgB,KAAK,IAAI;AAEtC,YAAI,CAAC,OAAO,SAAS,aAAa,KAAK,UAAW,cAA0B,gBAAe;AAE3F,oBAAY,mBAAmB,CAAC;MACpC;MAEA,WAAW,MAAM;AAzdzB,YAAAA;AA0dY,YAAI,OAAO;AACX,SAAAA,MAAA,aAAA,OAAA,SAAA,UAAW,aAAX,OAAA,SAAAA,IAAA,KAAA,SAAA;MACJ;IACJ;AAIA,WAAO;EACX;AEvdA,MAAM,SAAS;AAEf,WAAS,cACL,SACA,iBACA,OACA,UACA,aACiB;AACjB,QAAI,0BAA0B,IAAI,QAAQ,YAAY,CAAC,GAAG;AACtD,cAAQ,KAAK,iCAAiC,OAAO;AACrD,aAAO;IACX;AAEA,UAAM,UAAU,SAAS,gBAAgB,QAAQ,OAAO;AAExD,eAAW,YAAY,iBAAiB;AAKpC,YAAM,YAAY,uBAAuB,UAAU,gBAAgB,QAAQ,CAAC;AAC5E,UAAI,cAAc,OAAW;AAI7B,UAAI,qBAAqB,IAAI,QAAQ,GAAG;AACnC,gBAAyD,MAAM,QAAQ,IAAI,OAAO,SAAS;AAC5F;MACJ;AACA,cAAQ,aAAa,6BAA6B,QAAQ,GAAG,SAAS;IAC1E;AAGA,QAAI,OAAO;AACP,iBAAW,aAAa,OAAO;AAC1B,gBAAgB,MAAM,SAAS,IAAI,OAAO,MAAM,SAAS,CAAC;MAC/D;IACJ;AAEA,QAAI,UAAU;AACV,iBAAW,SAAS,UAAU;AAC1B,gBAAQ,YAAY,KAAK;MAC7B;IACJ;AAEA,QAAI,YAAa,SAAQ,cAAc;AAEvC,WAAO;EACX;AAMO,WAAS,WAAW,MAAc,MAA+B;AACpE,QAAI,CAAC,KAAM,QAAO;AAElB,UAA4C,KAAA,MAApC,EAAA,MAAM,UAAU,MArE5B,IAqEgD,IAAV,QAAA,UAAU,IAAV,CAA1B,QAAM,YAAU,OAAA,CAAA;AAOxB,UAAM,aAAc,MAAgC;AACpD,QAAI,eAAe,OAAW,QAAQ,MAAgC;AAGtE,UAAM,WAAW,QAAQ,IAA6B,KAAK;AAG3D,UAAM,gBAAgB,aAAa,OAAO,QAAQ;AAGlD,QAAI;AACJ,QAAI,UAAU;AACV,iBAAW,MAAM,UAAU;AACvB,cAAM,QAAQ,WAAW,IAAI,QAAQ;AACrC,YAAI,OAAO;AACP,cAAI,CAAC,cAAe,iBAAgB,CAAC;AACrC,wBAAc,KAAK,KAAK;QAC5B;MACJ;IACJ;AAEA,UAAM,UAAU;MACZ,QAAQ;MACR,mBAAmB,KAAK;MACxB;MACA;MACA,MAAM,SAAS,KAAK,MAAM,iBAAiB;IAC/C;AAIA,QAAI,WAAW,eAAe,OAAW,SAAQ,aAAa,QAAQ,UAAU;AAEhF,WAAO;EACX;AC5EO,WAAS,uBACZ,KACA,QACa;AAIb,UAAM,EAAE,SAAS,YAAY,YAAY,0BAA0B,EAAE,IAAI;AAEzE,UAAM,OAAO,IAAI,eAAe;AAEhC,QAAI,CAAC,MAAM;AACP,cAAQ,KAAK,8DAA8D;AAC3E,aAAO;IACX;AAKA,QAAI,WAAW;AAGf,UAAM,QAAQ,MAAM;AAChB,UAAI,UAAU;AACV,mBAAW;AACX,YAAI,gBAAgB,CAAC;MACzB;AACA,UAAI,KAAK;IACb;AAGA,UAAM,kBAAkB,MAAM;AAC1B,cAAQ,WAAW;QACf,KAAK;AACD,cAAI,MAAM;AACV;QACJ,KAAK;AACD,cAAI,OAAO;AACX;QACJ,KAAK;AAED,qBAAW;AACX,cAAI,gBAAgB,EAAE;AACtB,cAAI,KAAK;AACT;QACJ,KAAK;QACL;AAEI;MACR;IACJ;AAGA,YAAQ,SAAS;MACb,KAAK,QAAQ;AACT,cAAM,eAAe,MAAM,MAAM;AACjC,YAAI,SAAS,eAAe,YAAY;AACpC,uBAAa;QACjB,OAAO;AACH,iBAAO,iBAAiB,QAAQ,cAAc,EAAE,MAAM,KAAK,CAAC;QAChE;AACA;MACJ;MAEA,KAAK,aAAa;AACd,cAAM,mBAAmB,MAAM,MAAM;AACrC,cAAM,kBAAkB,MAAM,gBAAgB;AAE9C,aAAK,iBAAiB,cAAc,gBAAgB;AACpD,aAAK,iBAAiB,cAAc,eAAe;AACnD;MACJ;MAEA,KAAK,SAAS;AACV,cAAM,eAAe,MAAM;AACvB,cAAI,IAAI,UAAU,GAAG;AACjB,4BAAgB;UACpB,OAAO;AACH,kBAAM;UACV;QACJ;AACA,aAAK,iBAAiB,SAAS,YAAY;AAC3C;MACJ;MAEA,KAAK,kBAAkB;AACnB,cAAM,WAAW,IAAI;UACjB,CAAA,YAAW;AACP,oBAAQ,QAAQ,CAAA,UAAS;AAErB,kBAAI,MAAM,kBAAkB,MAAM,qBAAqB,yBAAyB;AAC5E,sBAAM;cACV,OAAO;AAEH,gCAAgB;cACpB;YACJ,CAAC;UACL;UACA,EAAE,WAAW,wBAAwB;QACzC;AACA,iBAAS,QAAQ,IAAI;AACrB;MACJ;MAEA,KAAK;AAED;IACR;AAEA,WAAO;EACX;AClIO,WAAS,YAAY,IAAY;AAEpC,WAAO,MAAM;EACjB;AAiBO,WAAS,wBACZ,KACA,SACA,WACA,aACa;AAEb,UAAM,SAAS,kBAAkB,GAAG,KAAK,CAAC;AAG1C,QAAI,CAAC,aAAa;AACd,UAAI,IAAI,IAAI;AACR,cAAM,eAAe,YAAY,IAAI,EAAE;AACvC,sBAAc,SAAS,cAAc,YAAY;AACjD,YAAI,CAAC,YAAa,SAAQ,KAAK,iEAAiE,YAAY;MAChH,OAAO;AACH,gBAAQ,KAAK,mDAAmD;MACpE;IACJ;AAEA,UAAM,WAAW;MACb;MACA,WAAW,iBAAiB,WAAW;MACvC;IACJ;AAGA,UAAM,MAAqB,cAAA,eAAA,CAAA,GACpB,QAAA,GADoB;MAEvB,kBAAkB,MAAM,eAAe;IAC3C,CAAA;AACA,QAAI,OAAO,QAAS,wBAAuB,KAAK,OAAO,OAAO;AAC9D,WAAO;EACX;AAEO,WAAS,iBAAiB,aAA8B;AAE3D,UAAM,kBAAkB,oBAAI,IAAY;AAExC,UAAM,UAA6B;MAC/B,aAAa,MAAM;AACf,YAAI,CAAC,YAAa,QAAO;AACzB,eAAO,YAAY;MACvB;MACA,cAAc,CAAC,IAAI,UAAU,UAAU;AAEnC,mBAAW,6BAA6B,QAAQ;AAEhD,cAAM,WAAW,YAAY,EAAE;AAG/B,cAAM,YAAW,eAAA,OAAA,SAAA,YAAa,iBAAiB,QAAA,MAAa,SAAS,iBAAiB,QAAQ;AAE9F,YAAI,SAAS,WAAW,KAAK,CAAC,gBAAgB,IAAI,QAAQ,GAAG;AACzD,0BAAgB,IAAI,QAAQ;AAC5B,kBAAQ,KAAK,mDAAmD,WAAW,GAAG;QAClF;AAEA,iBAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACtC,gBAAM,UAAU,SAAS,CAAC;AAK1B,gBAAM,oBAAoB,aAAa,eAAe,QAAQ,YAAY,YACpE,qBACA;AACN,kBAAQ,aAAa,mBAAmB,KAAK;AAC7C,cAAI,iBAAiB,IAAI,QAAQ,GAAG;AAC/B,oBAAwB,MAAM,QAAe,IAAI;UACtD;QACJ;MACJ;IACJ;AACA,WAAO;EACX;ACrFA,WAAS,YAAY,IAAgB,GAAW,UAAkB,gBAA6B;AAxB/F,QAAA,IAAA;AAyBI,QAAI,SAAQ,KAAA,GAAG,MAAH,OAAA,KAAQ,GAAG;AACvB,UAAM,KAAI,KAAA,GAAG,MAAH,OAAA,KAAQ,GAAG;AAErB,UAAM,QAAkB;MACpB,QAAQ;MACR,QAAQ,KAAK,MAAM,QAAQ,CAAC,IAAI,kBAAkB,EAAE,KAAK,GAAG,IAAI,MAAM;IAC1E;AAEA,QAAI;AACJ,QAAI,SAAS;AAEb,QAAI,kBAAkB,IAAI,QAAQ,KAAK,MAAM,QAAQ,KAAK,GAAG;AACzD,iBAAW,OAAO,KAAK;IAC3B,WAAW,aAAa,eAAe,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG;AAGzG,iBAAW,sBAAsB,OAAO,EAAE,WAAW,KAAK,CAAC;AAC3D,eAAS;IACb,WAAW,mBAAmB,IAAI,QAAQ,GAAG;AACzC,UAAI,MAAM,QAAQ,KAAK,GAAG;AACtB,YAAI,aAAa,YAAa,SAAQ,MAAM,IAAI,CAAA,MAAK,IAAI,IAAI;AAC7D,gBAAQ,MAAM,KAAK,GAAG;MAC1B;AACA,UAAI,aAAa,SAAU,SAAQ,QAAQ;AAC3C,iBAAW,WAAW,MAAM,QAAQ;AACpC,eAAS;IACb,WAAW,aAAa,KAAK;AAMzB,YAAM,QAA8B,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,MAAM,KAAK,IAC7F,MAAM,QAAQ,CAAC;AAIrB,iBAAW,WAAW,MAAM,IAAI,CAAA,OAAM,gBAAgB,IAAI,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI;IAChF,OAAO;AACH,iBAAW,KAAK;IACpB;AAEA,QAAI,CAAC,IAAI,SAAS,QAAQ,QAAQ,EAAG,gBAAe,IAAI,MAAM;AAE9D,aAAS,qBAAqB,MAAM;AACpC,UAAM,MAAM,IAAI;AAChB,WAAO;EACX;AAQA,WAAS,wBACL,UACA,WACA,UACY;AApFhB,QAAA,IAAA,IAAA,IAAA,IAAA;AAqFI,UAAM,SAAuB,CAAC;AAE9B,aAAS,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAK;AACvC,YAAM,KAAK,UAAU,CAAC;AACtB,YAAM,KAAI,KAAA,GAAG,MAAH,OAAA,KAAQ;AAElB,UAAI,IAAI,GAAG;AAEP,cAAM,OAAO,UAAU,IAAI,CAAC;AAC5B,YAAI,UAAS,KAAA,KAAK,MAAL,OAAA,KAAU,MAAM,GAAG;AAC5B,gBAAM,SAAQ,KAAA,KAAK,MAAL,OAAA,KAAU;AACxB,gBAAM,aAAa,IAAI,MAAM,QAAQ;AACrC,gBAAM,YAAY,GAAG,IAAI,YAAY,GAAG,CAAqC,EAAE,SAAS,IAAI;AAC5F,gBAAM,EAAE,OAAO,YAAY,IAAI,YAAY,GAAG,GAAU,SAAS;AACjE,iBAAO,KAAK,EAAE,GAAG,GAAG,GAAG,iBAAiB,UAAU,GAAG,GAAG,KAAK,GAAG,SAAS,GAAG,GAAG,YAAY,CAAC;QAChG;AACA;MACJ;AAEA,UAAI,IAAI,UAAU;AAEd,cAAM,OAAO,UAAU,IAAI,CAAC;AAC5B,YAAI,UAAS,KAAA,KAAK,MAAL,OAAA,KAAU,MAAM,UAAU;AACnC,gBAAM,SAAQ,KAAA,KAAK,MAAL,OAAA,KAAU;AACxB,gBAAM,aAAa,WAAW,UAAU,IAAI;AAC5C,gBAAM,YAAY,KAAK,IAAI,YAAY,KAAK,CAAqC,EAAE,SAAS,IAAI;AAChG,gBAAM,EAAE,MAAM,WAAW,IAAI,YAAY,KAAK,GAAU,SAAS;AACjE,cAAI,OAAO,SAAS,EAAG,QAAO,OAAO,SAAS,CAAC,IAAI,cAAA,eAAA,CAAA,GAAK,OAAO,OAAO,SAAS,CAAC,CAAA,GAA7B,EAAgC,GAAG,WAAW,CAAA;AACjG,iBAAO,KAAK,EAAE,GAAG,UAAU,GAAG,iBAAiB,UAAU,KAAK,GAAG,GAAG,GAAG,SAAS,GAAG,GAAG,OAAU,CAAC;QACrG;AACA;MACJ;AAEA,aAAO,KAAK,EAAE;IAClB;AAEA,WAAO;EACX;AAeO,WAAS,yBACZ,SACA,gBACA,QACuB;AA7I3B,QAAA;AA8II,UAAM,SAAS,oBAAI,IAAwB;AAE3C,eAAW,CAAC,UAAU,QAAQ,KAAK,OAAO,QAAQ,OAAO,GAAG;AACxD,YAAM,WAAW,OAAO,YAAY;AACpC,YAAM,mBAAmB,wBAAwB,UAAU,SAAS,OAAO,SAAS,aAAa,CAAC,GAAG,QAAQ;AAC7G,YAAM,eAA2B,CAAC;AAElC,eAAS,IAAI,GAAG,IAAI,iBAAiB,QAAQ,KAAK;AAC9C,cAAM,KAAK,iBAAiB,CAAC;AAE7B,cAAM,IAAI,QAAO,KAAA,GAAG,MAAH,OAAA,KAAQ,KAAK,UAAU,GAAG,CAAC;AAC5C,cAAM,QAAkB,YAAY,IAAI,GAAG,UAAU,cAAc;AAGnE,YAAI,MAAM,MAAM,MAAM,UAAU,KAAK,GAAG;AACpC,uBAAa,KAAK,cAAA,eAAA,CAAA,GAAK,KAAA,GAAL,EAAY,QAAQ,EAAE,CAAA,CAAC;QAC7C;AAEA,qBAAa,KAAK,KAAK;MAC3B;AAGA,UAAI,aAAa,SAAS,MAAM,aAAa,aAAa,SAAS,CAAC,EAAE,UAAU,KAAK,GAAG;AACpF,qBAAa,KAAK,cAAA,eAAA,CAAA,GACX,aAAa,aAAa,SAAS,CAAC,CAAA,GADzB;UAEd,QAAQ;QACZ,CAAA,CAAC;MACL;AAEA,UAAI,aAAa,SAAS,GAAG;AACzB,eAAO,IAAI,UAAU,YAAY;MACrC;IACJ;AAEA,WAAO;EACX;AAcO,WAAS,qBACZ,KACA,WACA,aACA,gCACoB;AApMxB,QAAA;AAsMI,UAAM,SAAS,kBAAkB,GAAG,KAAK,CAAC;AAG1C,QAAI,CAAC,aAAa;AACd,UAAI,IAAI,IAAI;AACR,cAAM,eAAe,YAAY,IAAI,EAAE;AACvC,sBAAc,SAAS,cAAc,YAAY;AACjD,YAAI,CAAC,YAAa,SAAQ,KAAK,iEAAiE,YAAY;MAChH,OAAO;AACH,gBAAQ,KAAK,mDAAmD;MACpE;IACJ;AAMA,UAAM,WAAW,sBAAsB,KAAK,iBAAiB,MAAM;AAEnE,UAAM,aAA+B,CAAC;AAEtC,UAAM,cAAc,OAAO;AAC3B,QAAI;AACJ,QAAI,OAAO,gBAAgB,SAAU,cAAa;AAClD,QAAI,gBAAgB,WAAY,cAAa;AAE7C,UAAM,iBAAiB,oBAAI,IAAY;AAMvC,QAAI,iBAAiB;AACrB,QAAI,eAAe;AAKnB,QAAI,EAAC,YAAA,OAAA,SAAA,SAAU,SAAQ;AACnB,cAAQ,KAAK,qDAAqD;IACtE;AAEA,eAAW,WAAW,YAAY,CAAC,GAAG;AAClC,YAAM,UAAU,QAAQ;AACxB,UAAI,CAAC,WAAW,OAAO,YAAY,YAAY,MAAM,QAAQ,OAAO,GAAG;AACnE,gBAAQ,KAAK,qDAAqD,OAAO;AACzE;MACJ;AAEA,YAAM,WAAW,YAAY,QAAQ,EAAE;AAGvC,YAAM,YAAW,eAAA,OAAA,SAAA,YAAa,iBAAiB,QAAA,MAAa,SAAS,iBAAiB,QAAQ;AAE9F,UAAI,SAAS,WAAW,GAAG;AACvB,gBAAQ,KAAK,2DAA2D,WAAW,GAAG;MAC1F;AAGA,YAAM,eAAe,yBAAyB,SAAS,gBAAgB,MAAM;AAW7E,YAAM,gBAAgB,OAAO,SAAS,OAAO,QAAQ,IAAI,OAAO,QAAQ;AACxE,UAAI;AACJ,UAAI,OAAO,SAAS,OAAO,QAAQ,KAAK,OAAO,UAAU;AACrD,cAAM,UAAU,CAAC,OAAO;AACxB,uBAAe,eAAe,WACxB,UAAU,OAAO,WACjB,KAAK,IAAI,SAAS,OAAO,YAAY,cAAA,OAAA,aAAc,EAAE;MAC/D;AAEA,YAAM,gBAAuC;QACzC,UAAU,OAAO;QACjB,OAAO;;;;;QAKP,OAAM,KAAA,OAAO,SAAP,OAAA,KAAe;QACrB,WAAW,OAAO;QAClB;MACJ;AAEA,eAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACtC,cAAM,UAAU,SAAS,CAAC;AAE1B,mBAAW,CAAC,EAAE,SAAS,KAAK,cAAc;AACtC,cAAI,UAAU,SAAS,GAAG;AACtB,gBAAI;AACA,oBAAM,SAAS,IAAI,eAAe,SAAS,WAAW,aAAa;AACnE,oBAAM,OAAO,IAAI,UAAU,QAAQ,SAAS,QAAQ;AAEpD,kBAAI,aAAA,OAAA,SAAA,UAAW,SAAU,MAAK,WAAW,MAAM;AA1SvE,oBAAAC;AA2S4B,oBAAI,eAAgB;AACpB,iCAAiB;AACjB,iBAAAA,MAAA,UAAU,aAAV,OAAA,SAAAA,IAAA,KAAA,SAAA;cACJ;AACA,kBAAI,aAAA,OAAA,SAAA,UAAW,SAAU,MAAK,WAAW,MAAM;AA/SvE,oBAAAA;AAgT4B,oBAAI,aAAc;AAClB,+BAAe;AACf,iBAAAA,MAAA,UAAU,aAAV,OAAA,SAAAA,IAAA,KAAA,SAAA;cACJ;AAIA,kBAAI,iBAAiB,QAAW;AAC5B,qBAAK,cAAc;cACvB;AAEA,yBAAW,KAAK,IAAI;YACxB,SAAS,GAAG;AACR,sBAAQ,KAAK,CAAC;YAClB;UACJ;QACJ;MACJ;IACJ;AAIA,QAAI,CAAC,kCAAkC,eAAe,MAAM;AACxD,cAAQ,KAAK,4BAA4B,CAAC,GAAG,cAAc,EAAE,KAAK,IAAI,CAAC;AACvE,aAAO;IACX;AAIA,UAAM,MAAqB;MAEvB,WAAW,MAAM;MAEjB,kBAAkB,MAAM,eAAe;MAEvC,aAAa,MAAe;AAnVpC,YAAAA;AAmVsC,iBAAOA,MAAA,WAAW,CAAC,MAAZ,OAAA,SAAAA,IAAe,eAAc;MAAW;MAE7E,QAAQ,MAAM;AArVtB,YAAAA;AAsVY,yBAAiB;AACjB,mBAAW,QAAQ,CAAA,MAAK,EAAE,KAAK,CAAC;AAChC,SAAAA,MAAA,aAAA,OAAA,SAAA,UAAW,WAAX,OAAA,SAAAA,IAAA,KAAA,SAAA;MACJ;MACA,SAAS,MAAM;AA1VvB,YAAAA;AA2VY,mBAAW,QAAQ,CAAA,MAAK,EAAE,MAAM,CAAC;AACjC,SAAAA,MAAA,aAAA,OAAA,SAAA,UAAW,YAAX,OAAA,SAAAA,IAAA,KAAA,SAAA;MACJ;MACA,UAAU,MAAM;AA9VxB,YAAAA;AA+VY,yBAAiB;AACjB,mBAAW,QAAQ,CAAA,MAAK,EAAE,OAAO,CAAC;AAClC,SAAAA,MAAA,aAAA,OAAA,SAAA,UAAW,aAAX,OAAA,SAAAA,IAAA,KAAA,SAAA;MACJ;MACA,UAAU,MAAM;AAnWxB,YAAAA;AAoWY,mBAAW,KAAK,YAAY;AACxB,cAAI;AACA,kBAAIA,MAAA,EAAE,WAAF,OAAA,SAAAA,IAAU,UAAA,EAAY,gBAAe,UAAU;AAC/C,gBAAE,OAAO,aAAa,EAAE,YAAY,EAAE,CAAC;AACvC,gBAAE,OAAO;AACT,gBAAE,OAAO,aAAa,EAAE,YAAY,SAAS,CAAC;YAClD,OAAO;AACH,gBAAE,OAAO;YACb;UACJ,SAAS,GAAG;AACR,cAAE,OAAO;UACb;QACJ;MAGJ;MAEA,mBAAmB,CAAC,SAAiB;AACjC,mBAAW,QAAQ,CAAA,MAAM,EAAE,eAAe,IAAK;AAC/C,eAAO;MACX;MACA,kBAAkB,MAAqB;AAzX/C,YAAAA,KAAA;AA0XY,cAAM,OAAM,MAAAA,MAAA,WAAW,CAAC,MAAZ,OAAA,SAAAA,IAAe,gBAAf,OAAA,KAA8B;AAC1C,eAAO,QAAQ,OAAO,CAAC,MAAM;MACjC;MACA,kBAAkB,CAAC,SAAiB;AAChC,yBAAiB;AACjB,mBAAW,QAAQ,CAAA,MAAK;AACpB,YAAE,cAAc;QACpB,CAAC;MACL;MAEA,WAAW,MAAM;AApYzB,YAAAA;AAqYY,YAAI,OAAO;AACX,mBAAW,OAAO,GAAG,WAAW,MAAM;AACtC,YAAI,CAAC,cAAc;AACf,yBAAe;AACf,WAAAA,MAAA,aAAA,OAAA,SAAA,UAAW,aAAX,OAAA,SAAAA,IAAA,KAAA,SAAA;QACJ;MACJ;IACJ;AAIA,QAAI,OAAO,SAAS;AAChB,6BAAuB,KAAK,OAAO,OAAO;IAC9C;AAEA,WAAO;EACX;ACjYA,WAAS,yBACL,KACA,SACA,WACA,aACa;AAEb,UAAM,iBAAiB,kBAAkB,GAAG,KAAK,CAAC;AAOlD,QAAI;AACJ,QAAI,qBAAqB;AACzB,QAAI,eAAe,eAAe;AAC9B,2BAAqB,cAAA,eAAA,CAAA,GACd,SAAA,GADc;QAEjB,UAAU,MAAM;AAvC5B,cAAA;AAwCgB,WAAA,KAAA,aAAA,OAAA,SAAA,UAAW,aAAX,OAAA,SAAA,GAAA,KAAA,SAAA;AACA,oBAAA,OAAA,SAAA,OAAQ,OAAA;QACZ;MACJ,CAAA;IACJ;AAEA,QAAI;AACJ,QAAI,eAAe,SAAS,eAAe,QAAQ;AAE/C,YAAM,wBAAwB,KAAK,SAAS,oBAAoB,WAAW;IAC/E,OAAO;AAGH,YACI;QAAqB;QAAK;QAAoB;QAC1C,eAAe,SAAS,eAAe;;MAC3C,KACA,wBAAwB,KAAK,SAAS,oBAAoB,WAAW;IAE7E;AACA,aAAS;AAET,QAAI,eAAe,eAAe;AAC7B,aAAe,eAAe,aAAa,IAAI;IACpD;AAEA,WAAO;EACX;AAeO,WAAS,mBACZ,KACA,SACA,WACA,kBACa;AAMb,UAAM,kBAAkB,oBAAoB,GAAU;AACtD,eAAW,KAAK,gBAAiB,SAAQ,KAAK,uCAAuC,CAAC;AAOtF,UAAM,iBAAiB,kBAAkB,GAAG,KAAK,CAAC;AAClD,UAAM,SAA2B,eAAe,SAAS,eAAe,SAClE,iBAAiB,SACjB,iBAAiB;AAKvB,UAAM,qBAAqB,KAAK,MAAM;AAEtC,QAAI,cAA8B;AAMlC,QAAI,kBAAkB;AAElB,YAAM,eAAe,GAAG;AAExB,YAAM,cAAc,OAAO,qBAAqB,WAC5C,SAAS,cAAc,gBAAgB,IAAI;AAE/C,UAAI,aAAa;AACb,sBAAc,WAAW,GAAG;AAC5B,YAAI,aAAa;AACb,sBAAY,gBAAgB,WAAW;QAC3C;MACJ;IACJ;AAEA,WAAO,yBAAyB,KAAK,SAAS,WAAW,WAAW;EACxE;AAyBO,WAAS,eAAe,SAA2C;AAEtE,UAAM,EAAE,KAAK,MAAM,SAAS,WAAW,UAAU,IAAI;AAErD,QAAI,SAAS,UAAa,QAAQ,QAAW;AACzC,YAAM,IAAI,MAAM,0DAA0D;IAC9E;AACA,QAAI,SAAS,UAAa,QAAQ,QAAW;AACzC,YAAM,IAAI,MAAM,oDAAoD;IACxE;AAEA,QAAI,SAAS,QAAW;AACpB,aAAO,mBAAmB,MAAM,SAAS,WAAW,SAAS;IACjE;AAGA,QAAI,WAAiC;AAMrC,QAAI,UAAsD,CAAC;AAC3D,QAAI,YAAY;AAEhB,UAAM,UAAU,CAAC,SAAuC;AACpD,UAAI,UAAU;AACV,aAAK,QAAQ;MACjB,WAAW,SAAS;AAChB,gBAAQ,KAAK,IAAI;MACrB;IACJ;AAEA,UAAM,GAAI,EAAE,KAAK,CAAA,QAAO,IAAI,KAAK,CAAC,EAAE,KAAK,CAAA,SAAQ;AAC7C,UAAI,UAAW;AACf,UAAI,sBAAsB,IAAI,GAAG;AAC7B,mBAAW,mBAAmB,MAAM,SAAS,WAAW,SAAS;AACjE,cAAM,SAAS;AACf,kBAAU;AACV,kBAAA,OAAA,SAAA,OAAQ,QAAQ,CAAA,SAAQ,KAAK,QAAS,CAAA;MAC1C,OAAO;AACH,gBAAQ,MAAM,2DAA2D,MAAM,GAAG;MACtF;IACJ,CAAC,EAAE,MAAM,CAAA,QAAO;AACZ,gBAAU;AACV,cAAQ,MAAM,qCAAqC,MAAM,KAAK,GAAG;IACrE,CAAC;AAGD,WAAO;MACH,WAAW,MAAM,CAAC,CAAC;MACnB,kBAAkB,MAAM,WAAW,SAAS,eAAe,IAAI;MAC/D,aAAa,OAAM,YAAA,OAAA,SAAA,SAAU,UAAA,MAAe;MAC5C,QAAQ,MAAM;AAAE,gBAAQ,CAAA,QAAO,IAAI,KAAK,CAAC;MAAG;MAC5C,SAAS,MAAM;AAAE,gBAAQ,CAAA,QAAO,IAAI,MAAM,CAAC;MAAG;MAC9C,UAAU,MAAM;AAAE,gBAAQ,CAAA,QAAO,IAAI,OAAO,CAAC;MAAG;MAChD,UAAU,MAAM;AAAE,gBAAQ,CAAA,QAAO,IAAI,OAAO,CAAC;MAAG;MAChD,mBAAmB,CAAC,SAAiB;AAAE,gBAAQ,CAAA,QAAO,IAAI,gBAAgB,IAAI,CAAC;MAAG;MAClF,kBAAkB,MAAM,WAAW,SAAS,eAAe,IAAI;MAC/D,kBAAkB,CAAC,SAAiB;AAAE,gBAAQ,CAAA,QAAO,IAAI,eAAe,IAAI,CAAC;MAAG;MAChF,WAAW,MAAM;AACb,oBAAY;AACZ,kBAAU;AACV,oBAAA,OAAA,SAAA,SAAU,QAAA;MACd;IACJ;EACJ;AAMO,WAAS,mBAAmB;AAC/B,UAAM,WAAW,SAAS,iBAAiB,MAAM,wBAAwB,GAAG;AAC5E,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AACtC,YAAM,UAAU,SAAS,CAAC;AAC1B,UAAI,CAAE,QAAgB,iBAAiB,GAAG;AACtC,cAAM,MAAM,QAAQ,aAAa,qBAAqB;AACtD,YAAI,KAAK;AACJ,kBAAgB,iBAAiB,IAAI,eAAe,EAAE,KAAK,WAAW,QAAQ,CAAC;QACpF;MACJ;IACJ;EACJ;AAEA,MAAI,OAAO,WAAW,aAAa;AAC9B,WAAe,kBAAkB,IAAI;AACrC,WAAe,gBAAgB,IAAI;AACnC,WAAe,wBAAwB,IAAI;EAChD;;;AC/OA,MAAAC,gBAA6E;;;ACH7E,qBAAuB;AAEhB,WAAS,WAAW,GAAQ,GAAiB;AAEhD,QAAI,MAAM,EAAG,QAAO;AACpB,QAAI,KAAK,QAAQ,KAAK,KAAM,QAAO;AACnC,QAAI,OAAO,MAAM,YAAY,OAAO,MAAM,SAAU,QAAO;AAG3D,UAAM,OAAO,oBAAI,QAAQ;AAEzB,aAAS,OAAO,GAAQ,GAAiB;AAErC,UAAI,MAAM,EAAG,QAAO;AACpB,UAAI,KAAK,QAAQ,KAAK,KAAM,QAAO;AACnC,UAAI,OAAO,MAAM,YAAY,OAAO,MAAM,SAAU,QAAO;AAG3D,UAAI,KAAK,IAAI,CAAC,GAAG;AACb,cAAM,IAAI,MAAM,6BAA6B;AAAA,MACjD;AACA,WAAK,IAAI,CAAC;AAGV,YAAM,WAAW,MAAM,QAAQ,CAAC;AAChC,YAAM,WAAW,MAAM,QAAQ,CAAC;AAChC,UAAI,aAAa,SAAU,QAAO;AAElC,UAAI,UAAU;AACV,YAAI,EAAE,WAAW,EAAE,OAAQ,QAAO;AAClC,iBAAS,IAAI,GAAG,IAAI,EAAE,QAAQ,KAAK;AAC/B,cAAI,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC,EAAG,QAAO;AAAA,QACpC;AACA,eAAO;AAAA,MACX;AAGA,YAAM,QAAQ,OAAO,KAAK,CAAC;AAC3B,YAAM,QAAQ,OAAO,KAAK,CAAC;AAC3B,UAAI,MAAM,WAAW,MAAM,OAAQ,QAAO;AAE1C,iBAAW,OAAO,OAAO;AACrB,YAAI,CAAC,MAAM,SAAS,GAAG,EAAG,QAAO;AACjC,YAAI,CAAC,OAAO,EAAE,GAAG,GAAG,EAAE,GAAG,CAAC,EAAG,QAAO;AAAA,MACxC;AAEA,aAAO;AAAA,IACX;AAEA,WAAO,OAAO,GAAG,CAAC;AAAA,EACtB;AAQA,WAAS,aAAa,UAAsB,UAA+B;AACvE,QAAI,SAAS,WAAW,SAAS,OAAQ,QAAO;AAEhD,aAAS,IAAI,GAAG,IAAI,SAAS,QAAQ,KAAK;AAEtC,UAAI,SAAS,CAAC,MAAM,SAAS,CAAC,EAAG;AAGjC,UAAI,CAAC,WAAW,SAAS,CAAC,GAAG,SAAS,CAAC,CAAC,EAAG,QAAO;AAAA,IACtD;AAEA,WAAO;AAAA,EACX;AAMO,WAAS,kBAAkB,MAA0B;AACxD,UAAM,YAAQ,qBAGJ,IAAI;AAGd,QAAI,MAAM,YAAY,MAAM;AACxB,YAAM,UAAU;AAAA,QACZ,WAAW;AAAA,QACX;AAAA,MACJ;AACA,aAAO;AAAA,IACX;AAGA,QAAI,CAAC,aAAa,MAAM,QAAQ,MAAM,IAAI,GAAG;AAEzC,YAAM,UAAU;AAAA,QACZ,WAAW,MAAM,QAAQ,YAAY;AAAA,QACrC;AAAA,MACJ;AAAA,IACJ;AAEA,WAAO,MAAM,QAAQ;AAAA,EACzB;;;AD2YQ;AA5TD,WAAS,mBAAmB,aAAgD;AAC/E,UAAM,kBAAkB,oBAAI,IAAY;AAExC,UAAM,UAA6B;AAAA,MAC/B,aAAa,MAAM;AACf,eAAO;AAAA,MACX;AAAA,MACA,cAAc,CAAC,IAAI,UAAU,UAAU;AAEnC,mBAAW,6BAA6B,QAAQ;AAEhD,cAAM,WAAWC,aAAY,EAAE;AAE/B,cAAM,UAAU,YAAY,QAAQ,IAAI,EAAE;AAE1C,YAAI,CAAC,WAAW,CAAC,gBAAgB,IAAI,QAAQ,GAAG;AAC5C,0BAAgB,IAAI,QAAQ;AAC5B,kBAAQ,KAAK,mDAAmD,WAAW,GAAG;AAC9E,kBAAQ,KAAK,YAAY,OAAO;AAAA,QACpC;AAEA,YAAI,SAAS;AACT,kBAAQ,aAAa,UAAU,KAAK;AACpC,cAAI,iBAAiB,IAAI,QAAQ,GAAG;AAChC,YAAC,QAAwB,MAAM,QAAe,IAAI;AAAA,UACtD;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AACA,WAAO;AAAA,EACX;AAEO,WAASA,aAAY,IAAY;AACpC,WAAO,MAAM;AAAA,EACjB;AAOA,MAAM,0BAA4D,CAAC;AAAA,IAC/D;AAAA,IAAW;AAAA,IAAO;AAAA,IAAK;AAAA,IAAU;AAAA,IAAc;AAAA,EACnD,MAAM;AAEF,UAAM,eAAe,GAAG;AAExB,UAAM,kBAAc,sBAAO,oBAAI,IAAiB,CAAC;AAEjD,UAAMC,cAAa,CAAC,MAA0B,SAAS,UAA+B;AAClF,UAAI,CAAC,KAAM,QAAO;AAElB,YAAM,EAAE,MAAM,SAAS,MAAM,UAAU,GAAG,MAAM,IAAI;AAEpD,YAAM,YAAY,mBAAmB,KAAK;AAE1C,gBAAU,KAAK,IAAI,CAAC,UAAe;AAC/B,YAAI,KAAK,IAAI,EAAG,aAAY,QAAQ,IAAI,KAAK,IAAI,GAAG,KAAK;AAAA,MAE7D;AAGA,UAAI,QAAQ;AACR,YAAI,WAAW;AACX,oBAAU,WAAW,IAAI,UAAU,WAAW,IACxC,UAAU,WAAW,IAAI,MAAM,YAC/B;AAAA,QACV;AACA,YAAI,MAAO,WAAU,OAAO,IAAI;AAAA,MACpC;AAEA,iBAAO,6BAAc,MAAM,WAAW,UAAU,IAAI,WAASA,YAAW,KAAK,CAAC,CAAC;AAAA,IACnF;AAEA,UAAM,OAAO,MAAMA,YAAW,KAAK,IAAI,IAAI;AAG3C,iCAAU,MAAM;AAIZ,YAAM,KAAK,CAAC,MAA0C,WAAW,UAAU,MAAM;AAC7E,qBAAa,UAAU,IAAI,IAAI;AAC/B,YAAI,SAAU,cAAa,SAAS,SAAS;AAAA,MACjD;AACA,YAAM,YAAY;AAAA,QACd,QAAU,GAAG,QAAQ;AAAA,QACrB,SAAU,GAAG,WAAW,IAAI;AAAA,QAC5B,UAAU,GAAG,YAAY,IAAI;AAAA,QAC7B,UAAU,GAAG,YAAY,IAAI;AAAA,QAC7B,UAAU,GAAG,YAAY,IAAI;AAAA,MACjC;AAEA,UAAI,MAAiC,eAAe,EAAE,MAAM,KAAK,SAAS,mBAAmB,WAAW,GAAG,UAAU,CAAC;AACtH,mBAAa,UAAU;AAEvB,aAAO,MAAM;AACT,aAAK,QAAQ;AACb,qBAAa,UAAU;AAAA,MAC3B;AAAA,IACJ,GAAG,CAAC,KAAK,cAAc,YAAY,CAAC;AAEpC,WAAO;AAAA,EACX;AAGA,MAAM,8BAA8B,cAAAC,QAAM;AAAA,IACtC;AAAA,IACA,MAAM;AAAA;AAAA,EACV;AAiCA,MAAM,sBAAoD,CAAC;AAAA,IACvD;AAAA,IAAW;AAAA,IACX;AAAA,IAAK;AAAA,IAAU;AAAA,IAAM;AAAA,IAAO;AAAA,IAAM;AAAA,IAAQ;AAAA;AAAA,IAG1C;AAAA,IAAM;AAAA,IAAO;AAAA,IAAM;AAAA,IAAY;AAAA,IAAU;AAAA,IAAW;AAAA,IAEpD;AAAA,IAAS;AAAA,IAAW;AAAA,IAEpB;AAAA,IAAQ;AAAA,IAAQ;AAAA,IAAS;AAAA,IAAU;AAAA,IAAU;AAAA,EACjD,MAAM;AAGF,QAAI,WAAW;AACf,QAAI,QAAQ;AACR,iBAAW;AAAA,IACf,WAAW,UAAU;AACjB,iBAAW;AAAA,IACf,WAAW,SAAS,UAAa,WAAW,QAAW;AACnD,iBAAW;AAAA,IACf,WAAW,SAAS,UAAa,UAAU,QAAW;AAClD,iBAAW;AAAA,IACf;AAIA,QAAI,aAAa,2BAAsC;AACnD,YAAMC,WAAU,IAAI,UAAU,SAAS;AACvC,UACIA,YACAA,aAAY,gBACd;AACE,cAAM;AAAA,UACF,GAAG;AAAA,UACH,UAAU;AAAA,YACN,GAAG,IAAI;AAAA,YACP,SAAS;AAAA,cACL,GAAG,IAAI,UAAU;AAAA,cACjB,SAAS;AAAA;AAAA,YACb;AAAA,UACJ;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAGA,QACI,SAAS,UACT,aAAa,UACb,UAAU,UACV,eAAe,UACf,SAAS,UACT,cAAc,UACd,cAAc,QAChB;AACE,YAAM,WAAW,IAAI,YAAY,CAAC;AAClC,YAAM;AAAA,QACF,GAAG;AAAA,QACH,UAAU;AAAA,UACN,GAAG;AAAA,UACH,MAAM,SAAS,SAAY,OAAO,SAAS;AAAA,UAC3C,UAAU,aAAa,SAAY,WAAW,SAAS;AAAA,UACvD,OAAO,UAAU,SAAY,QAAQ,SAAS;AAAA,UAC9C,YAAY,eAAe,SAAY,aAAa,SAAS;AAAA,UAC7D,MAAM,SAAS,SAAY,OAAO,SAAS;AAAA,UAC3C,WAAW,cAAc,SAAY,YAAY,SAAS;AAAA,UAC1D,WAAW,cAAc,SAAY,YAAY,SAAS;AAAA,QAC9D;AAAA,MACJ;AAAA,IACJ;AAGA,QACI,YAAY,UACZ,cAAc,UACd,4BAA4B,QAC9B;AACE,YAAM,UAAqB,IAAI,UAAU,WAAW,CAAC;AACrD,YAAM;AAAA,QACF,GAAG;AAAA,QACH,UAAU;AAAA,UACN,GAAG,IAAI;AAAA,UACP,SAAS;AAAA,YACL,GAAG;AAAA,YACH,SAAS,YAAY,SAAY,UAAU,QAAQ;AAAA,YACnD,WAAW,cAAc,SAAY,YAAY,QAAQ;AAAA,YACzD,yBAAyB,4BAA4B,SAAY,0BAA0B,QAAQ;AAAA,UACvG;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAOA,QAAI;AACJ,QAAI,aAAa,6BAAuC;AACpD,YAAM,WAAW,IAAI,YAAY,CAAC;AAClC,UAAI,SAAS,QAAW;AACpB,cAAM,kBAAkB,cAAc,SAAS;AAC/C,cAAM,kBAAkB,OAAO,oBAAoB,YAAY,mBAAmB,IAAI,kBAAkB;AACxG,cAAM,iBAAiB,YAAY,SAAS,YAAY;AACxD,iBAAS,OAAO,iBAAiB;AAAA,MACrC;AACA,UAAI,WAAW,OAAW,UAAS;AAAA,IACvC;AAEA,UAAM,mBAAe,sBAA6B,IAAI;AAGtD,UAAM,mBAAe,sBAAqC,CAAC,CAAC;AAC5D,iBAAa,UAAU,EAAE,QAAQ,QAAQ,SAAS,UAAU,UAAU,SAAS;AAG/E,2CAAoB,QAAQ,MAAM;AAC9B,aAAO;AAAA,QACH,WAAW,MAAM,aAAa,SAAS,UAAU,KAAK;AAAA,QACtD,MAAM,MAAM,aAAa,SAAS,KAAK;AAAA,QACvC,OAAO,MAAM,aAAa,SAAS,MAAM;AAAA,QACzC,QAAQ,MAAM,aAAa,SAAS,OAAO;AAAA,QAC3C,QAAQ,MAAM,aAAa,SAAS,OAAO;AAAA,QAC3C,iBAAiB,CAAC,SAAiB,aAAa,SAAS,gBAAgB,IAAI;AAAA,QAC7E,gBAAgB,MAAM,aAAa,SAAS,eAAe,KAAK;AAAA,QAChE,gBAAgB,CAACC,UAAiB,aAAa,SAAS,eAAeA,KAAI;AAAA,MAC/E;AAAA,IACJ,GAAG,CAAC,CAAC;AAIL,UAAM,MAAM,eAAe,UAAU,KAAK,WAAW,KAAK;AAI1D,iCAAU,MAAM;AAEZ,UAAI,aAAa,mBAAkC;AAC/C,YAAI,QAAQ,CAAC,OAAO;AAChB,uBAAa,SAAS,KAAK;AAAA,QAC/B,WAAW,OAAO;AACd,uBAAa,SAAS,MAAM;AAAA,QAChC,WAAW,SAAS,OAAO;AAEvB,uBAAa,SAAS,OAAO;AAAA,QACjC,OAAO;AAEH,uBAAa,SAAS,KAAK;AAAA,QAC/B;AAAA,MACJ;AAEA,aAAO,MAAM;AACT,YAAI,aAAa,mBAAkC;AAO/C,uBAAa,SAAS,MAAM;AAAA,QAChC;AAAA,MACJ;AAAA,IACJ,GAAG,CAAC,UAAU,MAAM,OAAO,GAAG,CAAC;AAI/B,iCAAU,MAAM;AACZ,UAAI,aAAa,+BAAyC,WAAW,QAAW;AAC5E,qBAAa,SAAS,eAAe,MAAM;AAC3C,qBAAa,SAAS,MAAM;AAAA,MAChC;AAAA,IACJ,GAAG,CAAC,UAAU,QAAQ,GAAG,CAAC;AAE1B,WACI;AAAA,MAAC;AAAA;AAAA,QAEG;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA;AAAA,MANK;AAAA,IAOT;AAAA,EAER;AAEA,MAAO,8BAAQ;;;AE3ff,MAAAC,gBAA0E;AA6ElE,MAAAC,sBAAA;AAvCR,MAAM,yBAMD,CAAC,EAAE,WAAW,OAAO,UAAU,UAAU,QAAQ,YAAY,WAAW,MAAM;AAE/E,UAAM,CAAC,OAAO,QAAQ,QAAI,wBAAoB,YAAY,SAAS,YAAY,MAAM;AAErF,UAAM,UAAM,sBAAuB,IAAI;AAEvC,iCAAU,MAAM;AACZ,UAAI,YAAY,iBAAkB;AAClC,YAAM,KAAK,IAAI;AACf,UAAI,CAAC,GAAI;AACT,YAAM,WACF,cAAc,UAAU,SACpB,cAAc,UAAU,WAAW;AAE3C,YAAM,WAAW,IAAI;AAAA,QACjB,CAAC,CAAC,KAAK,MAAM,SAAS,MAAM,iBAAiB,YAAY,QAAQ;AAAA,QACjE,EAAE,WAAW,IAAI;AAAA,MACrB;AACA,eAAS,QAAQ,EAAE;AACnB,aAAO,MAAM,SAAS,WAAW;AAAA,IACrC,GAAG,CAAC,SAAS,SAAS,CAAC;AAEvB,UAAM,QAAQ,MAAM;AAAA,MAChB,cAAc,UAAU,SACpB,cAAc,UAAU,WAAW;AAAA,IAC3C;AAEA,UAAM,WACF,YAAY,cAAc,EAAE,cAAc,MAAM,SAAS,SAAS,GAAG,cAAc,MAAM,IACrF,YAAY,UAAU,EAAE,SAAS,MAAM,UAAU,YAAY,MAAM,IAAI,SAAS,SAAS,EAAE,IACvF,CAAC;AAEb,WACI;AAAA,MAAC;AAAA;AAAA,QACG;AAAA,QACA,WAAW;AAAA,UACP;AAAA,UACA,UAAU,YAAY,oCAClB,UAAU,WAAW,oBAAoB;AAAA,QACjD,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,QAC1B;AAAA,QACC,GAAG;AAAA,QAEH;AAAA;AAAA,IACL;AAAA,EAER;AACA,MAAO,iCAAQ;","names":["React","__spreadValues","__spreadValues","__spreadProps","__spreadValues","__spreadProps","__spreadValues","str","pathStr","_a","_b","out","num","genId","walkAndMaterialise","clone","stripHash","kfs","remap","clamp","resolveStyle","_c","_d","resolveStyle","__spreadProps","__spreadValues","__spreadProps","__spreadValues","v","stripHash","effectiveProgress","_a","_a","import_react","getSelector","renderNode","React","startOn","time","import_react","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../../../node_modules/.pnpm/react@19.2.4/node_modules/react/cjs/react.production.js","../../../node_modules/.pnpm/react@19.2.4/node_modules/react/cjs/react.development.js","../../../node_modules/.pnpm/react@19.2.4/node_modules/react/index.js","../../../node_modules/.pnpm/react@19.2.4/node_modules/react/cjs/react-jsx-runtime.production.js","../../../node_modules/.pnpm/react@19.2.4/node_modules/react/cjs/react-jsx-runtime.development.js","../../../node_modules/.pnpm/react@19.2.4/node_modules/react/jsx-runtime.js","../src/index.ts","../../svg-animator-core/src/PxSchema.ts","../../svg-animator-core/src/PxAnimatorTypes.ts","../../svg-animator-core/src/PxAnimatorUtil.ts","../../svg-animator-core/src/PxIdUtil.ts","../../svg-animator-core/src/PxNodeProps.ts","../../svg-animator-core/src/PxMotionPath.ts","../../svg-animator-core/src/PxDefinitions.ts","../../svg-animator-core/src/PxNodeCloneUtil.ts","../../svg-animator-core/src/PxAnimatorUseMaterialiser.ts","../../svg-animator-core/src/effects/transformParts.ts","../../svg-animator-core/src/effects/transformationEffect.ts","../../svg-animator-core/src/effects/contentRefSplit.ts","../../svg-animator-core/src/effects/util.ts","../../svg-animator-core/src/effects/gradientEffect.ts","../../svg-animator-core/src/effects/clipPathEffect.ts","../../svg-animator-core/src/effects/maskedByEffect.ts","../../svg-animator-core/src/effects/refEffect.ts","../../svg-animator-core/src/effects/repeaterEffect.ts","../../svg-animator-core/src/effects/retimeEffect.ts","../../svg-animator-core/src/effects/pathSampler.ts","../../svg-animator-core/src/effects/textPathEffect.ts","../../svg-animator-core/src/effects/elementFactory.ts","../../svg-animator-core/src/effects/glyphPathBake.ts","../../svg-animator-core/src/effects/textGlyphsEffect.ts","../../svg-animator-core/src/effects/trimPathEffect.ts","../../svg-animator-core/src/effects/PlayerEffectsUtil.ts","../../svg-animator-core/src/PxAnimatorMaterialiseAll.ts","../../svg-animator-core/src/PxFrameLoop.ts","../../svg-animator-core/src/effects/PlayerEffectsUtil.visualModel.ts","../../svg-animator-web/src/PxAnimatorDOM.ts","../../svg-animator-web/src/PxAnimatorTriggers.ts","../../svg-animator-web/src/PxAnimatorFrameLoop.ts","../../svg-animator-web/src/PxAnimatorWebApi.ts","../../svg-animator-web/src/PxAnimator.ts","../src/PixodeskSvgAnimator.tsx","../src/Utils.ts","../src/PixodeskSvgCssAnimator.tsx"],"sourcesContent":["/**\n * @license React\n * react.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\"),\n REACT_STRICT_MODE_TYPE = Symbol.for(\"react.strict_mode\"),\n REACT_PROFILER_TYPE = Symbol.for(\"react.profiler\"),\n REACT_CONSUMER_TYPE = Symbol.for(\"react.consumer\"),\n REACT_CONTEXT_TYPE = Symbol.for(\"react.context\"),\n REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\"),\n REACT_SUSPENSE_TYPE = Symbol.for(\"react.suspense\"),\n REACT_MEMO_TYPE = Symbol.for(\"react.memo\"),\n REACT_LAZY_TYPE = Symbol.for(\"react.lazy\"),\n REACT_ACTIVITY_TYPE = Symbol.for(\"react.activity\"),\n MAYBE_ITERATOR_SYMBOL = Symbol.iterator;\nfunction getIteratorFn(maybeIterable) {\n if (null === maybeIterable || \"object\" !== typeof maybeIterable) return null;\n maybeIterable =\n (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) ||\n maybeIterable[\"@@iterator\"];\n return \"function\" === typeof maybeIterable ? maybeIterable : null;\n}\nvar ReactNoopUpdateQueue = {\n isMounted: function () {\n return !1;\n },\n enqueueForceUpdate: function () {},\n enqueueReplaceState: function () {},\n enqueueSetState: function () {}\n },\n assign = Object.assign,\n emptyObject = {};\nfunction Component(props, context, updater) {\n this.props = props;\n this.context = context;\n this.refs = emptyObject;\n this.updater = updater || ReactNoopUpdateQueue;\n}\nComponent.prototype.isReactComponent = {};\nComponent.prototype.setState = function (partialState, callback) {\n if (\n \"object\" !== typeof partialState &&\n \"function\" !== typeof partialState &&\n null != partialState\n )\n throw Error(\n \"takes an object of state variables to update or a function which returns an object of state variables.\"\n );\n this.updater.enqueueSetState(this, partialState, callback, \"setState\");\n};\nComponent.prototype.forceUpdate = function (callback) {\n this.updater.enqueueForceUpdate(this, callback, \"forceUpdate\");\n};\nfunction ComponentDummy() {}\nComponentDummy.prototype = Component.prototype;\nfunction PureComponent(props, context, updater) {\n this.props = props;\n this.context = context;\n this.refs = emptyObject;\n this.updater = updater || ReactNoopUpdateQueue;\n}\nvar pureComponentPrototype = (PureComponent.prototype = new ComponentDummy());\npureComponentPrototype.constructor = PureComponent;\nassign(pureComponentPrototype, Component.prototype);\npureComponentPrototype.isPureReactComponent = !0;\nvar isArrayImpl = Array.isArray;\nfunction noop() {}\nvar ReactSharedInternals = { H: null, A: null, T: null, S: null },\n hasOwnProperty = Object.prototype.hasOwnProperty;\nfunction ReactElement(type, key, props) {\n var refProp = props.ref;\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n ref: void 0 !== refProp ? refProp : null,\n props: props\n };\n}\nfunction cloneAndReplaceKey(oldElement, newKey) {\n return ReactElement(oldElement.type, newKey, oldElement.props);\n}\nfunction isValidElement(object) {\n return (\n \"object\" === typeof object &&\n null !== object &&\n object.$$typeof === REACT_ELEMENT_TYPE\n );\n}\nfunction escape(key) {\n var escaperLookup = { \"=\": \"=0\", \":\": \"=2\" };\n return (\n \"$\" +\n key.replace(/[=:]/g, function (match) {\n return escaperLookup[match];\n })\n );\n}\nvar userProvidedKeyEscapeRegex = /\\/+/g;\nfunction getElementKey(element, index) {\n return \"object\" === typeof element && null !== element && null != element.key\n ? escape(\"\" + element.key)\n : index.toString(36);\n}\nfunction resolveThenable(thenable) {\n switch (thenable.status) {\n case \"fulfilled\":\n return thenable.value;\n case \"rejected\":\n throw thenable.reason;\n default:\n switch (\n (\"string\" === typeof thenable.status\n ? thenable.then(noop, noop)\n : ((thenable.status = \"pending\"),\n thenable.then(\n function (fulfilledValue) {\n \"pending\" === thenable.status &&\n ((thenable.status = \"fulfilled\"),\n (thenable.value = fulfilledValue));\n },\n function (error) {\n \"pending\" === thenable.status &&\n ((thenable.status = \"rejected\"), (thenable.reason = error));\n }\n )),\n thenable.status)\n ) {\n case \"fulfilled\":\n return thenable.value;\n case \"rejected\":\n throw thenable.reason;\n }\n }\n throw thenable;\n}\nfunction mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) {\n var type = typeof children;\n if (\"undefined\" === type || \"boolean\" === type) children = null;\n var invokeCallback = !1;\n if (null === children) invokeCallback = !0;\n else\n switch (type) {\n case \"bigint\":\n case \"string\":\n case \"number\":\n invokeCallback = !0;\n break;\n case \"object\":\n switch (children.$$typeof) {\n case REACT_ELEMENT_TYPE:\n case REACT_PORTAL_TYPE:\n invokeCallback = !0;\n break;\n case REACT_LAZY_TYPE:\n return (\n (invokeCallback = children._init),\n mapIntoArray(\n invokeCallback(children._payload),\n array,\n escapedPrefix,\n nameSoFar,\n callback\n )\n );\n }\n }\n if (invokeCallback)\n return (\n (callback = callback(children)),\n (invokeCallback =\n \"\" === nameSoFar ? \".\" + getElementKey(children, 0) : nameSoFar),\n isArrayImpl(callback)\n ? ((escapedPrefix = \"\"),\n null != invokeCallback &&\n (escapedPrefix =\n invokeCallback.replace(userProvidedKeyEscapeRegex, \"$&/\") + \"/\"),\n mapIntoArray(callback, array, escapedPrefix, \"\", function (c) {\n return c;\n }))\n : null != callback &&\n (isValidElement(callback) &&\n (callback = cloneAndReplaceKey(\n callback,\n escapedPrefix +\n (null == callback.key ||\n (children && children.key === callback.key)\n ? \"\"\n : (\"\" + callback.key).replace(\n userProvidedKeyEscapeRegex,\n \"$&/\"\n ) + \"/\") +\n invokeCallback\n )),\n array.push(callback)),\n 1\n );\n invokeCallback = 0;\n var nextNamePrefix = \"\" === nameSoFar ? \".\" : nameSoFar + \":\";\n if (isArrayImpl(children))\n for (var i = 0; i < children.length; i++)\n (nameSoFar = children[i]),\n (type = nextNamePrefix + getElementKey(nameSoFar, i)),\n (invokeCallback += mapIntoArray(\n nameSoFar,\n array,\n escapedPrefix,\n type,\n callback\n ));\n else if (((i = getIteratorFn(children)), \"function\" === typeof i))\n for (\n children = i.call(children), i = 0;\n !(nameSoFar = children.next()).done;\n\n )\n (nameSoFar = nameSoFar.value),\n (type = nextNamePrefix + getElementKey(nameSoFar, i++)),\n (invokeCallback += mapIntoArray(\n nameSoFar,\n array,\n escapedPrefix,\n type,\n callback\n ));\n else if (\"object\" === type) {\n if (\"function\" === typeof children.then)\n return mapIntoArray(\n resolveThenable(children),\n array,\n escapedPrefix,\n nameSoFar,\n callback\n );\n array = String(children);\n throw Error(\n \"Objects are not valid as a React child (found: \" +\n (\"[object Object]\" === array\n ? \"object with keys {\" + Object.keys(children).join(\", \") + \"}\"\n : array) +\n \"). If you meant to render a collection of children, use an array instead.\"\n );\n }\n return invokeCallback;\n}\nfunction mapChildren(children, func, context) {\n if (null == children) return children;\n var result = [],\n count = 0;\n mapIntoArray(children, result, \"\", \"\", function (child) {\n return func.call(context, child, count++);\n });\n return result;\n}\nfunction lazyInitializer(payload) {\n if (-1 === payload._status) {\n var ctor = payload._result;\n ctor = ctor();\n ctor.then(\n function (moduleObject) {\n if (0 === payload._status || -1 === payload._status)\n (payload._status = 1), (payload._result = moduleObject);\n },\n function (error) {\n if (0 === payload._status || -1 === payload._status)\n (payload._status = 2), (payload._result = error);\n }\n );\n -1 === payload._status && ((payload._status = 0), (payload._result = ctor));\n }\n if (1 === payload._status) return payload._result.default;\n throw payload._result;\n}\nvar reportGlobalError =\n \"function\" === typeof reportError\n ? reportError\n : function (error) {\n if (\n \"object\" === typeof window &&\n \"function\" === typeof window.ErrorEvent\n ) {\n var event = new window.ErrorEvent(\"error\", {\n bubbles: !0,\n cancelable: !0,\n message:\n \"object\" === typeof error &&\n null !== error &&\n \"string\" === typeof error.message\n ? String(error.message)\n : String(error),\n error: error\n });\n if (!window.dispatchEvent(event)) return;\n } else if (\n \"object\" === typeof process &&\n \"function\" === typeof process.emit\n ) {\n process.emit(\"uncaughtException\", error);\n return;\n }\n console.error(error);\n },\n Children = {\n map: mapChildren,\n forEach: function (children, forEachFunc, forEachContext) {\n mapChildren(\n children,\n function () {\n forEachFunc.apply(this, arguments);\n },\n forEachContext\n );\n },\n count: function (children) {\n var n = 0;\n mapChildren(children, function () {\n n++;\n });\n return n;\n },\n toArray: function (children) {\n return (\n mapChildren(children, function (child) {\n return child;\n }) || []\n );\n },\n only: function (children) {\n if (!isValidElement(children))\n throw Error(\n \"React.Children.only expected to receive a single React element child.\"\n );\n return children;\n }\n };\nexports.Activity = REACT_ACTIVITY_TYPE;\nexports.Children = Children;\nexports.Component = Component;\nexports.Fragment = REACT_FRAGMENT_TYPE;\nexports.Profiler = REACT_PROFILER_TYPE;\nexports.PureComponent = PureComponent;\nexports.StrictMode = REACT_STRICT_MODE_TYPE;\nexports.Suspense = REACT_SUSPENSE_TYPE;\nexports.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE =\n ReactSharedInternals;\nexports.__COMPILER_RUNTIME = {\n __proto__: null,\n c: function (size) {\n return ReactSharedInternals.H.useMemoCache(size);\n }\n};\nexports.cache = function (fn) {\n return function () {\n return fn.apply(null, arguments);\n };\n};\nexports.cacheSignal = function () {\n return null;\n};\nexports.cloneElement = function (element, config, children) {\n if (null === element || void 0 === element)\n throw Error(\n \"The argument must be a React element, but you passed \" + element + \".\"\n );\n var props = assign({}, element.props),\n key = element.key;\n if (null != config)\n for (propName in (void 0 !== config.key && (key = \"\" + config.key), config))\n !hasOwnProperty.call(config, propName) ||\n \"key\" === propName ||\n \"__self\" === propName ||\n \"__source\" === propName ||\n (\"ref\" === propName && void 0 === config.ref) ||\n (props[propName] = config[propName]);\n var propName = arguments.length - 2;\n if (1 === propName) props.children = children;\n else if (1 < propName) {\n for (var childArray = Array(propName), i = 0; i < propName; i++)\n childArray[i] = arguments[i + 2];\n props.children = childArray;\n }\n return ReactElement(element.type, key, props);\n};\nexports.createContext = function (defaultValue) {\n defaultValue = {\n $$typeof: REACT_CONTEXT_TYPE,\n _currentValue: defaultValue,\n _currentValue2: defaultValue,\n _threadCount: 0,\n Provider: null,\n Consumer: null\n };\n defaultValue.Provider = defaultValue;\n defaultValue.Consumer = {\n $$typeof: REACT_CONSUMER_TYPE,\n _context: defaultValue\n };\n return defaultValue;\n};\nexports.createElement = function (type, config, children) {\n var propName,\n props = {},\n key = null;\n if (null != config)\n for (propName in (void 0 !== config.key && (key = \"\" + config.key), config))\n hasOwnProperty.call(config, propName) &&\n \"key\" !== propName &&\n \"__self\" !== propName &&\n \"__source\" !== propName &&\n (props[propName] = config[propName]);\n var childrenLength = arguments.length - 2;\n if (1 === childrenLength) props.children = children;\n else if (1 < childrenLength) {\n for (var childArray = Array(childrenLength), i = 0; i < childrenLength; i++)\n childArray[i] = arguments[i + 2];\n props.children = childArray;\n }\n if (type && type.defaultProps)\n for (propName in ((childrenLength = type.defaultProps), childrenLength))\n void 0 === props[propName] &&\n (props[propName] = childrenLength[propName]);\n return ReactElement(type, key, props);\n};\nexports.createRef = function () {\n return { current: null };\n};\nexports.forwardRef = function (render) {\n return { $$typeof: REACT_FORWARD_REF_TYPE, render: render };\n};\nexports.isValidElement = isValidElement;\nexports.lazy = function (ctor) {\n return {\n $$typeof: REACT_LAZY_TYPE,\n _payload: { _status: -1, _result: ctor },\n _init: lazyInitializer\n };\n};\nexports.memo = function (type, compare) {\n return {\n $$typeof: REACT_MEMO_TYPE,\n type: type,\n compare: void 0 === compare ? null : compare\n };\n};\nexports.startTransition = function (scope) {\n var prevTransition = ReactSharedInternals.T,\n currentTransition = {};\n ReactSharedInternals.T = currentTransition;\n try {\n var returnValue = scope(),\n onStartTransitionFinish = ReactSharedInternals.S;\n null !== onStartTransitionFinish &&\n onStartTransitionFinish(currentTransition, returnValue);\n \"object\" === typeof returnValue &&\n null !== returnValue &&\n \"function\" === typeof returnValue.then &&\n returnValue.then(noop, reportGlobalError);\n } catch (error) {\n reportGlobalError(error);\n } finally {\n null !== prevTransition &&\n null !== currentTransition.types &&\n (prevTransition.types = currentTransition.types),\n (ReactSharedInternals.T = prevTransition);\n }\n};\nexports.unstable_useCacheRefresh = function () {\n return ReactSharedInternals.H.useCacheRefresh();\n};\nexports.use = function (usable) {\n return ReactSharedInternals.H.use(usable);\n};\nexports.useActionState = function (action, initialState, permalink) {\n return ReactSharedInternals.H.useActionState(action, initialState, permalink);\n};\nexports.useCallback = function (callback, deps) {\n return ReactSharedInternals.H.useCallback(callback, deps);\n};\nexports.useContext = function (Context) {\n return ReactSharedInternals.H.useContext(Context);\n};\nexports.useDebugValue = function () {};\nexports.useDeferredValue = function (value, initialValue) {\n return ReactSharedInternals.H.useDeferredValue(value, initialValue);\n};\nexports.useEffect = function (create, deps) {\n return ReactSharedInternals.H.useEffect(create, deps);\n};\nexports.useEffectEvent = function (callback) {\n return ReactSharedInternals.H.useEffectEvent(callback);\n};\nexports.useId = function () {\n return ReactSharedInternals.H.useId();\n};\nexports.useImperativeHandle = function (ref, create, deps) {\n return ReactSharedInternals.H.useImperativeHandle(ref, create, deps);\n};\nexports.useInsertionEffect = function (create, deps) {\n return ReactSharedInternals.H.useInsertionEffect(create, deps);\n};\nexports.useLayoutEffect = function (create, deps) {\n return ReactSharedInternals.H.useLayoutEffect(create, deps);\n};\nexports.useMemo = function (create, deps) {\n return ReactSharedInternals.H.useMemo(create, deps);\n};\nexports.useOptimistic = function (passthrough, reducer) {\n return ReactSharedInternals.H.useOptimistic(passthrough, reducer);\n};\nexports.useReducer = function (reducer, initialArg, init) {\n return ReactSharedInternals.H.useReducer(reducer, initialArg, init);\n};\nexports.useRef = function (initialValue) {\n return ReactSharedInternals.H.useRef(initialValue);\n};\nexports.useState = function (initialState) {\n return ReactSharedInternals.H.useState(initialState);\n};\nexports.useSyncExternalStore = function (\n subscribe,\n getSnapshot,\n getServerSnapshot\n) {\n return ReactSharedInternals.H.useSyncExternalStore(\n subscribe,\n getSnapshot,\n getServerSnapshot\n );\n};\nexports.useTransition = function () {\n return ReactSharedInternals.H.useTransition();\n};\nexports.version = \"19.2.4\";\n","/**\n * @license React\n * react.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n (function () {\n function defineDeprecationWarning(methodName, info) {\n Object.defineProperty(Component.prototype, methodName, {\n get: function () {\n console.warn(\n \"%s(...) is deprecated in plain JavaScript React classes. %s\",\n info[0],\n info[1]\n );\n }\n });\n }\n function getIteratorFn(maybeIterable) {\n if (null === maybeIterable || \"object\" !== typeof maybeIterable)\n return null;\n maybeIterable =\n (MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL]) ||\n maybeIterable[\"@@iterator\"];\n return \"function\" === typeof maybeIterable ? maybeIterable : null;\n }\n function warnNoop(publicInstance, callerName) {\n publicInstance =\n ((publicInstance = publicInstance.constructor) &&\n (publicInstance.displayName || publicInstance.name)) ||\n \"ReactClass\";\n var warningKey = publicInstance + \".\" + callerName;\n didWarnStateUpdateForUnmountedComponent[warningKey] ||\n (console.error(\n \"Can't call %s on a component that is not yet mounted. This is a no-op, but it might indicate a bug in your application. Instead, assign to `this.state` directly or define a `state = {};` class property with the desired state in the %s component.\",\n callerName,\n publicInstance\n ),\n (didWarnStateUpdateForUnmountedComponent[warningKey] = !0));\n }\n function Component(props, context, updater) {\n this.props = props;\n this.context = context;\n this.refs = emptyObject;\n this.updater = updater || ReactNoopUpdateQueue;\n }\n function ComponentDummy() {}\n function PureComponent(props, context, updater) {\n this.props = props;\n this.context = context;\n this.refs = emptyObject;\n this.updater = updater || ReactNoopUpdateQueue;\n }\n function noop() {}\n function testStringCoercion(value) {\n return \"\" + value;\n }\n function checkKeyStringCoercion(value) {\n try {\n testStringCoercion(value);\n var JSCompiler_inline_result = !1;\n } catch (e) {\n JSCompiler_inline_result = !0;\n }\n if (JSCompiler_inline_result) {\n JSCompiler_inline_result = console;\n var JSCompiler_temp_const = JSCompiler_inline_result.error;\n var JSCompiler_inline_result$jscomp$0 =\n (\"function\" === typeof Symbol &&\n Symbol.toStringTag &&\n value[Symbol.toStringTag]) ||\n value.constructor.name ||\n \"Object\";\n JSCompiler_temp_const.call(\n JSCompiler_inline_result,\n \"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.\",\n JSCompiler_inline_result$jscomp$0\n );\n return testStringCoercion(value);\n }\n }\n function getComponentNameFromType(type) {\n if (null == type) return null;\n if (\"function\" === typeof type)\n return type.$$typeof === REACT_CLIENT_REFERENCE\n ? null\n : type.displayName || type.name || null;\n if (\"string\" === typeof type) return type;\n switch (type) {\n case REACT_FRAGMENT_TYPE:\n return \"Fragment\";\n case REACT_PROFILER_TYPE:\n return \"Profiler\";\n case REACT_STRICT_MODE_TYPE:\n return \"StrictMode\";\n case REACT_SUSPENSE_TYPE:\n return \"Suspense\";\n case REACT_SUSPENSE_LIST_TYPE:\n return \"SuspenseList\";\n case REACT_ACTIVITY_TYPE:\n return \"Activity\";\n }\n if (\"object\" === typeof type)\n switch (\n (\"number\" === typeof type.tag &&\n console.error(\n \"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.\"\n ),\n type.$$typeof)\n ) {\n case REACT_PORTAL_TYPE:\n return \"Portal\";\n case REACT_CONTEXT_TYPE:\n return type.displayName || \"Context\";\n case REACT_CONSUMER_TYPE:\n return (type._context.displayName || \"Context\") + \".Consumer\";\n case REACT_FORWARD_REF_TYPE:\n var innerType = type.render;\n type = type.displayName;\n type ||\n ((type = innerType.displayName || innerType.name || \"\"),\n (type = \"\" !== type ? \"ForwardRef(\" + type + \")\" : \"ForwardRef\"));\n return type;\n case REACT_MEMO_TYPE:\n return (\n (innerType = type.displayName || null),\n null !== innerType\n ? innerType\n : getComponentNameFromType(type.type) || \"Memo\"\n );\n case REACT_LAZY_TYPE:\n innerType = type._payload;\n type = type._init;\n try {\n return getComponentNameFromType(type(innerType));\n } catch (x) {}\n }\n return null;\n }\n function getTaskName(type) {\n if (type === REACT_FRAGMENT_TYPE) return \"<>\";\n if (\n \"object\" === typeof type &&\n null !== type &&\n type.$$typeof === REACT_LAZY_TYPE\n )\n return \"<...>\";\n try {\n var name = getComponentNameFromType(type);\n return name ? \"<\" + name + \">\" : \"<...>\";\n } catch (x) {\n return \"<...>\";\n }\n }\n function getOwner() {\n var dispatcher = ReactSharedInternals.A;\n return null === dispatcher ? null : dispatcher.getOwner();\n }\n function UnknownOwner() {\n return Error(\"react-stack-top-frame\");\n }\n function hasValidKey(config) {\n if (hasOwnProperty.call(config, \"key\")) {\n var getter = Object.getOwnPropertyDescriptor(config, \"key\").get;\n if (getter && getter.isReactWarning) return !1;\n }\n return void 0 !== config.key;\n }\n function defineKeyPropWarningGetter(props, displayName) {\n function warnAboutAccessingKey() {\n specialPropKeyWarningShown ||\n ((specialPropKeyWarningShown = !0),\n console.error(\n \"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)\",\n displayName\n ));\n }\n warnAboutAccessingKey.isReactWarning = !0;\n Object.defineProperty(props, \"key\", {\n get: warnAboutAccessingKey,\n configurable: !0\n });\n }\n function elementRefGetterWithDeprecationWarning() {\n var componentName = getComponentNameFromType(this.type);\n didWarnAboutElementRef[componentName] ||\n ((didWarnAboutElementRef[componentName] = !0),\n console.error(\n \"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.\"\n ));\n componentName = this.props.ref;\n return void 0 !== componentName ? componentName : null;\n }\n function ReactElement(type, key, props, owner, debugStack, debugTask) {\n var refProp = props.ref;\n type = {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n props: props,\n _owner: owner\n };\n null !== (void 0 !== refProp ? refProp : null)\n ? Object.defineProperty(type, \"ref\", {\n enumerable: !1,\n get: elementRefGetterWithDeprecationWarning\n })\n : Object.defineProperty(type, \"ref\", { enumerable: !1, value: null });\n type._store = {};\n Object.defineProperty(type._store, \"validated\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: 0\n });\n Object.defineProperty(type, \"_debugInfo\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: null\n });\n Object.defineProperty(type, \"_debugStack\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugStack\n });\n Object.defineProperty(type, \"_debugTask\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugTask\n });\n Object.freeze && (Object.freeze(type.props), Object.freeze(type));\n return type;\n }\n function cloneAndReplaceKey(oldElement, newKey) {\n newKey = ReactElement(\n oldElement.type,\n newKey,\n oldElement.props,\n oldElement._owner,\n oldElement._debugStack,\n oldElement._debugTask\n );\n oldElement._store &&\n (newKey._store.validated = oldElement._store.validated);\n return newKey;\n }\n function validateChildKeys(node) {\n isValidElement(node)\n ? node._store && (node._store.validated = 1)\n : \"object\" === typeof node &&\n null !== node &&\n node.$$typeof === REACT_LAZY_TYPE &&\n (\"fulfilled\" === node._payload.status\n ? isValidElement(node._payload.value) &&\n node._payload.value._store &&\n (node._payload.value._store.validated = 1)\n : node._store && (node._store.validated = 1));\n }\n function isValidElement(object) {\n return (\n \"object\" === typeof object &&\n null !== object &&\n object.$$typeof === REACT_ELEMENT_TYPE\n );\n }\n function escape(key) {\n var escaperLookup = { \"=\": \"=0\", \":\": \"=2\" };\n return (\n \"$\" +\n key.replace(/[=:]/g, function (match) {\n return escaperLookup[match];\n })\n );\n }\n function getElementKey(element, index) {\n return \"object\" === typeof element &&\n null !== element &&\n null != element.key\n ? (checkKeyStringCoercion(element.key), escape(\"\" + element.key))\n : index.toString(36);\n }\n function resolveThenable(thenable) {\n switch (thenable.status) {\n case \"fulfilled\":\n return thenable.value;\n case \"rejected\":\n throw thenable.reason;\n default:\n switch (\n (\"string\" === typeof thenable.status\n ? thenable.then(noop, noop)\n : ((thenable.status = \"pending\"),\n thenable.then(\n function (fulfilledValue) {\n \"pending\" === thenable.status &&\n ((thenable.status = \"fulfilled\"),\n (thenable.value = fulfilledValue));\n },\n function (error) {\n \"pending\" === thenable.status &&\n ((thenable.status = \"rejected\"),\n (thenable.reason = error));\n }\n )),\n thenable.status)\n ) {\n case \"fulfilled\":\n return thenable.value;\n case \"rejected\":\n throw thenable.reason;\n }\n }\n throw thenable;\n }\n function mapIntoArray(children, array, escapedPrefix, nameSoFar, callback) {\n var type = typeof children;\n if (\"undefined\" === type || \"boolean\" === type) children = null;\n var invokeCallback = !1;\n if (null === children) invokeCallback = !0;\n else\n switch (type) {\n case \"bigint\":\n case \"string\":\n case \"number\":\n invokeCallback = !0;\n break;\n case \"object\":\n switch (children.$$typeof) {\n case REACT_ELEMENT_TYPE:\n case REACT_PORTAL_TYPE:\n invokeCallback = !0;\n break;\n case REACT_LAZY_TYPE:\n return (\n (invokeCallback = children._init),\n mapIntoArray(\n invokeCallback(children._payload),\n array,\n escapedPrefix,\n nameSoFar,\n callback\n )\n );\n }\n }\n if (invokeCallback) {\n invokeCallback = children;\n callback = callback(invokeCallback);\n var childKey =\n \"\" === nameSoFar ? \".\" + getElementKey(invokeCallback, 0) : nameSoFar;\n isArrayImpl(callback)\n ? ((escapedPrefix = \"\"),\n null != childKey &&\n (escapedPrefix =\n childKey.replace(userProvidedKeyEscapeRegex, \"$&/\") + \"/\"),\n mapIntoArray(callback, array, escapedPrefix, \"\", function (c) {\n return c;\n }))\n : null != callback &&\n (isValidElement(callback) &&\n (null != callback.key &&\n ((invokeCallback && invokeCallback.key === callback.key) ||\n checkKeyStringCoercion(callback.key)),\n (escapedPrefix = cloneAndReplaceKey(\n callback,\n escapedPrefix +\n (null == callback.key ||\n (invokeCallback && invokeCallback.key === callback.key)\n ? \"\"\n : (\"\" + callback.key).replace(\n userProvidedKeyEscapeRegex,\n \"$&/\"\n ) + \"/\") +\n childKey\n )),\n \"\" !== nameSoFar &&\n null != invokeCallback &&\n isValidElement(invokeCallback) &&\n null == invokeCallback.key &&\n invokeCallback._store &&\n !invokeCallback._store.validated &&\n (escapedPrefix._store.validated = 2),\n (callback = escapedPrefix)),\n array.push(callback));\n return 1;\n }\n invokeCallback = 0;\n childKey = \"\" === nameSoFar ? \".\" : nameSoFar + \":\";\n if (isArrayImpl(children))\n for (var i = 0; i < children.length; i++)\n (nameSoFar = children[i]),\n (type = childKey + getElementKey(nameSoFar, i)),\n (invokeCallback += mapIntoArray(\n nameSoFar,\n array,\n escapedPrefix,\n type,\n callback\n ));\n else if (((i = getIteratorFn(children)), \"function\" === typeof i))\n for (\n i === children.entries &&\n (didWarnAboutMaps ||\n console.warn(\n \"Using Maps as children is not supported. Use an array of keyed ReactElements instead.\"\n ),\n (didWarnAboutMaps = !0)),\n children = i.call(children),\n i = 0;\n !(nameSoFar = children.next()).done;\n\n )\n (nameSoFar = nameSoFar.value),\n (type = childKey + getElementKey(nameSoFar, i++)),\n (invokeCallback += mapIntoArray(\n nameSoFar,\n array,\n escapedPrefix,\n type,\n callback\n ));\n else if (\"object\" === type) {\n if (\"function\" === typeof children.then)\n return mapIntoArray(\n resolveThenable(children),\n array,\n escapedPrefix,\n nameSoFar,\n callback\n );\n array = String(children);\n throw Error(\n \"Objects are not valid as a React child (found: \" +\n (\"[object Object]\" === array\n ? \"object with keys {\" + Object.keys(children).join(\", \") + \"}\"\n : array) +\n \"). If you meant to render a collection of children, use an array instead.\"\n );\n }\n return invokeCallback;\n }\n function mapChildren(children, func, context) {\n if (null == children) return children;\n var result = [],\n count = 0;\n mapIntoArray(children, result, \"\", \"\", function (child) {\n return func.call(context, child, count++);\n });\n return result;\n }\n function lazyInitializer(payload) {\n if (-1 === payload._status) {\n var ioInfo = payload._ioInfo;\n null != ioInfo && (ioInfo.start = ioInfo.end = performance.now());\n ioInfo = payload._result;\n var thenable = ioInfo();\n thenable.then(\n function (moduleObject) {\n if (0 === payload._status || -1 === payload._status) {\n payload._status = 1;\n payload._result = moduleObject;\n var _ioInfo = payload._ioInfo;\n null != _ioInfo && (_ioInfo.end = performance.now());\n void 0 === thenable.status &&\n ((thenable.status = \"fulfilled\"),\n (thenable.value = moduleObject));\n }\n },\n function (error) {\n if (0 === payload._status || -1 === payload._status) {\n payload._status = 2;\n payload._result = error;\n var _ioInfo2 = payload._ioInfo;\n null != _ioInfo2 && (_ioInfo2.end = performance.now());\n void 0 === thenable.status &&\n ((thenable.status = \"rejected\"), (thenable.reason = error));\n }\n }\n );\n ioInfo = payload._ioInfo;\n if (null != ioInfo) {\n ioInfo.value = thenable;\n var displayName = thenable.displayName;\n \"string\" === typeof displayName && (ioInfo.name = displayName);\n }\n -1 === payload._status &&\n ((payload._status = 0), (payload._result = thenable));\n }\n if (1 === payload._status)\n return (\n (ioInfo = payload._result),\n void 0 === ioInfo &&\n console.error(\n \"lazy: Expected the result of a dynamic import() call. Instead received: %s\\n\\nYour code should look like: \\n const MyComponent = lazy(() => import('./MyComponent'))\\n\\nDid you accidentally put curly braces around the import?\",\n ioInfo\n ),\n \"default\" in ioInfo ||\n console.error(\n \"lazy: Expected the result of a dynamic import() call. Instead received: %s\\n\\nYour code should look like: \\n const MyComponent = lazy(() => import('./MyComponent'))\",\n ioInfo\n ),\n ioInfo.default\n );\n throw payload._result;\n }\n function resolveDispatcher() {\n var dispatcher = ReactSharedInternals.H;\n null === dispatcher &&\n console.error(\n \"Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\\n1. You might have mismatching versions of React and the renderer (such as React DOM)\\n2. You might be breaking the Rules of Hooks\\n3. You might have more than one copy of React in the same app\\nSee https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.\"\n );\n return dispatcher;\n }\n function releaseAsyncTransition() {\n ReactSharedInternals.asyncTransitions--;\n }\n function enqueueTask(task) {\n if (null === enqueueTaskImpl)\n try {\n var requireString = (\"require\" + Math.random()).slice(0, 7);\n enqueueTaskImpl = (module && module[requireString]).call(\n module,\n \"timers\"\n ).setImmediate;\n } catch (_err) {\n enqueueTaskImpl = function (callback) {\n !1 === didWarnAboutMessageChannel &&\n ((didWarnAboutMessageChannel = !0),\n \"undefined\" === typeof MessageChannel &&\n console.error(\n \"This browser does not have a MessageChannel implementation, so enqueuing tasks via await act(async () => ...) will fail. Please file an issue at https://github.com/facebook/react/issues if you encounter this warning.\"\n ));\n var channel = new MessageChannel();\n channel.port1.onmessage = callback;\n channel.port2.postMessage(void 0);\n };\n }\n return enqueueTaskImpl(task);\n }\n function aggregateErrors(errors) {\n return 1 < errors.length && \"function\" === typeof AggregateError\n ? new AggregateError(errors)\n : errors[0];\n }\n function popActScope(prevActQueue, prevActScopeDepth) {\n prevActScopeDepth !== actScopeDepth - 1 &&\n console.error(\n \"You seem to have overlapping act() calls, this is not supported. Be sure to await previous act() calls before making a new one. \"\n );\n actScopeDepth = prevActScopeDepth;\n }\n function recursivelyFlushAsyncActWork(returnValue, resolve, reject) {\n var queue = ReactSharedInternals.actQueue;\n if (null !== queue)\n if (0 !== queue.length)\n try {\n flushActQueue(queue);\n enqueueTask(function () {\n return recursivelyFlushAsyncActWork(returnValue, resolve, reject);\n });\n return;\n } catch (error) {\n ReactSharedInternals.thrownErrors.push(error);\n }\n else ReactSharedInternals.actQueue = null;\n 0 < ReactSharedInternals.thrownErrors.length\n ? ((queue = aggregateErrors(ReactSharedInternals.thrownErrors)),\n (ReactSharedInternals.thrownErrors.length = 0),\n reject(queue))\n : resolve(returnValue);\n }\n function flushActQueue(queue) {\n if (!isFlushing) {\n isFlushing = !0;\n var i = 0;\n try {\n for (; i < queue.length; i++) {\n var callback = queue[i];\n do {\n ReactSharedInternals.didUsePromise = !1;\n var continuation = callback(!1);\n if (null !== continuation) {\n if (ReactSharedInternals.didUsePromise) {\n queue[i] = callback;\n queue.splice(0, i);\n return;\n }\n callback = continuation;\n } else break;\n } while (1);\n }\n queue.length = 0;\n } catch (error) {\n queue.splice(0, i + 1), ReactSharedInternals.thrownErrors.push(error);\n } finally {\n isFlushing = !1;\n }\n }\n }\n \"undefined\" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&\n \"function\" ===\n typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart &&\n __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(Error());\n var REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\"),\n REACT_STRICT_MODE_TYPE = Symbol.for(\"react.strict_mode\"),\n REACT_PROFILER_TYPE = Symbol.for(\"react.profiler\"),\n REACT_CONSUMER_TYPE = Symbol.for(\"react.consumer\"),\n REACT_CONTEXT_TYPE = Symbol.for(\"react.context\"),\n REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\"),\n REACT_SUSPENSE_TYPE = Symbol.for(\"react.suspense\"),\n REACT_SUSPENSE_LIST_TYPE = Symbol.for(\"react.suspense_list\"),\n REACT_MEMO_TYPE = Symbol.for(\"react.memo\"),\n REACT_LAZY_TYPE = Symbol.for(\"react.lazy\"),\n REACT_ACTIVITY_TYPE = Symbol.for(\"react.activity\"),\n MAYBE_ITERATOR_SYMBOL = Symbol.iterator,\n didWarnStateUpdateForUnmountedComponent = {},\n ReactNoopUpdateQueue = {\n isMounted: function () {\n return !1;\n },\n enqueueForceUpdate: function (publicInstance) {\n warnNoop(publicInstance, \"forceUpdate\");\n },\n enqueueReplaceState: function (publicInstance) {\n warnNoop(publicInstance, \"replaceState\");\n },\n enqueueSetState: function (publicInstance) {\n warnNoop(publicInstance, \"setState\");\n }\n },\n assign = Object.assign,\n emptyObject = {};\n Object.freeze(emptyObject);\n Component.prototype.isReactComponent = {};\n Component.prototype.setState = function (partialState, callback) {\n if (\n \"object\" !== typeof partialState &&\n \"function\" !== typeof partialState &&\n null != partialState\n )\n throw Error(\n \"takes an object of state variables to update or a function which returns an object of state variables.\"\n );\n this.updater.enqueueSetState(this, partialState, callback, \"setState\");\n };\n Component.prototype.forceUpdate = function (callback) {\n this.updater.enqueueForceUpdate(this, callback, \"forceUpdate\");\n };\n var deprecatedAPIs = {\n isMounted: [\n \"isMounted\",\n \"Instead, make sure to clean up subscriptions and pending requests in componentWillUnmount to prevent memory leaks.\"\n ],\n replaceState: [\n \"replaceState\",\n \"Refactor your code to use setState instead (see https://github.com/facebook/react/issues/3236).\"\n ]\n };\n for (fnName in deprecatedAPIs)\n deprecatedAPIs.hasOwnProperty(fnName) &&\n defineDeprecationWarning(fnName, deprecatedAPIs[fnName]);\n ComponentDummy.prototype = Component.prototype;\n deprecatedAPIs = PureComponent.prototype = new ComponentDummy();\n deprecatedAPIs.constructor = PureComponent;\n assign(deprecatedAPIs, Component.prototype);\n deprecatedAPIs.isPureReactComponent = !0;\n var isArrayImpl = Array.isArray,\n REACT_CLIENT_REFERENCE = Symbol.for(\"react.client.reference\"),\n ReactSharedInternals = {\n H: null,\n A: null,\n T: null,\n S: null,\n actQueue: null,\n asyncTransitions: 0,\n isBatchingLegacy: !1,\n didScheduleLegacyUpdate: !1,\n didUsePromise: !1,\n thrownErrors: [],\n getCurrentStack: null,\n recentlyCreatedOwnerStacks: 0\n },\n hasOwnProperty = Object.prototype.hasOwnProperty,\n createTask = console.createTask\n ? console.createTask\n : function () {\n return null;\n };\n deprecatedAPIs = {\n react_stack_bottom_frame: function (callStackForError) {\n return callStackForError();\n }\n };\n var specialPropKeyWarningShown, didWarnAboutOldJSXRuntime;\n var didWarnAboutElementRef = {};\n var unknownOwnerDebugStack = deprecatedAPIs.react_stack_bottom_frame.bind(\n deprecatedAPIs,\n UnknownOwner\n )();\n var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));\n var didWarnAboutMaps = !1,\n userProvidedKeyEscapeRegex = /\\/+/g,\n reportGlobalError =\n \"function\" === typeof reportError\n ? reportError\n : function (error) {\n if (\n \"object\" === typeof window &&\n \"function\" === typeof window.ErrorEvent\n ) {\n var event = new window.ErrorEvent(\"error\", {\n bubbles: !0,\n cancelable: !0,\n message:\n \"object\" === typeof error &&\n null !== error &&\n \"string\" === typeof error.message\n ? String(error.message)\n : String(error),\n error: error\n });\n if (!window.dispatchEvent(event)) return;\n } else if (\n \"object\" === typeof process &&\n \"function\" === typeof process.emit\n ) {\n process.emit(\"uncaughtException\", error);\n return;\n }\n console.error(error);\n },\n didWarnAboutMessageChannel = !1,\n enqueueTaskImpl = null,\n actScopeDepth = 0,\n didWarnNoAwaitAct = !1,\n isFlushing = !1,\n queueSeveralMicrotasks =\n \"function\" === typeof queueMicrotask\n ? function (callback) {\n queueMicrotask(function () {\n return queueMicrotask(callback);\n });\n }\n : enqueueTask;\n deprecatedAPIs = Object.freeze({\n __proto__: null,\n c: function (size) {\n return resolveDispatcher().useMemoCache(size);\n }\n });\n var fnName = {\n map: mapChildren,\n forEach: function (children, forEachFunc, forEachContext) {\n mapChildren(\n children,\n function () {\n forEachFunc.apply(this, arguments);\n },\n forEachContext\n );\n },\n count: function (children) {\n var n = 0;\n mapChildren(children, function () {\n n++;\n });\n return n;\n },\n toArray: function (children) {\n return (\n mapChildren(children, function (child) {\n return child;\n }) || []\n );\n },\n only: function (children) {\n if (!isValidElement(children))\n throw Error(\n \"React.Children.only expected to receive a single React element child.\"\n );\n return children;\n }\n };\n exports.Activity = REACT_ACTIVITY_TYPE;\n exports.Children = fnName;\n exports.Component = Component;\n exports.Fragment = REACT_FRAGMENT_TYPE;\n exports.Profiler = REACT_PROFILER_TYPE;\n exports.PureComponent = PureComponent;\n exports.StrictMode = REACT_STRICT_MODE_TYPE;\n exports.Suspense = REACT_SUSPENSE_TYPE;\n exports.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE =\n ReactSharedInternals;\n exports.__COMPILER_RUNTIME = deprecatedAPIs;\n exports.act = function (callback) {\n var prevActQueue = ReactSharedInternals.actQueue,\n prevActScopeDepth = actScopeDepth;\n actScopeDepth++;\n var queue = (ReactSharedInternals.actQueue =\n null !== prevActQueue ? prevActQueue : []),\n didAwaitActCall = !1;\n try {\n var result = callback();\n } catch (error) {\n ReactSharedInternals.thrownErrors.push(error);\n }\n if (0 < ReactSharedInternals.thrownErrors.length)\n throw (\n (popActScope(prevActQueue, prevActScopeDepth),\n (callback = aggregateErrors(ReactSharedInternals.thrownErrors)),\n (ReactSharedInternals.thrownErrors.length = 0),\n callback)\n );\n if (\n null !== result &&\n \"object\" === typeof result &&\n \"function\" === typeof result.then\n ) {\n var thenable = result;\n queueSeveralMicrotasks(function () {\n didAwaitActCall ||\n didWarnNoAwaitAct ||\n ((didWarnNoAwaitAct = !0),\n console.error(\n \"You called act(async () => ...) without await. This could lead to unexpected testing behaviour, interleaving multiple act calls and mixing their scopes. You should - await act(async () => ...);\"\n ));\n });\n return {\n then: function (resolve, reject) {\n didAwaitActCall = !0;\n thenable.then(\n function (returnValue) {\n popActScope(prevActQueue, prevActScopeDepth);\n if (0 === prevActScopeDepth) {\n try {\n flushActQueue(queue),\n enqueueTask(function () {\n return recursivelyFlushAsyncActWork(\n returnValue,\n resolve,\n reject\n );\n });\n } catch (error$0) {\n ReactSharedInternals.thrownErrors.push(error$0);\n }\n if (0 < ReactSharedInternals.thrownErrors.length) {\n var _thrownError = aggregateErrors(\n ReactSharedInternals.thrownErrors\n );\n ReactSharedInternals.thrownErrors.length = 0;\n reject(_thrownError);\n }\n } else resolve(returnValue);\n },\n function (error) {\n popActScope(prevActQueue, prevActScopeDepth);\n 0 < ReactSharedInternals.thrownErrors.length\n ? ((error = aggregateErrors(\n ReactSharedInternals.thrownErrors\n )),\n (ReactSharedInternals.thrownErrors.length = 0),\n reject(error))\n : reject(error);\n }\n );\n }\n };\n }\n var returnValue$jscomp$0 = result;\n popActScope(prevActQueue, prevActScopeDepth);\n 0 === prevActScopeDepth &&\n (flushActQueue(queue),\n 0 !== queue.length &&\n queueSeveralMicrotasks(function () {\n didAwaitActCall ||\n didWarnNoAwaitAct ||\n ((didWarnNoAwaitAct = !0),\n console.error(\n \"A component suspended inside an `act` scope, but the `act` call was not awaited. When testing React components that depend on asynchronous data, you must await the result:\\n\\nawait act(() => ...)\"\n ));\n }),\n (ReactSharedInternals.actQueue = null));\n if (0 < ReactSharedInternals.thrownErrors.length)\n throw (\n ((callback = aggregateErrors(ReactSharedInternals.thrownErrors)),\n (ReactSharedInternals.thrownErrors.length = 0),\n callback)\n );\n return {\n then: function (resolve, reject) {\n didAwaitActCall = !0;\n 0 === prevActScopeDepth\n ? ((ReactSharedInternals.actQueue = queue),\n enqueueTask(function () {\n return recursivelyFlushAsyncActWork(\n returnValue$jscomp$0,\n resolve,\n reject\n );\n }))\n : resolve(returnValue$jscomp$0);\n }\n };\n };\n exports.cache = function (fn) {\n return function () {\n return fn.apply(null, arguments);\n };\n };\n exports.cacheSignal = function () {\n return null;\n };\n exports.captureOwnerStack = function () {\n var getCurrentStack = ReactSharedInternals.getCurrentStack;\n return null === getCurrentStack ? null : getCurrentStack();\n };\n exports.cloneElement = function (element, config, children) {\n if (null === element || void 0 === element)\n throw Error(\n \"The argument must be a React element, but you passed \" +\n element +\n \".\"\n );\n var props = assign({}, element.props),\n key = element.key,\n owner = element._owner;\n if (null != config) {\n var JSCompiler_inline_result;\n a: {\n if (\n hasOwnProperty.call(config, \"ref\") &&\n (JSCompiler_inline_result = Object.getOwnPropertyDescriptor(\n config,\n \"ref\"\n ).get) &&\n JSCompiler_inline_result.isReactWarning\n ) {\n JSCompiler_inline_result = !1;\n break a;\n }\n JSCompiler_inline_result = void 0 !== config.ref;\n }\n JSCompiler_inline_result && (owner = getOwner());\n hasValidKey(config) &&\n (checkKeyStringCoercion(config.key), (key = \"\" + config.key));\n for (propName in config)\n !hasOwnProperty.call(config, propName) ||\n \"key\" === propName ||\n \"__self\" === propName ||\n \"__source\" === propName ||\n (\"ref\" === propName && void 0 === config.ref) ||\n (props[propName] = config[propName]);\n }\n var propName = arguments.length - 2;\n if (1 === propName) props.children = children;\n else if (1 < propName) {\n JSCompiler_inline_result = Array(propName);\n for (var i = 0; i < propName; i++)\n JSCompiler_inline_result[i] = arguments[i + 2];\n props.children = JSCompiler_inline_result;\n }\n props = ReactElement(\n element.type,\n key,\n props,\n owner,\n element._debugStack,\n element._debugTask\n );\n for (key = 2; key < arguments.length; key++)\n validateChildKeys(arguments[key]);\n return props;\n };\n exports.createContext = function (defaultValue) {\n defaultValue = {\n $$typeof: REACT_CONTEXT_TYPE,\n _currentValue: defaultValue,\n _currentValue2: defaultValue,\n _threadCount: 0,\n Provider: null,\n Consumer: null\n };\n defaultValue.Provider = defaultValue;\n defaultValue.Consumer = {\n $$typeof: REACT_CONSUMER_TYPE,\n _context: defaultValue\n };\n defaultValue._currentRenderer = null;\n defaultValue._currentRenderer2 = null;\n return defaultValue;\n };\n exports.createElement = function (type, config, children) {\n for (var i = 2; i < arguments.length; i++)\n validateChildKeys(arguments[i]);\n i = {};\n var key = null;\n if (null != config)\n for (propName in (didWarnAboutOldJSXRuntime ||\n !(\"__self\" in config) ||\n \"key\" in config ||\n ((didWarnAboutOldJSXRuntime = !0),\n console.warn(\n \"Your app (or one of its dependencies) is using an outdated JSX transform. Update to the modern JSX transform for faster performance: https://react.dev/link/new-jsx-transform\"\n )),\n hasValidKey(config) &&\n (checkKeyStringCoercion(config.key), (key = \"\" + config.key)),\n config))\n hasOwnProperty.call(config, propName) &&\n \"key\" !== propName &&\n \"__self\" !== propName &&\n \"__source\" !== propName &&\n (i[propName] = config[propName]);\n var childrenLength = arguments.length - 2;\n if (1 === childrenLength) i.children = children;\n else if (1 < childrenLength) {\n for (\n var childArray = Array(childrenLength), _i = 0;\n _i < childrenLength;\n _i++\n )\n childArray[_i] = arguments[_i + 2];\n Object.freeze && Object.freeze(childArray);\n i.children = childArray;\n }\n if (type && type.defaultProps)\n for (propName in ((childrenLength = type.defaultProps), childrenLength))\n void 0 === i[propName] && (i[propName] = childrenLength[propName]);\n key &&\n defineKeyPropWarningGetter(\n i,\n \"function\" === typeof type\n ? type.displayName || type.name || \"Unknown\"\n : type\n );\n var propName = 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return ReactElement(\n type,\n key,\n i,\n getOwner(),\n propName ? Error(\"react-stack-top-frame\") : unknownOwnerDebugStack,\n propName ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n exports.createRef = function () {\n var refObject = { current: null };\n Object.seal(refObject);\n return refObject;\n };\n exports.forwardRef = function (render) {\n null != render && render.$$typeof === REACT_MEMO_TYPE\n ? console.error(\n \"forwardRef requires a render function but received a `memo` component. Instead of forwardRef(memo(...)), use memo(forwardRef(...)).\"\n )\n : \"function\" !== typeof render\n ? console.error(\n \"forwardRef requires a render function but was given %s.\",\n null === render ? \"null\" : typeof render\n )\n : 0 !== render.length &&\n 2 !== render.length &&\n console.error(\n \"forwardRef render functions accept exactly two parameters: props and ref. %s\",\n 1 === render.length\n ? \"Did you forget to use the ref parameter?\"\n : \"Any additional parameter will be undefined.\"\n );\n null != render &&\n null != render.defaultProps &&\n console.error(\n \"forwardRef render functions do not support defaultProps. Did you accidentally pass a React component?\"\n );\n var elementType = { $$typeof: REACT_FORWARD_REF_TYPE, render: render },\n ownName;\n Object.defineProperty(elementType, \"displayName\", {\n enumerable: !1,\n configurable: !0,\n get: function () {\n return ownName;\n },\n set: function (name) {\n ownName = name;\n render.name ||\n render.displayName ||\n (Object.defineProperty(render, \"name\", { value: name }),\n (render.displayName = name));\n }\n });\n return elementType;\n };\n exports.isValidElement = isValidElement;\n exports.lazy = function (ctor) {\n ctor = { _status: -1, _result: ctor };\n var lazyType = {\n $$typeof: REACT_LAZY_TYPE,\n _payload: ctor,\n _init: lazyInitializer\n },\n ioInfo = {\n name: \"lazy\",\n start: -1,\n end: -1,\n value: null,\n owner: null,\n debugStack: Error(\"react-stack-top-frame\"),\n debugTask: console.createTask ? console.createTask(\"lazy()\") : null\n };\n ctor._ioInfo = ioInfo;\n lazyType._debugInfo = [{ awaited: ioInfo }];\n return lazyType;\n };\n exports.memo = function (type, compare) {\n null == type &&\n console.error(\n \"memo: The first argument must be a component. Instead received: %s\",\n null === type ? \"null\" : typeof type\n );\n compare = {\n $$typeof: REACT_MEMO_TYPE,\n type: type,\n compare: void 0 === compare ? null : compare\n };\n var ownName;\n Object.defineProperty(compare, \"displayName\", {\n enumerable: !1,\n configurable: !0,\n get: function () {\n return ownName;\n },\n set: function (name) {\n ownName = name;\n type.name ||\n type.displayName ||\n (Object.defineProperty(type, \"name\", { value: name }),\n (type.displayName = name));\n }\n });\n return compare;\n };\n exports.startTransition = function (scope) {\n var prevTransition = ReactSharedInternals.T,\n currentTransition = {};\n currentTransition._updatedFibers = new Set();\n ReactSharedInternals.T = currentTransition;\n try {\n var returnValue = scope(),\n onStartTransitionFinish = ReactSharedInternals.S;\n null !== onStartTransitionFinish &&\n onStartTransitionFinish(currentTransition, returnValue);\n \"object\" === typeof returnValue &&\n null !== returnValue &&\n \"function\" === typeof returnValue.then &&\n (ReactSharedInternals.asyncTransitions++,\n returnValue.then(releaseAsyncTransition, releaseAsyncTransition),\n returnValue.then(noop, reportGlobalError));\n } catch (error) {\n reportGlobalError(error);\n } finally {\n null === prevTransition &&\n currentTransition._updatedFibers &&\n ((scope = currentTransition._updatedFibers.size),\n currentTransition._updatedFibers.clear(),\n 10 < scope &&\n console.warn(\n \"Detected a large number of updates inside startTransition. If this is due to a subscription please re-write it to use React provided hooks. Otherwise concurrent mode guarantees are off the table.\"\n )),\n null !== prevTransition &&\n null !== currentTransition.types &&\n (null !== prevTransition.types &&\n prevTransition.types !== currentTransition.types &&\n console.error(\n \"We expected inner Transitions to have transferred the outer types set and that you cannot add to the outer Transition while inside the inner.This is a bug in React.\"\n ),\n (prevTransition.types = currentTransition.types)),\n (ReactSharedInternals.T = prevTransition);\n }\n };\n exports.unstable_useCacheRefresh = function () {\n return resolveDispatcher().useCacheRefresh();\n };\n exports.use = function (usable) {\n return resolveDispatcher().use(usable);\n };\n exports.useActionState = function (action, initialState, permalink) {\n return resolveDispatcher().useActionState(\n action,\n initialState,\n permalink\n );\n };\n exports.useCallback = function (callback, deps) {\n return resolveDispatcher().useCallback(callback, deps);\n };\n exports.useContext = function (Context) {\n var dispatcher = resolveDispatcher();\n Context.$$typeof === REACT_CONSUMER_TYPE &&\n console.error(\n \"Calling useContext(Context.Consumer) is not supported and will cause bugs. Did you mean to call useContext(Context) instead?\"\n );\n return dispatcher.useContext(Context);\n };\n exports.useDebugValue = function (value, formatterFn) {\n return resolveDispatcher().useDebugValue(value, formatterFn);\n };\n exports.useDeferredValue = function (value, initialValue) {\n return resolveDispatcher().useDeferredValue(value, initialValue);\n };\n exports.useEffect = function (create, deps) {\n null == create &&\n console.warn(\n \"React Hook useEffect requires an effect callback. Did you forget to pass a callback to the hook?\"\n );\n return resolveDispatcher().useEffect(create, deps);\n };\n exports.useEffectEvent = function (callback) {\n return resolveDispatcher().useEffectEvent(callback);\n };\n exports.useId = function () {\n return resolveDispatcher().useId();\n };\n exports.useImperativeHandle = function (ref, create, deps) {\n return resolveDispatcher().useImperativeHandle(ref, create, deps);\n };\n exports.useInsertionEffect = function (create, deps) {\n null == create &&\n console.warn(\n \"React Hook useInsertionEffect requires an effect callback. Did you forget to pass a callback to the hook?\"\n );\n return resolveDispatcher().useInsertionEffect(create, deps);\n };\n exports.useLayoutEffect = function (create, deps) {\n null == create &&\n console.warn(\n \"React Hook useLayoutEffect requires an effect callback. Did you forget to pass a callback to the hook?\"\n );\n return resolveDispatcher().useLayoutEffect(create, deps);\n };\n exports.useMemo = function (create, deps) {\n return resolveDispatcher().useMemo(create, deps);\n };\n exports.useOptimistic = function (passthrough, reducer) {\n return resolveDispatcher().useOptimistic(passthrough, reducer);\n };\n exports.useReducer = function (reducer, initialArg, init) {\n return resolveDispatcher().useReducer(reducer, initialArg, init);\n };\n exports.useRef = function (initialValue) {\n return resolveDispatcher().useRef(initialValue);\n };\n exports.useState = function (initialState) {\n return resolveDispatcher().useState(initialState);\n };\n exports.useSyncExternalStore = function (\n subscribe,\n getSnapshot,\n getServerSnapshot\n ) {\n return resolveDispatcher().useSyncExternalStore(\n subscribe,\n getSnapshot,\n getServerSnapshot\n );\n };\n exports.useTransition = function () {\n return resolveDispatcher().useTransition();\n };\n exports.version = \"19.2.4\";\n \"undefined\" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&\n \"function\" ===\n typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&\n __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(Error());\n })();\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react.production.js');\n} else {\n module.exports = require('./cjs/react.development.js');\n}\n","/**\n * @license React\n * react-jsx-runtime.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\");\nfunction jsxProd(type, config, maybeKey) {\n var key = null;\n void 0 !== maybeKey && (key = \"\" + maybeKey);\n void 0 !== config.key && (key = \"\" + config.key);\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n config = maybeKey.ref;\n return {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n ref: void 0 !== config ? config : null,\n props: maybeKey\n };\n}\nexports.Fragment = REACT_FRAGMENT_TYPE;\nexports.jsx = jsxProd;\nexports.jsxs = jsxProd;\n","/**\n * @license React\n * react-jsx-runtime.development.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\n\"production\" !== process.env.NODE_ENV &&\n (function () {\n function getComponentNameFromType(type) {\n if (null == type) return null;\n if (\"function\" === typeof type)\n return type.$$typeof === REACT_CLIENT_REFERENCE\n ? null\n : type.displayName || type.name || null;\n if (\"string\" === typeof type) return type;\n switch (type) {\n case REACT_FRAGMENT_TYPE:\n return \"Fragment\";\n case REACT_PROFILER_TYPE:\n return \"Profiler\";\n case REACT_STRICT_MODE_TYPE:\n return \"StrictMode\";\n case REACT_SUSPENSE_TYPE:\n return \"Suspense\";\n case REACT_SUSPENSE_LIST_TYPE:\n return \"SuspenseList\";\n case REACT_ACTIVITY_TYPE:\n return \"Activity\";\n }\n if (\"object\" === typeof type)\n switch (\n (\"number\" === typeof type.tag &&\n console.error(\n \"Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue.\"\n ),\n type.$$typeof)\n ) {\n case REACT_PORTAL_TYPE:\n return \"Portal\";\n case REACT_CONTEXT_TYPE:\n return type.displayName || \"Context\";\n case REACT_CONSUMER_TYPE:\n return (type._context.displayName || \"Context\") + \".Consumer\";\n case REACT_FORWARD_REF_TYPE:\n var innerType = type.render;\n type = type.displayName;\n type ||\n ((type = innerType.displayName || innerType.name || \"\"),\n (type = \"\" !== type ? \"ForwardRef(\" + type + \")\" : \"ForwardRef\"));\n return type;\n case REACT_MEMO_TYPE:\n return (\n (innerType = type.displayName || null),\n null !== innerType\n ? innerType\n : getComponentNameFromType(type.type) || \"Memo\"\n );\n case REACT_LAZY_TYPE:\n innerType = type._payload;\n type = type._init;\n try {\n return getComponentNameFromType(type(innerType));\n } catch (x) {}\n }\n return null;\n }\n function testStringCoercion(value) {\n return \"\" + value;\n }\n function checkKeyStringCoercion(value) {\n try {\n testStringCoercion(value);\n var JSCompiler_inline_result = !1;\n } catch (e) {\n JSCompiler_inline_result = !0;\n }\n if (JSCompiler_inline_result) {\n JSCompiler_inline_result = console;\n var JSCompiler_temp_const = JSCompiler_inline_result.error;\n var JSCompiler_inline_result$jscomp$0 =\n (\"function\" === typeof Symbol &&\n Symbol.toStringTag &&\n value[Symbol.toStringTag]) ||\n value.constructor.name ||\n \"Object\";\n JSCompiler_temp_const.call(\n JSCompiler_inline_result,\n \"The provided key is an unsupported type %s. This value must be coerced to a string before using it here.\",\n JSCompiler_inline_result$jscomp$0\n );\n return testStringCoercion(value);\n }\n }\n function getTaskName(type) {\n if (type === REACT_FRAGMENT_TYPE) return \"<>\";\n if (\n \"object\" === typeof type &&\n null !== type &&\n type.$$typeof === REACT_LAZY_TYPE\n )\n return \"<...>\";\n try {\n var name = getComponentNameFromType(type);\n return name ? \"<\" + name + \">\" : \"<...>\";\n } catch (x) {\n return \"<...>\";\n }\n }\n function getOwner() {\n var dispatcher = ReactSharedInternals.A;\n return null === dispatcher ? null : dispatcher.getOwner();\n }\n function UnknownOwner() {\n return Error(\"react-stack-top-frame\");\n }\n function hasValidKey(config) {\n if (hasOwnProperty.call(config, \"key\")) {\n var getter = Object.getOwnPropertyDescriptor(config, \"key\").get;\n if (getter && getter.isReactWarning) return !1;\n }\n return void 0 !== config.key;\n }\n function defineKeyPropWarningGetter(props, displayName) {\n function warnAboutAccessingKey() {\n specialPropKeyWarningShown ||\n ((specialPropKeyWarningShown = !0),\n console.error(\n \"%s: `key` is not a prop. Trying to access it will result in `undefined` being returned. If you need to access the same value within the child component, you should pass it as a different prop. (https://react.dev/link/special-props)\",\n displayName\n ));\n }\n warnAboutAccessingKey.isReactWarning = !0;\n Object.defineProperty(props, \"key\", {\n get: warnAboutAccessingKey,\n configurable: !0\n });\n }\n function elementRefGetterWithDeprecationWarning() {\n var componentName = getComponentNameFromType(this.type);\n didWarnAboutElementRef[componentName] ||\n ((didWarnAboutElementRef[componentName] = !0),\n console.error(\n \"Accessing element.ref was removed in React 19. ref is now a regular prop. It will be removed from the JSX Element type in a future release.\"\n ));\n componentName = this.props.ref;\n return void 0 !== componentName ? componentName : null;\n }\n function ReactElement(type, key, props, owner, debugStack, debugTask) {\n var refProp = props.ref;\n type = {\n $$typeof: REACT_ELEMENT_TYPE,\n type: type,\n key: key,\n props: props,\n _owner: owner\n };\n null !== (void 0 !== refProp ? refProp : null)\n ? Object.defineProperty(type, \"ref\", {\n enumerable: !1,\n get: elementRefGetterWithDeprecationWarning\n })\n : Object.defineProperty(type, \"ref\", { enumerable: !1, value: null });\n type._store = {};\n Object.defineProperty(type._store, \"validated\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: 0\n });\n Object.defineProperty(type, \"_debugInfo\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: null\n });\n Object.defineProperty(type, \"_debugStack\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugStack\n });\n Object.defineProperty(type, \"_debugTask\", {\n configurable: !1,\n enumerable: !1,\n writable: !0,\n value: debugTask\n });\n Object.freeze && (Object.freeze(type.props), Object.freeze(type));\n return type;\n }\n function jsxDEVImpl(\n type,\n config,\n maybeKey,\n isStaticChildren,\n debugStack,\n debugTask\n ) {\n var children = config.children;\n if (void 0 !== children)\n if (isStaticChildren)\n if (isArrayImpl(children)) {\n for (\n isStaticChildren = 0;\n isStaticChildren < children.length;\n isStaticChildren++\n )\n validateChildKeys(children[isStaticChildren]);\n Object.freeze && Object.freeze(children);\n } else\n console.error(\n \"React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead.\"\n );\n else validateChildKeys(children);\n if (hasOwnProperty.call(config, \"key\")) {\n children = getComponentNameFromType(type);\n var keys = Object.keys(config).filter(function (k) {\n return \"key\" !== k;\n });\n isStaticChildren =\n 0 < keys.length\n ? \"{key: someKey, \" + keys.join(\": ..., \") + \": ...}\"\n : \"{key: someKey}\";\n didWarnAboutKeySpread[children + isStaticChildren] ||\n ((keys =\n 0 < keys.length ? \"{\" + keys.join(\": ..., \") + \": ...}\" : \"{}\"),\n console.error(\n 'A props object containing a \"key\" prop is being spread into JSX:\\n let props = %s;\\n <%s {...props} />\\nReact keys must be passed directly to JSX without using spread:\\n let props = %s;\\n <%s key={someKey} {...props} />',\n isStaticChildren,\n children,\n keys,\n children\n ),\n (didWarnAboutKeySpread[children + isStaticChildren] = !0));\n }\n children = null;\n void 0 !== maybeKey &&\n (checkKeyStringCoercion(maybeKey), (children = \"\" + maybeKey));\n hasValidKey(config) &&\n (checkKeyStringCoercion(config.key), (children = \"\" + config.key));\n if (\"key\" in config) {\n maybeKey = {};\n for (var propName in config)\n \"key\" !== propName && (maybeKey[propName] = config[propName]);\n } else maybeKey = config;\n children &&\n defineKeyPropWarningGetter(\n maybeKey,\n \"function\" === typeof type\n ? type.displayName || type.name || \"Unknown\"\n : type\n );\n return ReactElement(\n type,\n children,\n maybeKey,\n getOwner(),\n debugStack,\n debugTask\n );\n }\n function validateChildKeys(node) {\n isValidElement(node)\n ? node._store && (node._store.validated = 1)\n : \"object\" === typeof node &&\n null !== node &&\n node.$$typeof === REACT_LAZY_TYPE &&\n (\"fulfilled\" === node._payload.status\n ? isValidElement(node._payload.value) &&\n node._payload.value._store &&\n (node._payload.value._store.validated = 1)\n : node._store && (node._store.validated = 1));\n }\n function isValidElement(object) {\n return (\n \"object\" === typeof object &&\n null !== object &&\n object.$$typeof === REACT_ELEMENT_TYPE\n );\n }\n var React = require(\"react\"),\n REACT_ELEMENT_TYPE = Symbol.for(\"react.transitional.element\"),\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\"),\n REACT_FRAGMENT_TYPE = Symbol.for(\"react.fragment\"),\n REACT_STRICT_MODE_TYPE = Symbol.for(\"react.strict_mode\"),\n REACT_PROFILER_TYPE = Symbol.for(\"react.profiler\"),\n REACT_CONSUMER_TYPE = Symbol.for(\"react.consumer\"),\n REACT_CONTEXT_TYPE = Symbol.for(\"react.context\"),\n REACT_FORWARD_REF_TYPE = Symbol.for(\"react.forward_ref\"),\n REACT_SUSPENSE_TYPE = Symbol.for(\"react.suspense\"),\n REACT_SUSPENSE_LIST_TYPE = Symbol.for(\"react.suspense_list\"),\n REACT_MEMO_TYPE = Symbol.for(\"react.memo\"),\n REACT_LAZY_TYPE = Symbol.for(\"react.lazy\"),\n REACT_ACTIVITY_TYPE = Symbol.for(\"react.activity\"),\n REACT_CLIENT_REFERENCE = Symbol.for(\"react.client.reference\"),\n ReactSharedInternals =\n React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE,\n hasOwnProperty = Object.prototype.hasOwnProperty,\n isArrayImpl = Array.isArray,\n createTask = console.createTask\n ? console.createTask\n : function () {\n return null;\n };\n React = {\n react_stack_bottom_frame: function (callStackForError) {\n return callStackForError();\n }\n };\n var specialPropKeyWarningShown;\n var didWarnAboutElementRef = {};\n var unknownOwnerDebugStack = React.react_stack_bottom_frame.bind(\n React,\n UnknownOwner\n )();\n var unknownOwnerDebugTask = createTask(getTaskName(UnknownOwner));\n var didWarnAboutKeySpread = {};\n exports.Fragment = REACT_FRAGMENT_TYPE;\n exports.jsx = function (type, config, maybeKey) {\n var trackActualOwner =\n 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return jsxDEVImpl(\n type,\n config,\n maybeKey,\n !1,\n trackActualOwner\n ? Error(\"react-stack-top-frame\")\n : unknownOwnerDebugStack,\n trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n exports.jsxs = function (type, config, maybeKey) {\n var trackActualOwner =\n 1e4 > ReactSharedInternals.recentlyCreatedOwnerStacks++;\n return jsxDEVImpl(\n type,\n config,\n maybeKey,\n !0,\n trackActualOwner\n ? Error(\"react-stack-top-frame\")\n : unknownOwnerDebugStack,\n trackActualOwner ? createTask(getTaskName(type)) : unknownOwnerDebugTask\n );\n };\n })();\n","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react-jsx-runtime.production.js');\n} else {\n module.exports = require('./cjs/react-jsx-runtime.development.js');\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport PixodeskSvgAnimator from './PixodeskSvgAnimator';\nexport type { PixodeskSvgAnimatorCallbacks, PixodeskSvgAnimatorProps, ReactAnimatorApi } from './PixodeskSvgAnimator';\nexport { PixodeskSvgAnimator };\n\nimport PixodeskSvgCssAnimator from './PixodeskSvgCssAnimator';\nexport { PixodeskSvgCssAnimator };\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n/**\n * Lightweight Zod-like schema system — type declaration + runtime sanitization.\n *\n * Two operations per schema:\n * isValid(raw) — true only when raw already conforms; no repair needed.\n * sanitize(raw) — always returns T; fixes or replaces invalid input with defaults.\n *\n * Field rules inside px.object():\n * required field → if absent/invalid, field's declared default is used.\n * optional field → if absent/invalid (or wrong JS type), field becomes undefined.\n *\n * Array: items that cannot even be attempted are filtered out.\n * Record: values that cannot even be attempted are dropped.\n *\n * The distinction between isValid and _canSanitize:\n * isValid — strict; ALL fields must be correct, no repairs accepted.\n * _canSanitize — permissive; \"is the JS type right enough to attempt repair?\"\n * For containers (object/array/record) this is a structural check\n * so that partially-valid nested objects are sanitized rather than dropped.\n * For primitives it equals isValid (a wrong primitive type is unrecoverable).\n *\n * Validation context (optional):\n * Pass a PxValidationContext as the second arg to isValid() to collect per-field\n * error and warning messages with their dot-paths.\n * e.g. schema.isValid(raw, ctx, []) where ctx = { errors: [], warnings: [] }\n * Path segments are pushed/popped during recursion; join with '.' only when reporting.\n */\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Public interfaces\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Collects structured validation feedback. Pass to isValid() as the second argument. */\nexport interface PxValidationContext {\n /** Per-field errors — each entry is \"<dot.path>: <reason>\". */\n errors: Array<string>;\n /** Per-field warnings — same format as errors but non-fatal. */\n warnings: Array<string>;\n /**\n * When true, closed objects (`px.object` / `px.extendedObject`) report any\n * extra (undeclared) keys as errors. Default `false` (or omitted) — extras\n * are ignored, matching `sanitize`'s strip-extras behaviour, which is what\n * production app code wants (forward-compat with unknown future fields).\n * Tests that want to lock the wire shape down to its declared schema\n * should pass `strict: true`.\n *\n * Open objects (`px.openObject`) are unaffected by `strict` — they accept\n * extras by design (used for SVG element nodes that carry arbitrary attrs).\n */\n strict?: boolean;\n}\n\nexport interface PxSchema<T, IsOptional extends boolean = false> {\n /** Phantom discriminator — `false` for required schemas, `true` for optional. Used by InferShape. */\n readonly _optional: IsOptional;\n sanitize(raw: unknown): T;\n /**\n * Returns true when raw already conforms to this schema.\n * Pass an optional PxValidationContext to collect per-field error messages.\n * Pass a mutable Array<string> as `path` — segments are pushed/popped during\n * recursion so only a single array allocation is needed per validation call.\n */\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean;\n /** True if raw has the right structure to attempt sanitization (may still need repair). */\n _canSanitize(raw: unknown): boolean;\n readonly _default: T;\n /** Returns a new schema that marks this field as optional (?: in object shapes). */\n optional(): PxSchema<T | undefined, true>;\n}\n\n/** Extract the TypeScript type from a schema. */\nexport type PxInfer<S> = S extends PxSchema<infer T, any> ? T : never;\n\n/**\n * Removes string/number index signatures from T, leaving only explicitly named properties.\n * Useful for strict property-access checking on types that have an open `[key: string]: any`.\n *\n * @example\n * type Strict = RemoveIndex<PxAnimatedSvgDocument>;\n * Strict['animator'] // PxAnimatorConfig | undefined ✓\n * Strict['anything'] // compile error ✓\n */\nexport type RemoveIndex<T> = {\n [K in keyof T as string extends K ? never : number extends K ? never : K]: T[K]\n};\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Internal path helper\n// ─────────────────────────────────────────────────────────────────────────────\n\n// Joins path segments into a dot-path string for error messages.\n// Segments starting with '[' are appended without a leading dot.\n// e.g. ['obj', 'key'] -> 'obj.key' ['arr', '[0]'] -> 'arr[0]' [] -> '.'\nfunction pathStr(path: Array<string>): string {\n if (!path.length) return '.';\n let result = '';\n for (const seg of path) {\n if (seg.startsWith('[')) result += seg;\n else result += (result ? '.' : '') + seg;\n }\n return result;\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Base — default _canSanitize = isValid (correct for primitives)\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Shared base; overrides _canSanitize only when the structural check must differ from isValid. */\nabstract class Base<T, IsOptional extends boolean = false> implements PxSchema<T, IsOptional> {\n // `declare` emits no runtime code; purely satisfies the interface's phantom _optional property.\n declare readonly _optional: IsOptional;\n abstract sanitize(raw: unknown): T;\n abstract isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean;\n abstract readonly _default: T;\n\n _canSanitize(raw: unknown): boolean { return this.isValid(raw); }\n\n optional(): PxSchema<T | undefined, true> { return new Optional(this); }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Optional wrapper\n// Uses _canSanitize (not isValid) so that partially-valid nested objects are\n// repaired rather than dropped entirely.\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Wraps any schema to make its value optional.\n * sanitize uses _canSanitize (not isValid) so partially-valid objects are repaired, not dropped.\n */\nclass Optional<T> extends Base<T | undefined, true> {\n readonly _default = undefined as T | undefined;\n constructor(private readonly inner: PxSchema<T, any>) { super(); }\n\n sanitize(raw: unknown): T | undefined {\n if (raw === undefined || raw === null) return undefined;\n return this.inner._canSanitize(raw) ? this.inner.sanitize(raw) : undefined;\n }\n\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n if (raw === undefined || raw === null) return true;\n return this.inner.isValid(raw, ctx, path);\n }\n\n override _canSanitize(raw: unknown): boolean {\n return raw === undefined || raw === null || this.inner._canSanitize(raw);\n }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Primitives — _canSanitize = isValid (a wrong primitive type is unrecoverable)\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** String schema; wrong type is unrecoverable so _canSanitize = isValid (inherited default). */\nclass Str extends Base<string> {\n constructor(readonly _default: string = '') { super(); }\n sanitize(raw: unknown): string { return typeof raw === 'string' ? raw : this._default; }\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n if (typeof raw === 'string') return true;\n ctx?.errors.push(pathStr(path ?? []) + ': expected string, got ' + typeof raw);\n return false;\n }\n}\n\n/** Finite-number schema; rejects NaN and ±Infinity as unrecoverable. */\nclass Num extends Base<number> {\n constructor(readonly _default: number = 0) { super(); }\n sanitize(raw: unknown): number {\n return typeof raw === 'number' && isFinite(raw) ? raw : this._default;\n }\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n if (typeof raw === 'number' && isFinite(raw)) return true;\n ctx?.errors.push(pathStr(path ?? []) + ': expected finite number, got ' + JSON.stringify(raw));\n return false;\n }\n}\n\n/** Boolean schema. */\nclass Bool extends Base<boolean> {\n constructor(readonly _default: boolean = false) { super(); }\n sanitize(raw: unknown): boolean { return typeof raw === 'boolean' ? raw : this._default; }\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n if (typeof raw === 'boolean') return true;\n ctx?.errors.push(pathStr(path ?? []) + ': expected boolean, got ' + typeof raw);\n return false;\n }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Literal — exact value match; default is the literal itself\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Matches one exact primitive value; its _default is the value itself. */\nclass Literal<T extends string | number | boolean> extends Base<T> {\n readonly _default: T;\n constructor(private readonly value: T) { super(); this._default = value; }\n sanitize(raw: unknown): T { return raw === this.value ? this.value : this._default; }\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n if (raw === this.value) return true;\n ctx?.errors.push(pathStr(path ?? []) + ': expected ' + JSON.stringify(this.value) + ', got ' + JSON.stringify(raw));\n return false;\n }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Enum — union of string/number literals; default is first value\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Union of string/number literals; _default is the first value unless overridden. */\nclass Enum<T extends string | number> extends Base<T> {\n readonly _default: T;\n constructor(private readonly values: readonly T[], defaultVal?: T) {\n super();\n this._default = defaultVal ?? values[0];\n }\n sanitize(raw: unknown): T { return this.values.includes(raw as T) ? (raw as T) : this._default; }\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n if (this.values.includes(raw as T)) return true;\n ctx?.errors.push(pathStr(path ?? []) + ': expected one of ' + this.values.map(v => JSON.stringify(v)).join(' | ') + ', got ' + JSON.stringify(raw));\n return false;\n }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Union — first matching schema wins\n// _canSanitize: true if any member can attempt sanitization\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Tries member schemas in order; first whose isValid passes wins. sanitize returns _default when none match. */\nclass Union<T> extends Base<T> {\n readonly _default: T;\n constructor(private readonly schemas: ReadonlyArray<PxSchema<T>>, defaultVal?: T) {\n super();\n this._default = defaultVal ?? schemas[0]._default;\n }\n sanitize(raw: unknown): T {\n for (const s of this.schemas) {\n if (s.isValid(raw)) return s.sanitize(raw);\n }\n return this._default;\n }\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n // Test members without ctx — avoids spurious errors from non-matching branches.\n if (this.schemas.some(s => s.isValid(raw))) return true;\n ctx?.errors.push(pathStr(path ?? []) + ': no union member matched for value ' + (JSON.stringify(raw) ?? '').slice(0, 60));\n return false;\n }\n override _canSanitize(raw: unknown): boolean { return this.schemas.some(s => s._canSanitize(raw)); }\n}\n\n// Infers the union of all member types from a tuple of schemas\ntype UnionMembers<T extends ReadonlyArray<PxSchema<any, any>>> =\n T extends ReadonlyArray<PxSchema<infer U, any>> ? U : never;\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// DiscriminatedUnion — routes by a literal key field, not first-match order\n// ─────────────────────────────────────────────────────────────────────────────\n\ntype AnyDiscriminantShape<K extends string> = Record<K, PxSchema<string | number | boolean, any>>;\n\n/**\n * Reads `raw[key]`, finds the member schema whose literal matches that value,\n * then delegates sanitize/isValid to that member. Falls back to the first\n * member for sanitize when no match is found.\n */\nclass DiscriminatedUnion<T> extends Base<T> {\n readonly _default: T;\n private readonly _map: Map<string | number | boolean, PxSchema<T>>;\n\n constructor(\n private readonly _key: string,\n private readonly _schemas: ReadonlyArray<PxSchema<T> & { readonly _shape: AnyDiscriminantShape<string> }>,\n defaultVal?: T\n ) {\n super();\n this._default = defaultVal ?? _schemas[0]._default;\n this._map = new Map();\n for (const s of _schemas) {\n const keySchema = s._shape[_key];\n if (keySchema) this._map.set(keySchema._default, s);\n }\n }\n\n private _findSchema(raw: unknown): PxSchema<T> | undefined {\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) return undefined;\n const val = (raw as Record<string, unknown>)[this._key];\n if (val === undefined || val === null) return undefined;\n return this._map.get(val as string | number | boolean);\n }\n\n sanitize(raw: unknown): T {\n return (this._findSchema(raw) ?? this._schemas[0]).sanitize(raw);\n }\n\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n const schema = this._findSchema(raw);\n if (!schema) {\n const val = (raw !== null && typeof raw === 'object' && !Array.isArray(raw))\n ? (raw as Record<string, unknown>)[this._key] : undefined;\n ctx?.errors.push(pathStr(path ?? []) + ': no discriminated union member matched '\n + this._key + '=' + JSON.stringify(val));\n return false;\n }\n return schema.isValid(raw, ctx, path);\n }\n\n override _canSanitize(raw: unknown): boolean {\n if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) return false;\n const schema = this._findSchema(raw);\n return schema ? schema._canSanitize(raw) : this._schemas[0]._canSanitize(raw);\n }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Object — strips unknown keys; required fields use default, optional → undefined\n// _canSanitize: true when raw is a plain (non-array) object\n// ─────────────────────────────────────────────────────────────────────────────\n\ntype AnyShape = Record<string, PxSchema<any, any>>;\n\n// Required keys: IsOptional=false → plain property.\n// Optional keys: IsOptional=true → ?:, with Exclude<T,undefined> (?: already adds undefined).\ntype InferShape<S extends AnyShape> =\n { [K in keyof S as S[K] extends PxSchema<any, true> ? never : K]: PxInfer<S[K]> } &\n { [K in keyof S as S[K] extends PxSchema<any, true> ? K : never]?: Exclude<PxInfer<S[K]>, undefined> };\n\n/**\n * Typed object schema; strips unknown keys, repairs required fields via their defaults.\n * _canSanitize checks structure only (non-array object) so partially-valid objects are repaired.\n */\nclass Obj<S extends AnyShape> extends Base<InferShape<S>> {\n readonly _default: InferShape<S>;\n\n constructor(readonly _shape: S) {\n super();\n const d: any = {};\n for (const key of Object.keys(_shape)) d[key] = _shape[key]._default;\n this._default = d;\n }\n\n sanitize(raw: unknown): InferShape<S> {\n const src = (raw && typeof raw === 'object' && !Array.isArray(raw)) ? raw as any : {};\n const out: any = {};\n for (const key of Object.keys(this._shape)) {\n out[key] = this._shape[key].sanitize(src[key]);\n }\n return out;\n }\n\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n ctx?.errors.push(pathStr(path ?? []) + ': expected object, got ' + (Array.isArray(raw) ? 'array' : typeof raw));\n return false;\n }\n const obj = raw as any;\n const p = path ?? [];\n let ok = true;\n for (const key of Object.keys(this._shape)) {\n p.push(key);\n if (!this._shape[key].isValid(obj[key], ctx, p)) ok = false;\n p.pop();\n }\n // Strict mode: closed objects reject extra (undeclared) keys.\n // Default mode silently ignores them (matching `sanitize`'s strip-extras).\n if (ctx?.strict) {\n for (const key of Object.keys(obj)) {\n if (key in this._shape) continue;\n p.push(key);\n ctx.errors.push(pathStr(p) + ': unexpected extra key');\n p.pop();\n ok = false;\n }\n }\n return ok;\n }\n\n override _canSanitize(raw: unknown): boolean {\n return !!raw && typeof raw === 'object' && !Array.isArray(raw);\n }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// OpenObj — like Obj but passes unknown keys through unchanged (or validates/sanitizes\n// them against an optional open-value schema).\n// Known keys are validated/sanitized; unknown keys are passed through as-is when no\n// open schema is given, or validated/sanitized against the open schema when one is provided.\n// Inferred type: InferShape<S> & { [key: string]: V } where V defaults to any.\n// Note: TypeScript intersection semantics mean named-property access on the\n// derived type yields `any` rather than the specific declared type. For\n// type-precise access keep a hand-written interface alongside the schema.\n// ─────────────────────────────────────────────────────────────────────────────\n\ntype InferOpenShape<S extends AnyShape, _V = any> = InferShape<S> & { [key: string]: any };\n\n/**\n * Open object schema; validates/repairs known keys, passes unknown keys through unchanged.\n * Use when the object may carry arbitrary extra properties (e.g. SVG element attributes).\n *\n * @param shape Known key schemas (validated and type-inferred).\n * @param openSchema Optional schema applied to every unknown key's value.\n * When omitted, unknown values are passed through as-is (`any`).\n */\nclass OpenObj<S extends AnyShape, V = any> extends Base<InferOpenShape<S, V>> {\n readonly _default: InferOpenShape<S, V>;\n\n constructor(readonly _shape: S, private readonly _openSchema?: PxSchema<V>) {\n super();\n const d: any = {};\n for (const key of Object.keys(_shape)) d[key] = _shape[key]._default;\n this._default = d;\n }\n\n sanitize(raw: unknown): InferOpenShape<S, V> {\n const src: Record<string, unknown> = (raw && typeof raw === 'object' && !Array.isArray(raw))\n ? raw as Record<string, unknown>\n : {};\n const out: Record<string, unknown> = { ...src };\n for (const key of Object.keys(this._shape)) {\n out[key] = this._shape[key].sanitize(src[key]);\n }\n if (this._openSchema) {\n for (const key of Object.keys(src)) {\n if (!(key in this._shape)) out[key] = this._openSchema.sanitize(src[key]);\n }\n }\n return out as InferOpenShape<S, V>;\n }\n\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n ctx?.errors.push(pathStr(path ?? []) + ': expected object, got ' + (Array.isArray(raw) ? 'array' : typeof raw));\n return false;\n }\n const obj = raw as any;\n const p = path ?? [];\n let ok = true;\n for (const key of Object.keys(this._shape)) {\n p.push(key);\n if (!this._shape[key].isValid(obj[key], ctx, p)) ok = false;\n p.pop();\n }\n if (this._openSchema) {\n for (const key of Object.keys(obj)) {\n if (key in this._shape) continue;\n p.push(key);\n if (!this._openSchema.isValid(obj[key], ctx, p)) ok = false;\n p.pop();\n }\n }\n return ok;\n }\n\n override _canSanitize(raw: unknown): boolean {\n return !!raw && typeof raw === 'object' && !Array.isArray(raw);\n }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Array — items that cannot be attempted are filtered out; default is []\n// Uses _canSanitize for filtering so partially-valid objects are repaired, not dropped.\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Array schema; items failing _canSanitize are filtered out rather than blocking the whole array. */\nclass Arr<T> extends Base<Array<T>> {\n readonly _default: Array<T> = [];\n constructor(private readonly item: PxSchema<T>) { super(); }\n\n sanitize(raw: unknown): Array<T> {\n if (!Array.isArray(raw)) return [];\n const out: Array<T> = [];\n for (const el of raw) {\n if (this.item._canSanitize(el)) out.push(this.item.sanitize(el));\n }\n return out;\n }\n\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n if (!Array.isArray(raw)) {\n ctx?.errors.push(pathStr(path ?? []) + ': expected array, got ' + typeof raw);\n return false;\n }\n const p = path ?? [];\n let ok = true;\n for (let i = 0; i < raw.length; i++) {\n p.push('[' + i + ']');\n if (!this.item.isValid(raw[i], ctx, p)) ok = false;\n p.pop();\n }\n return ok;\n }\n\n override _canSanitize(raw: unknown): boolean { return Array.isArray(raw); }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Record — invalid values are dropped; default is {}\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** String-keyed record; values failing _canSanitize are dropped rather than blocking the whole record. */\nclass Rec<T> extends Base<Record<string, T>> {\n readonly _default: Record<string, T> = {};\n constructor(private readonly value: PxSchema<T>) { super(); }\n\n sanitize(raw: unknown): Record<string, T> {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return {};\n const out: Record<string, T> = {};\n for (const [k, v] of Object.entries(raw)) {\n if (this.value._canSanitize(v)) out[k] = this.value.sanitize(v);\n }\n return out;\n }\n\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n ctx?.errors.push(pathStr(path ?? []) + ': expected object/record, got ' + (Array.isArray(raw) ? 'array' : typeof raw));\n return false;\n }\n const p = path ?? [];\n let ok = true;\n for (const [k, v] of Object.entries(raw as object)) {\n p.push(k);\n if (!this.value.isValid(v, ctx, p)) ok = false;\n p.pop();\n }\n return ok;\n }\n\n override _canSanitize(raw: unknown): boolean {\n return !!raw && typeof raw === 'object' && !Array.isArray(raw);\n }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Any — passes raw through unchanged, always valid\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Passes any value through unchanged; always valid. Useful for opaque blobs with no schema. */\nclass Any extends Base<any> {\n readonly _default: any = undefined;\n sanitize(raw: unknown): any { return raw; }\n isValid(_raw: unknown, _ctx?: PxValidationContext, _path?: Array<string>): boolean { return true; }\n override _canSanitize(_raw: unknown): boolean { return true; }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Lazy — resolves schema on first use, required for recursive types\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Defers schema resolution to first use; required to break circular references in recursive types. */\nclass Lazy<T> extends Base<T> {\n private resolved: PxSchema<T> | null = null;\n constructor(private readonly fn: () => PxSchema<T>, readonly _default: T) { super(); }\n\n private get schema(): PxSchema<T> {\n return this.resolved ?? (this.resolved = this.fn());\n }\n\n sanitize(raw: unknown): T { return this.schema.sanitize(raw); }\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean { return this.schema.isValid(raw, ctx, path); }\n override _canSanitize(raw: unknown): boolean { return this.schema._canSanitize(raw); }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Tuple — fixed-length array with per-position schemas; default is defaults of each position\n// _canSanitize: true only when raw is an array of the exact expected length\n// ─────────────────────────────────────────────────────────────────────────────\n\n// Maps a tuple of schemas to a tuple of their inferred types.\ntype TupleItems<T extends ReadonlyArray<PxSchema<any, any>>> =\n { -readonly [K in keyof T]: T[K] extends PxSchema<infer U, any> ? U : never };\n\n/** Fixed-length array schema; validates element count and each position individually. */\nclass Tuple<T extends ReadonlyArray<PxSchema<any, any>>> extends Base<TupleItems<T>> {\n readonly _default: TupleItems<T>;\n\n constructor(private readonly schemas: T) {\n super();\n this._default = schemas.map(s => s._default) as unknown as TupleItems<T>;\n }\n\n sanitize(raw: unknown): TupleItems<T> {\n if (!Array.isArray(raw) || raw.length !== this.schemas.length) return this._default;\n return this.schemas.map((s, i) => s.sanitize((raw as unknown[])[i])) as unknown as TupleItems<T>;\n }\n\n isValid(raw: unknown, ctx?: PxValidationContext, path?: Array<string>): boolean {\n if (!Array.isArray(raw) || raw.length !== this.schemas.length) {\n ctx?.errors.push(pathStr(path ?? []) + ': expected tuple of length ' + this.schemas.length + ', got ' + (Array.isArray(raw) ? 'array[' + (raw as unknown[]).length + ']' : typeof raw));\n return false;\n }\n const p = path ?? [];\n let ok = true;\n for (let i = 0; i < this.schemas.length; i++) {\n p.push('[' + i + ']');\n if (!(this.schemas as ReadonlyArray<PxSchema<any, any>>)[i].isValid((raw as unknown[])[i], ctx, p)) ok = false;\n p.pop();\n }\n return ok;\n }\n\n // Require exact length so wrong-length arrays are dropped rather than repaired to default.\n override _canSanitize(raw: unknown): boolean {\n return Array.isArray(raw) && raw.length === this.schemas.length;\n }\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// implementsInterface — compile-time lock between a schema and an interface\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Returns a pass-through wrapper that enforces at compile time that the schema's\n * inferred type is structurally assignable to `T`. Catches type mismatches on\n * required fields and value-type mismatches on optional fields.\n *\n * For key-level equality (catching optional field renames), pair with a\n * `KeysMatch` assertion after the inferred type alias:\n * ```ts\n * const _ck: KeysMatch<PxFoo, _PxFoo> = true;\n * ```\n *\n * @example\n * export const PxLoopSchema = implementsInterface<_PxLoop>()(px.object({ ... }));\n */\nexport function implementsInterface<T>() {\n return <S extends PxSchema<T>>(schema: S): S => schema;\n}\n\n/**\n * Evaluates to `true` when A and B have exactly the same set of keys; `false` otherwise.\n * Use with a `const` assertion to get a compile-time error on key renames:\n * ```ts\n * const _ck: KeysMatch<PxFoo, _PxFoo> = true;\n * ```\n */\nexport type KeysMatch<A, B> =\n [Exclude<keyof A, keyof B>] extends [never]\n ? [Exclude<keyof B, keyof A>] extends [never] ? true : false\n : false;\n\n/**\n * Builds a `{ key: 'key', ... }` object from a schema's shape.\n * Each value is typed as the literal key name, so `schemaKeys(PxFooSchema).bar`\n * is typed as `'bar'` — use in @serializable calls to get a compile-time error\n * if the field is renamed in the schema.\n */\nexport function schemaKeys<S extends { readonly _shape: Record<string, any> }>(schema: S) {\n return Object.fromEntries(\n Object.keys(schema['_shape']).map(k => [k, k])\n ) as { [K in keyof S['_shape']]: K };\n}\n\n/**\n * Describes the structural kind of a schema for traversal purposes.\n * Use with `getMissingCoveragePaths` or similar tree-walking utilities.\n *\n * - `shape` — object schema (Obj/OpenObj); `shape` maps key → sub-schema\n * - `array` — array schema; `item` is the element schema\n * - `optional` — optional wrapper; `inner` is the wrapped schema\n * - `lazy` — lazy/recursive schema; `resolved` is the resolved schema (cached)\n * - `leaf` — primitive, union, record, any, tuple — no traversable children\n */\nexport type PxSchemaDesc =\n | { kind: 'shape'; shape: Record<string, PxSchema<any, any>> }\n | { kind: 'array'; item: PxSchema<any, any> }\n | { kind: 'optional'; inner: PxSchema<any, any> }\n | { kind: 'lazy'; resolved: PxSchema<any, any> }\n | { kind: 'leaf' };\n\nexport function describeSchema(schema: PxSchema<any, any>): PxSchemaDesc {\n const s = schema as any;\n if ('_shape' in s) return { kind: 'shape', shape: s._shape };\n if ('item' in s) return { kind: 'array', item: s.item };\n if ('inner' in s) return { kind: 'optional', inner: s.inner };\n if ('fn' in s) return { kind: 'lazy', resolved: s.resolved ?? s.fn() };\n return { kind: 'leaf' };\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Public factory\n// ─────────────────────────────────────────────────────────────────────────────\n\nexport const px = {\n /** Matches a string. Default: '' or provided value. */\n string: (defaultVal = ''): PxSchema<string> => new Str(defaultVal),\n\n /** Matches a finite number. Default: 0 or provided value. */\n number: (defaultVal = 0): PxSchema<number> => new Num(defaultVal),\n\n /** Matches a boolean. Default: false or provided value. */\n boolean: (defaultVal = false): PxSchema<boolean> => new Bool(defaultVal),\n\n /** Matches one exact primitive value; its default is the value itself. */\n literal: <T extends string | number | boolean>(value: T): PxSchema<T> =>\n new Literal(value),\n\n /** Matches one of a fixed set of string/number values. Default: first value. */\n enum: <T extends string | number>(values: readonly T[], defaultVal?: T): PxSchema<T> =>\n new Enum(values, defaultVal),\n\n /**\n * Returns the first schema whose isValid passes.\n * TypeScript infers the union of all member types automatically.\n */\n union: <T extends ReadonlyArray<PxSchema<any, any>>>(\n schemas: T,\n defaultVal?: UnionMembers<T>\n ): PxSchema<UnionMembers<T>> =>\n new Union(schemas as any, defaultVal) as any,\n\n /**\n * Discriminated union — reads `raw[key]`, finds the member schema whose\n * literal at `key` matches, then delegates sanitize/isValid to that member.\n * Each member must be an object schema with a `px.literal(...)` at `key`.\n * TypeScript infers the union of all member types automatically.\n */\n discriminatedUnion: <\n K extends string,\n T extends ReadonlyArray<PxSchema<any, any> & { readonly _shape: Record<K, PxSchema<string | number | boolean, any>> }>\n >(key: K, schemas: T): PxSchema<UnionMembers<T>> =>\n new DiscriminatedUnion(key, schemas as any) as any,\n\n /** Typed object — unknown keys are stripped. Required fields fall back to their default. */\n object: <S extends AnyShape>(shape: S): PxSchema<InferShape<S>> & { readonly _shape: S } =>\n new Obj(shape),\n\n /**\n * Open object — validates known keys; passes unknown keys through as-is,\n * or validates/sanitizes them against `openSchema` when provided.\n */\n openObject: <S extends AnyShape, V = any>(\n shape: S,\n openSchema?: PxSchema<V>\n ): PxSchema<InferOpenShape<S, V>> & { readonly _shape: S } =>\n new OpenObj(shape, openSchema) as any,\n\n /**\n * Creates a new closed object schema by merging a base schema's shape with additional fields.\n * The base can be the result of px.object() or px.openObject() — anything with a _shape property.\n *\n * @example\n * const PxSvgNodeSchema = px.extendedObject(PxNodeBase, { width: px.number().optional() });\n */\n extendedObject: <B extends AnyShape, E extends AnyShape>(\n base: { readonly _shape: B },\n extra: E\n ): PxSchema<InferShape<B & E>> & { readonly _shape: B & E } =>\n new Obj({ ...base._shape, ...extra } as B & E),\n\n /** Array whose unrecoverable items are filtered out. Default: []. */\n array: <T>(item: PxSchema<T>): PxSchema<Array<T>> =>\n new Arr(item),\n\n /** String-keyed record whose unrecoverable values are dropped. Default: {}. */\n record: <T>(value: PxSchema<T>): PxSchema<Record<string, T>> =>\n new Rec(value),\n\n /** Passes anything through unchanged — always valid. */\n any: (): PxSchema<any> => new Any(),\n\n /** Fixed-length tuple — validates element count and each position individually. */\n tuple: <T extends ReadonlyArray<PxSchema<any, any>>>(schemas: T): PxSchema<TupleItems<T>> =>\n new Tuple(schemas),\n\n /** Defers schema creation — required for recursive types. Must supply a default value. */\n lazy: <T>(fn: () => PxSchema<T>, defaultVal: T): PxSchema<T> =>\n new Lazy(fn, defaultVal),\n} as const;\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport type { KeysMatch, PxInfer, PxSchema, PxValidationContext, RemoveIndex } from './PxSchema';\nimport { implementsInterface, px } from './PxSchema';\n\nexport type FillMode = 'forwards' | 'backwards' | 'both' | 'none';\n\nexport type PlaybackDirection = 'normal' | 'reverse' | 'alternate' | 'alternate-reverse';\n\nexport const PX_ANIM_SRC_ATTR_NAME = 'data-px-animation-src';\n\nexport const PX_ANIM_ATTR_NAME = '_px_animator';\n\nexport type StartOn = 'load' | 'mouseOver' | 'click' | 'scrollIntoView';\n\nexport type OutAction = 'continue' | 'pause' | 'reset' | 'reverse';\n\n/** Animation engine selection (config level). `auto` means \"try `webapi`, fall\n * back to `frames`\"; the runtime resolves it to a concrete {@link PxAnimatorEngine}\n * via `createAnimatorFromConfig`. Wire as a const-namespace + matching string\n * type so call sites can use named members (`PxAnimatorMode.frames`) instead of\n * bare string literals. */\nexport const PxAnimatorMode = {\n auto: 'auto',\n webapi: 'webapi',\n frames: 'frames',\n} as const;\nexport type PxAnimatorMode = typeof PxAnimatorMode[keyof typeof PxAnimatorMode];\n\n/** Resolved engine after `auto` dispatch — used downstream by code that always\n * knows exactly which engine is running (e.g. `getNormalisedBindings`'s\n * `engine` arg gates motion-along-path materialisation). Strictly a subset of\n * {@link PxAnimatorMode} (no `auto`). */\nexport const PxAnimatorEngine = {\n webapi: PxAnimatorMode.webapi,\n frames: PxAnimatorMode.frames,\n} as const;\nexport type PxAnimatorEngine = typeof PxAnimatorEngine[keyof typeof PxAnimatorEngine];\n\n/** @deprecated Backwards-compatibility alias — use {@link PxAnimatorMode} for the type. */\nexport type JsMode = PxAnimatorMode;\n\n\nexport const TEXT_ATTR = 'text';\nexport const TEXT_CONTENT_ATTR = 'textContent';\n\n// Attributes that should not be set on DOM elements (internal use only)\nexport const INTERNAL_ATTRS = new Set([\n 'type', 'children', 'animator', 'meta', 'animate', TEXT_ATTR, TEXT_CONTENT_ATTR\n]);\n\n\n// ============================================================================\n// EASING\n// ============================================================================\n\n/**\n * Easing function definition.\n * Can be a named reference to a predefined easing or a cubic-bezier array [x1, y1, x2, y2].\n *\n * @example \"ease-in\" | [0.68, -0.55, 0.265, 1.55]\n *\n * `string | [x1, y1, x2, y2]`\n */\nexport const PxEasingOrRefSchema = px.union([\n px.string(),\n px.tuple([px.number(), px.number(), px.number(), px.number()] as const),\n]);\n\n/**\n * Easing function definition.\n * Can be a named reference to a predefined easing or a cubic-bezier array [x1, y1, x2, y2].\n *\n * @example \"ease-in\" | \"easeOut\" | [0.68, -0.55, 0.265, 1.55]\n */\nexport type PxEasingOrRef = PxInfer<typeof PxEasingOrRefSchema>;\n\n\n// ============================================================================\n// KEYFRAME\n// ============================================================================\n\n/**\n * A single animation keyframe defining the state at a specific point in time.\n * Supports both full property names and short aliases for compact notation.\n */\nexport interface _PxKeyframe {\n\n /** Timestamp in milliseconds from animation start */\n time?: number;\n\n /** Short alias for \"time\" */\n t?: number;\n\n /** The value of the animated property at this keyframe */\n value?: any;\n\n /** Short alias for \"value\" */\n v?: any;\n\n /** Easing function applied to the interval from this keyframe to the next */\n easing?: PxEasingOrRef;\n\n /** Short alias for \"easing\" */\n e?: PxEasingOrRef;\n\n /**\n * Outgoing spatial tangent `[dx, dy]` for motion-along-path interpolation\n * (translate animations only).\n *\n * Stored as a *delta relative to* this keyframe's translate position —\n * the cubic Bezier segment between this kf and the next is built from\n * `(P0=value, P1=value+tangentOut, P2=next.value+next.tangentIn, P3=next.value)`.\n *\n * Defined when the segment leaving this keyframe is curved.\n */\n tangentOut?: [number, number];\n\n /** Short alias for \"tangentOut\" */\n to?: [number, number];\n\n /**\n * Incoming spatial tangent `[dx, dy]` for motion-along-path interpolation\n * (translate animations only). Delta relative to this keyframe's translate\n * position. See `tangentOut` for the segment construction.\n *\n * Defined when the segment arriving at this keyframe is curved.\n */\n tangentIn?: [number, number];\n\n /** Short alias for \"tangentIn\" */\n ti?: [number, number];\n\n /**\n * Editor-side UI state (whether the keyframe is selected in the timeline).\n * Declared here so strict-mode schema validation accepts it on the wire —\n * the Player ignores it.\n */\n selected?: boolean;\n}\n\n/**\n * Allowed shapes for a single keyframe `value` across the wire schema:\n * - `number` — scalar properties (rotate-degree, opacity, offset-distance, …)\n * - `Array<number>` — vector properties (translate `[x,y]`, scale `[sx,sy]`, stroke-dasharray, RGBA …)\n * - `string` — color (hex / `url(#…)` / named) and other string-valued props\n * - `PxTransformParts` — unified body `transform` parts record\n * `{translate, rotate, scale, origin}`\n * - `{ paths: Array<PxBezierPath> }` — animated SVG path `d` value\n *\n * Used as documentation / explicit-validation entry point; `PxKeyframeSchema`\n * itself stores `value` as `any` to keep downstream interpolator code in\n * `PxDefinitions.ts` working with duck-typed access (`prevV?.paths`,\n * `Array.isArray(prevV)`, …) without per-shape narrowing.\n */\nexport type _PxKeyframeValue =\n | string\n | number\n | Array<number>\n | PxTransformParts\n | { path: string }\n | { paths: Array<PxBezierPath> };\n\n// `string | number | Array<number> | PxTransformParts | { path: string } | { paths: BezierPath[] }`\n//\n// `{ path: \"M…\" }` is the unified single-`d`-string form for animated paths\n// (compound shapes are one string with multiple `M…` sub-paths); `{ paths: […] }`\n// is the legacy bezier-array form, both accepted.\n//\n// `PxTransformPartsSchema` / `PxBezierPathSchema` are declared later in this\n// file — `px.lazy` defers the lookup until validation time so the declarations\n// stay in narrative order without a TDZ at module load.\nexport const PxKeyframeValueSchema = implementsInterface<_PxKeyframeValue>()(px.union([\n px.string(), // e.g. for colors\n px.number(),\n px.array(px.number()),\n px.lazy<PxTransformParts>(() => PxTransformPartsSchema, {}),\n px.object({ path: px.string() }),\n px.lazy<{ paths: Array<PxBezierPath> }>(() => px.object({ paths: px.array(PxBezierPathSchema) }), { paths: [] }),\n]));\n\n/** A single keyframe `value` — union of all wire-allowed shapes. */\nexport type PxKeyframeValue = PxInfer<typeof PxKeyframeValueSchema>;\n\n// `{ time?:number, t?:number, value?:any, v?:any, easing?:Easing, e?:Easing,\n// tangentOut?:[dx,dy], tangentIn?:[dx,dy] }`\n//\n// `value` / `v` are stored as `px.any()` to match the `_PxKeyframe` interface\n// (`value?: any`) and to keep the inferred `PxKeyframe.value` type permissive\n// for the duck-typed access in `PxDefinitions.ts`. The structured value-shape\n// union is still available via {@link PxKeyframeValueSchema} for callers that\n// want to validate or document the allowed shapes.\nexport const PxKeyframeSchema = implementsInterface<_PxKeyframe>()(px.object({\n time: px.number().optional(),\n t: px.number().optional(),\n value: px.any().optional(),\n v: px.any().optional(),\n easing: PxEasingOrRefSchema.optional(),\n e: PxEasingOrRefSchema.optional(),\n tangentOut: px.tuple([px.number(), px.number()] as const).optional(),\n to: px.tuple([px.number(), px.number()] as const).optional(), // short alias\n tangentIn: px.tuple([px.number(), px.number()] as const).optional(),\n ti: px.tuple([px.number(), px.number()] as const).optional(), // short alias\n selected: px.boolean().optional(), // editor-side UI state (Player ignores it)\n}));\n\n/**\n * A single animation keyframe defining the state at a specific point in time.\n *\n * Generic over the keyframe `value` type for callers that know the per-property\n * value shape (e.g. `PxKeyframe<Vec2>` in the effect appliers). Defaults to\n * `any`, matching the schema (`value` is stored as `px.any()` on the wire).\n */\nexport type PxKeyframe<T = any> = Omit<PxInfer<typeof PxKeyframeSchema>, 'value' | 'v'> & { value?: T; v?: T };\nconst _ck_PxKeyframe: KeysMatch<PxKeyframe, _PxKeyframe> = true; // the key sets are identical\n\n\n// ============================================================================\n// LOOP\n// ============================================================================\n\n/**\n * Defines how a property's keyframe animation is extended beyond its defined keyframe range\n * by continuously repeating a chosen segment of the sequence.\n *\n * The repeated segment is a contiguous run of keyframe *intervals* (gaps between consecutive\n * keyframes). Which end of the sequence is repeated is controlled by `before`, and whether\n * each repetition plays in the same direction or alternates is controlled by `alternate`.\n *\n * **Relationship to `animator.iterations`**\n *\n * `PxLoop` and `animator.iterations` are independent mechanisms operating at different levels:\n *\n * - `PxLoop` is a **pre-processing step**: it expands the property's keyframe list to fill the\n * full `animator.duration` before any playback begins. The runtime sees a single, fully\n * expanded keyframe sequence — it has no knowledge of the loop.\n *\n * - `animator.iterations` repeats the **entire document timeline** (all properties, all\n * elements) as a unit, after the expanded keyframes are already in place.\n *\n * The two compose independently: a property with `loop: true` inside a document with\n * `iterations: \"infinite\"` will cycle its own segment within each document iteration, and\n * that iteration will itself repeat forever — loop-within-loop.\n */\nexport interface _PxLoop {\n\n /**\n * Number of keyframe intervals (gaps between consecutive keyframes) that form the repeating\n * segment.\n *\n * - `undefined` → the entire keyframe sequence is used as the loop segment.\n * - `N` → only the first `N` intervals (when `before: true`) or the last `N` intervals\n * (when `before: false`) are looped. Clamped to `[1, keyframes.length - 1]`.\n */\n segmentCount?: number;\n\n /**\n * Selects which end of the keyframe sequence is looped.\n *\n * - `true` → the source segment is taken from the *start* of the keyframe sequence.\n * The animation is extended *before* the first keyframe — useful for intro loops\n * that run before the main timeline begins.\n *\n * - `false` (default) → the source segment is taken from the *end* of the keyframe sequence.\n * The animation is extended *after* the last keyframe — useful for idle or outro\n * loops that continue once the main timeline has finished.\n */\n before?: boolean;\n\n /**\n * Controls playback direction on each successive loop iteration.\n *\n * - `false` (default) → **cycle**: every iteration replays the segment in the same direction.\n *\n * - `true` → **pingpong**: iterations alternate between forward and backward playback\n * (even iterations play forward, odd iterations play in reverse).\n */\n alternate?: boolean;\n}\n\n// `{ segmentCount?:number, before?:boolean, alternate?:boolean }`\nexport const PxLoopSchema = implementsInterface<_PxLoop>()(px.object({\n segmentCount: px.number().optional(),\n before: px.boolean().optional(),\n alternate: px.boolean().optional(),\n}));\n\n/**\n * Defines how a property's keyframe animation is extended beyond its defined keyframe range\n * by continuously repeating a chosen segment of the sequence.\n */\nexport type PxLoop = PxInfer<typeof PxLoopSchema>;\nconst _ck_PxLoop: KeysMatch<PxLoop, _PxLoop> = true; // the key sets are identical\n\n\n// ============================================================================\n// PROPERTY ANIMATION\n// ============================================================================\n\n/**\n * Animation definition for a single CSS/SVG property.\n * Contains an array of keyframes that define how the property changes over time.\n */\nexport interface _PxPropertyAnimation {\n\n /** Array of keyframes defining the animation timeline */\n keyframes?: PxKeyframe[];\n\n /** Short alias for \"keyframes\" */\n kfs?: PxKeyframe[];\n\n /**\n * Optional loop configuration. When set, the keyframe sequence is expanded at pre-processing\n * time to fill the gap between the keyframe range and `animator.duration` by repeating a\n * chosen segment. `true` is shorthand for the default {@link PxLoop} (loop the last segment\n * after the final keyframe, cycling forward). See {@link PxLoop} for details.\n *\n * Note: this operates independently of `animator.iterations` — see {@link _PxLoop} for the\n * interaction between the two.\n */\n loop?: PxLoop | boolean;\n\n /**\n * Motion-along-path \"auto-orient\" flag. Only meaningful for translate\n * animations whose keyframes carry spatial tangents (`tangentIn` /\n * `tangentOut`): when true, the element rotates so its local X axis aligns\n * with the path tangent at the current position. The rotation is computed\n * from the cubic-Bezier derivative at the eased progress along the\n * arc-length-parametrised segment.\n */\n autoOrient?: boolean;\n}\n\n// `{ keyframes?:Keyframe[], kfs?:Keyframe[], loop?:Loop|boolean, autoOrient?:bool }`\nexport const PxPropertyAnimationSchema = implementsInterface<_PxPropertyAnimation>()(px.object({\n keyframes: px.array(PxKeyframeSchema).optional(),\n kfs: px.array(PxKeyframeSchema).optional(),\n loop: px.union([PxLoopSchema, px.boolean()]).optional(),\n autoOrient: px.boolean().optional(),\n}));\n\n/** Animation definition for a single CSS/SVG property. */\nexport type PxPropertyAnimation = PxInfer<typeof PxPropertyAnimationSchema>;\nconst _ck_PxPropertyAnimation: KeysMatch<PxPropertyAnimation, _PxPropertyAnimation> = true; // the key sets are identical\n\n\n// ============================================================================\n// TRANSFORM\n// ============================================================================\n\n/**\n * Names of the transform parts that can appear inside a transform value record.\n * The unified `transform` slot replaces the earlier per-part top-level keys\n * (`translate`, `rotate`, `scale`, `origin`) — those names now live as keys\n * inside a `PxTransformParts` record.\n */\nexport const PX_TRANSFORM_PART_KEYS = ['translate', 'rotate', 'scale', 'origin'] as const;\n\n/** One of the transform-part key strings. */\nexport type PxTransformPartKey = typeof PX_TRANSFORM_PART_KEYS[number];\n\n/**\n * Record of transform parts forming a single transform `value`. Each present\n * key contributes one segment of the composed CSS transform string at render /\n * interpolation time, in the canonical order\n * `translate, translate(+origin), rotate, scale, translate(-origin)`.\n *\n * `origin` is meaningful only when `rotate` or `scale` is also present in the\n * same record — see \"When does origin belong inside a keyframe value?\" in\n * `file-format-remaining-design-issues2.md`.\n */\nexport interface _PxTransformParts {\n\n /** Translation offset `[x, y]` in user units. */\n translate?: [number, number];\n\n /** Rotation in degrees. */\n rotate?: number;\n\n /** Skew (skewX) in degrees, pivoting at `origin` — composed between `rotate`\n * and `scale` (matches Lottie's transform order). */\n skew?: number;\n\n /** Scale factor `[sx, sy]`. */\n scale?: [number, number];\n\n /**\n * Pivot for rotate / scale `[x, y]`. Only meaningful alongside `rotate` or\n * `scale` in the same record.\n */\n origin?: [number, number];\n}\n\n// `{ translate?:[x,y], rotate?:deg, skew?:deg, scale?:[sx,sy], origin?:[x,y] }`\nexport const PxTransformPartsSchema = implementsInterface<_PxTransformParts>()(px.object({\n translate: px.tuple([px.number(), px.number()] as const).optional(),\n rotate: px.number().optional(),\n skew: px.number().optional(),\n scale: px.tuple([px.number(), px.number()] as const).optional(),\n origin: px.tuple([px.number(), px.number()] as const).optional(),\n}));\n\n/** Record of transform parts forming a single transform `value`. */\nexport type PxTransformParts = PxInfer<typeof PxTransformPartsSchema>;\nconst _ck_PxTransformParts: KeysMatch<PxTransformParts, _PxTransformParts> = true; // the key sets are identical\n\n/**\n * Unified `transform` slot value. Three valid shapes:\n *\n * - **SVG transform string** — `\"translate(10,10)rotate(45)scale(2,2)\"`. What\n * plain renderers consume directly.\n * - **Structured static** — `{value: PxTransformParts}`. Parametric record;\n * parts stay independently addressable.\n * - **Animated** — `{keyframes: [{time, value: PxTransformParts, …}, …]}`.\n * Each keyframe's `value` is a parts record. The interpolator composes the\n * parts into a single transform string per frame.\n *\n * Replaces the earlier convention of putting each animated transform part\n * under its own top-level attribute name (`translate`, `rotate`, `scale`,\n * `origin`).\n */\nexport const PxTransformValueSchema = px.union([\n px.string(),\n px.object({ value: PxTransformPartsSchema }),\n PxPropertyAnimationSchema,\n]);\n\n/** Unified `transform` slot value: string | structured static | animated. */\nexport type PxTransformValue = PxInfer<typeof PxTransformValueSchema>;\n\n\n// ============================================================================\n// ANIMATION DEFINITION\n// ============================================================================\n\n/**\n * Complete animation definition containing one or more property animations.\n * Each key is a CSS/SVG property name (e.g., \"opacity\", \"translate\", \"fill\").\n *\n * @example\n * { \"opacity\": { keyframes: [...] }, \"translate\": { keyframes: [...] } }\n */\nexport interface _PxAnimationDefinition {\n [property: string]: PxPropertyAnimation;\n}\n\n// `Record<propName, PropertyAnimation>`\nexport const PxAnimationDefinitionSchema = implementsInterface<_PxAnimationDefinition>()(\n px.record(PxPropertyAnimationSchema)\n);\n\n/**\n * Complete animation definition containing one or more property animations.\n * Each key is a CSS/SVG property name (e.g., \"opacity\", \"scale\", \"rotate\").\n */\nexport type PxAnimationDefinition = PxInfer<typeof PxAnimationDefinitionSchema>;\n\n\n// ============================================================================\n// ELEMENT ANIMATION\n// ============================================================================\n\n/**\n * Element animation specification. Can be:\n * - A string referencing a named animation from `definitions.animations`\n * - An array of named references\n * - An inline `AnimationDefinition` object\n * - A mixed array of references and inline definitions\n *\n * @example\n * \"fadeIn\"\n * [\"fadeIn\", \"spin\"]\n * { opacity: { keyframes: [...] } }\n * [\"fadeIn\", { scale: { keyframes: [...] } }]\n */\nexport type _PxElementAnimation =\n | string\n | string[]\n | PxAnimationDefinition\n | (string | PxAnimationDefinition)[];\n\n// `string | Array<string|AnimationDefinition> | AnimationDefinition`\nexport const PxElementAnimationSchema = implementsInterface<_PxElementAnimation>()(px.union([\n px.string(),\n px.array(px.union([px.string(), PxAnimationDefinitionSchema])),\n PxAnimationDefinitionSchema,\n]));\n\n/**\n * Element animation specification.\n * Can be a string reference, array of references, inline definition, or a mixed array.\n */\nexport type PxElementAnimation = PxInfer<typeof PxElementAnimationSchema>;\n\n\n// ============================================================================\n// TRIGGER\n// ============================================================================\n\ntype StartOnExtra = StartOn | 'programmatic';\n\n/**\n * Defines when and how an animation should be triggered.\n */\nexport interface _PxTrigger {\n\n /** Event that starts the animation */\n startOn?: StartOnExtra;\n\n /** Action to take when the trigger condition is no longer met (e.g., mouse leaves) */\n outAction?: 'continue' | 'pause' | 'reset' | 'reverse';\n\n /** Percentage of element visibility required to trigger (0–1, default 0 = any pixel).\n * Only applies to scrollIntoView. */\n scrollIntoViewThreshold?: number;\n}\n\n// `{ startOn?:'load'|'mouseOver'|'click'|'scrollIntoView'|'programmatic', outAction?:..., scrollIntoViewThreshold?:number }`\nexport const PxTriggerSchema = implementsInterface<_PxTrigger>()(px.object({\n startOn: px.enum(['load', 'mouseOver', 'click', 'scrollIntoView', 'programmatic'] as const).optional(),\n outAction: px.enum(['continue', 'pause', 'reset', 'reverse'] as const).optional(),\n scrollIntoViewThreshold: px.number().optional(),\n}));\n\n/** Defines when and how an animation should be triggered. */\nexport type PxTrigger = PxInfer<typeof PxTriggerSchema>;\nconst _ck_PxTrigger: KeysMatch<PxTrigger, _PxTrigger> = true; // the key sets are identical\n\n\n// ============================================================================\n// DEFS\n// ============================================================================\n\n/**\n * A single character's embedded outline (glyph-mode text). Coordinates and\n * advance are in the owning {@link _PxGlyphFont}'s `unitsPerEm` units, so the\n * player can render text without the original font. See svga.text.design.md.\n */\nexport interface _PxGlyph {\n /** Advance width, in the font's `unitsPerEm`. */\n width: number;\n /** Outline path `d`, in the font's `unitsPerEm` (empty for whitespace). */\n d: string;\n}\n\nexport const PxGlyphSchema = implementsInterface<_PxGlyph>()(px.object({\n width: px.number(),\n d: px.string(),\n}));\n\nexport type PxGlyph = PxInfer<typeof PxGlyphSchema>;\nconst _ck_PxGlyph: KeysMatch<PxGlyph, _PxGlyph> = true; // the key sets are identical\n\n/**\n * The used glyphs of one font, keyed by character. Referenced by a text's\n * `font-family` (the key in {@link _PxDefs.glyphs}).\n */\nexport interface _PxGlyphFont {\n /** CSS family name, e.g. \"Roboto\". */\n fFamily: string;\n /** Style notation, e.g. \"\" | \"italic\". */\n style: string;\n /** Ascent, in `unitsPerEm` units (baseline placement). */\n ascent: number;\n /** Units per em the glyph `width`/`d` are expressed in, e.g. 1000. */\n unitsPerEm: number;\n /** Outlines of the used characters, keyed by the character itself. */\n glyphs: { [char: string]: PxGlyph; };\n}\n\nexport const PxGlyphFontSchema = implementsInterface<_PxGlyphFont>()(px.object({\n fFamily: px.string(),\n style: px.string(),\n ascent: px.number(),\n unitsPerEm: px.number(),\n glyphs: px.record(PxGlyphSchema),\n}));\n\nexport type PxGlyphFont = PxInfer<typeof PxGlyphFontSchema>;\nconst _ck_PxGlyphFont: KeysMatch<PxGlyphFont, _PxGlyphFont> = true; // the key sets are identical\n\n/**\n * Reusable definitions library for easings, animations, and styles.\n * Defined once here, referenced by name on elements.\n */\nexport interface _PxDefs {\n\n /** Named cubic-bezier easing functions */\n easings?: { [name: string]: [number, number, number, number]; };\n\n /** Named animation definitions that can be referenced by elements */\n animations?: { [name: string]: PxAnimationDefinition; };\n\n /** Named style presets. A node's `style` may reference one by name;\n * resolved and applied at render time (see `resolveStyle` in PxAnimatorDOM). */\n styles?: { [name: string]: Record<string, string | number>; };\n\n /** Embedded per-font glyph outlines, keyed by the text's `font-family`.\n * Lets glyph-mode `<text>` render without an external font. */\n glyphs?: { [fontName: string]: PxGlyphFont; };\n}\n\n// `{ easings?:Record<name,[x1,y1,x2,y2]>, animations?:Record<name,AnimationDefinition>, styles?:Record<string,any>, glyphs?:Record<fontName,PxGlyphFont> }`\nexport const PxDefsSchema = implementsInterface<_PxDefs>()(px.object({\n easings: px.record(px.tuple([px.number(), px.number(), px.number(), px.number()] as const)).optional(),\n animations: px.record(PxAnimationDefinitionSchema).optional(),\n styles: px.record(px.any()).optional(),\n glyphs: px.record(PxGlyphFontSchema).optional(),\n}));\n\n/** Reusable definitions library for easings, animations, and styles. */\nexport type PxDefs = PxInfer<typeof PxDefsSchema>;\nconst _ck_PxDefs: KeysMatch<PxDefs, _PxDefs> = true; // the key sets are identical\n\n\n// ============================================================================\n// ANIMATOR CONFIG\n// ============================================================================\n\n/**\n * Global animation configuration that applies to all animations in the document.\n * Defines timing, playback behaviour, and rendering strategy.\n */\nexport interface _PxAnimatorConfig {\n\n /** JavaScript animation implementation strategy */\n mode?: PxAnimatorMode;\n\n /** Total animation duration in milliseconds */\n duration?: number;\n\n /** Delay before animation starts in milliseconds */\n delay?: number;\n\n /**\n * Number of times to repeat the entire document timeline. Use `\"infinite\"` for endless loop.\n *\n * This repeats **all properties across all elements** as a unit. It is independent of\n * per-property `loop` configuration: if a property uses `loop`, its keyframes are already\n * expanded to fill `duration` before `iterations` takes effect — the two do not interfere,\n * but they do compose (a looping property inside an infinitely iterating document loops\n * within each iteration).\n */\n iterations?: number | \"infinite\";\n\n /** After a natural finish, snap the document back to its start state (same\n * mechanics as the trigger `reset` out-action). Off by default — the animation\n * holds its end state per `fill`. */\n resetOnFinish?: boolean;\n\n /**\n * Defines which values are applied before/after the active animation period\n * (maps directly to the Web Animations API `fill` option).\n * Defaults to `'forwards'` when not set so that elements hold their final\n * state after the animation ends — consistent with Lottie and other animation\n * runtimes. Without this default, seeking to the last frame would cause\n * elements to revert to their pre-animation state.\n */\n fill?: FillMode;\n\n /** Direction of animation playback */\n direction?: PlaybackDirection;\n\n /** Target frame rate for frame-based animations (only applicable when mode=\"frames\") */\n frameRate?: number;\n\n /** Trigger configuration for when animation should start */\n trigger?: PxTrigger;\n\n /** Named easings, animations, and styles — referenced by elements */\n definitions?: PxDefs;\n\n /**\n * Animation map for pre-rendered SVG elements (Mode B).\n * Maps element IDs to their animation specs. Used when the SVG DOM already exists\n * and the player only needs to animate existing elements.\n *\n * @example { \"_px_abc\": { opacity: { keyframes: [...] } }, \"_px_def\": [\"fadeIn\"] }\n */\n animate?: Record<string, PxElementAnimation>;\n\n /** Editor-side timeline mode. Written by the editor on every document;\n * accepted on the wire and ignored by the player. */\n timeline?: string;\n\n /** Reserved for future use — accepted on the wire but currently has no effect. */\n debug?: boolean;\n\n /** Debug helper: exposes the animator instance as `window[debugInstName]`. */\n debugInstName?: string;\n}\n\n// `{ mode?, duration?, delay?, iterations?, fill?, direction?, frameRate?, trigger?, definitions?, animate?, debug?, debugInstName? }`\nexport const PxAnimatorConfigSchema = implementsInterface<_PxAnimatorConfig>()(px.object({\n mode: px.enum([PxAnimatorMode.auto, PxAnimatorMode.webapi, PxAnimatorMode.frames] as const).optional(),\n duration: px.number().optional(),\n delay: px.number().optional(),\n iterations: px.union([px.number(), px.literal('infinite')]).optional(),\n fill: px.enum(['forwards', 'backwards', 'both', 'none'] as const).optional(),\n direction: px.enum(['normal', 'reverse', 'alternate', 'alternate-reverse'] as const).optional(),\n frameRate: px.number().optional(),\n trigger: PxTriggerSchema.optional(),\n resetOnFinish: px.boolean().optional(),\n definitions: PxDefsSchema.optional(),\n animate: px.record(PxElementAnimationSchema).optional(),\n timeline: px.string().optional(),\n debug: px.boolean().optional(),\n debugInstName: px.string().optional(),\n}));\n\n/**\n * Global animation configuration that applies to all animations in the document.\n * Defines timing, playback behavior, and rendering strategy.\n */\nexport type PxAnimatorConfig = PxInfer<typeof PxAnimatorConfigSchema>;\nconst _ck_PxAnimatorConfig: KeysMatch<PxAnimatorConfig, _PxAnimatorConfig> = true; // the key sets are identical\n\n\n// ============================================================================\n// BINDING\n// ============================================================================\n\n/**\n * Binds animations to existing DOM elements by ID.\n * Used when the SVG tree is pre-rendered and animations are applied separately.\n */\nexport interface _PxBinding {\n\n /** ID targeting elements in the DOM (data-px-id=\"...\") */\n id: string;\n\n /** Animation to apply to matched elements */\n animate: PxElementAnimation;\n}\n\n// `{ id:string, animate:ElementAnimation }`\nexport const PxBindingSchema = implementsInterface<_PxBinding>()(px.object({\n id: px.string(),\n animate: PxElementAnimationSchema,\n}));\n\n/**\n * Binds animations to existing DOM elements via CSS selectors.\n * Used when the SVG tree is pre-rendered and animations are applied separately.\n */\nexport type PxBinding = PxInfer<typeof PxBindingSchema>;\nconst _ck_PxBinding: KeysMatch<PxBinding, _PxBinding> = true; // the key sets are identical\n\n\n// ============================================================================\n// NODE\n// ============================================================================\n\n/**\n * Per-attribute value shape on the element body. A property key carries either:\n * - a primitive (string/number) — static SVG attribute\n * - a `{value: …}` object — structured static parametric source (record-shaped\n * static value, used by attributes whose static representation is itself a\n * record — notably `transform: {value: PxTransformParts}`)\n * - a `{keyframes}` / `{kfs}` object — inline property animation\n *\n * The unified rule (primitive | `{value}` | `{keyframes}`) applies across the\n * format. For most attributes the `{value}` form is rarely used on the body\n * (a primitive suffices for static); for `transform` it is the canonical\n * structured-static shape. See `PxTransformValueSchema`.\n */\nexport const PxAttrValueSchema = px.union([\n px.string(),\n px.number(),\n px.object({ value: px.any() }),\n PxPropertyAnimationSchema,\n]);\n\n/** Per-attribute value: primitive for static, `{value}` for structured static, `PxPropertyAnimation` for animated. */\nexport type PxAttrValue = string | number | { value: any } | PxPropertyAnimation;\n\n\n/**\n * Base interface for all SVG elements.\n * Named properties take precedence over the index signature when accessed.\n */\nexport interface _PxNode {\n\n /** SVG element type (e.g., \"circle\", \"rect\", \"path\", \"g\") */\n type: string;\n\n /** Child elements (for container elements like <g>) */\n children?: PxNode[];\n\n /** Meta informaion about this element */\n meta?: any;\n\n /**\n * Player-effects bucket (transformation/repeater/maskedBy/trimPath/retime/ref)\n * emitted by the Editor's lightweight design format. `applyPlayerEffects`\n * materialises and removes these before any other normalisation, so the\n * Player never observes a non-empty `effects` after entry-point processing.\n *\n * Typed against `PxEffectsSchema` (closed object — strict-mode validation\n * flags unknown effect keys). Adding a new effect requires extending the\n * `_PxEffects` interface AND the schema in lockstep.\n */\n effects?: PxEffects;\n\n /**\n * In-place property animations for this element. Same shape as the\n * `animator.animate` map values: string ref, array of refs, inline\n * definition (`{propName: PxPropertyAnimation}`), or mixed array.\n * The static initial value of an animated property is still carried as a\n * plain attribute on the body.\n */\n animate?: PxElementAnimation;\n\n /**\n * FIXME - do we need it?\n * Style applied to this element (named reference or inline object)\n */\n style?: string | Record<string, string | number>;\n\n /**\n * All other SVG attributes (cx, cy, r, fill, stroke, etc.).\n * A value is either a primitive (static) or a PxPropertyAnimation (in-place\n * animation `{keyframes: [...]}` / `{kfs: [...]}`).\n */\n [key: string]: any;\n}\n\n// ============================================================================\n// PLAYER-EFFECTS BUCKET — INTERFACES + SCHEMAS (linked via `implementsInterface`)\n// ============================================================================\n//\n// Schemas for the `node.effects` payload emitted by the Editor's lightweight\n// design format. `applyPlayerEffects` (in `effects/PlayerEffectsUtil.ts`)\n// materialises and removes these before any other normalisation, so the Player\n// never observes a non-empty `effects` after entry-point processing.\n//\n// Each effect is declared as a `_Px*` interface, paired with a `Px*Schema`\n// wrapped in `implementsInterface<_Px*>()(…)`. The runtime schema and the\n// compile-time interface drift together: a new field added to either without\n// matching the other is a TS error. `KeysMatch` asserts key-set equality so\n// renames are caught too. This is the same pattern used by `PxKeyframe`,\n// `PxLoop`, etc. earlier in this file.\n//\n// `effects/types.ts` re-exports these types so the applier internals\n// (`effects/*.ts`) can still `import from './types'` unchanged.\n\n/** Fixed-length 2-number tuple. `[x, y]` for positions, `[sx, sy]` for scale, …. */\nexport type Vec2 = [number, number];\n\n/**\n * Animatable wire value: a raw static value, a `{value}` structured-static, or\n * a `{keyframes}` animation. Used by the effect schemas; the runtime schema\n * variants live below as `PxAnimatableNumberSchema` / `PxAnimatableVec2Schema`.\n *\n * Generic over the per-kf value type `T` for compile-time narrowing of the\n * static / `{value}` forms. The `{keyframes}` form uses the lib's non-generic\n * `PxKeyframe` (whose `value` is `any`) — kf values are read with care in the\n * applier (the visualModel walker / `interpParts` know per-property shapes).\n */\nexport type PxAnimatable<T> = T | { value: T } | { keyframes: Array<PxKeyframe>; autoOrient?: boolean };\n\n// PxAnimatable<number> — static number OR `{value}` static OR `{keyframes}` animated.\nconst PxAnimatableNumberSchema = px.union([\n px.number(),\n px.object({ value: px.number() }),\n px.object({\n keyframes: px.array(PxKeyframeSchema),\n autoOrient: px.boolean().optional(),\n }),\n]);\n\n// PxAnimatable<Vec2> — static `[x,y]` OR `{value:[x,y]}` OR `{keyframes}` animated.\n// `as const` on the tuples is REQUIRED for TS to infer `[number, number]` (a\n// fixed-length tuple = `Vec2`) instead of the looser `number[]`.\nconst PxAnimatableVec2Schema = px.union([\n px.tuple([px.number(), px.number()] as const),\n px.object({ value: px.tuple([px.number(), px.number()] as const) }),\n px.object({\n keyframes: px.array(PxKeyframeSchema),\n autoOrient: px.boolean().optional(),\n }),\n]);\n\n\n/** Per-part editor transform (`transformation` effect). All parts optional and animatable. */\nexport interface _PxTransformationEffect {\n translate?: PxAnimatable<Vec2>;\n rotate?: PxAnimatable<number>;\n scale?: PxAnimatable<Vec2>;\n /** Skew (skewX) in degrees — a NUMBER (matches the editor's scalar skew part). */\n skew?: PxAnimatable<number>;\n origin?: PxAnimatable<Vec2>;\n}\nexport const PxTransformationEffectSchema = implementsInterface<_PxTransformationEffect>()(px.object({\n translate: PxAnimatableVec2Schema.optional(),\n rotate: PxAnimatableNumberSchema.optional(),\n scale: PxAnimatableVec2Schema.optional(),\n skew: PxAnimatableNumberSchema.optional(),\n origin: PxAnimatableVec2Schema.optional(),\n}));\nexport type PxTransformationEffect = PxInfer<typeof PxTransformationEffectSchema>;\nconst _ck_PxTransformationEffect: KeysMatch<PxTransformationEffect, _PxTransformationEffect> = true;\n\n\n/** Per-copy repeater offsets. Each part is animatable; per-copy values scale\n * with the copy index `i` (translate/rotate/origin × i; scale per-axis `(v/100)^i`).\n * Static repeater values pass through as a structured `transform: {value:…}` on\n * the per-copy wrapper; animated values are emitted as `animate.transform.keyframes`\n * with each kf value scaled by `i`. See `effects/repeaterEffect.ts`. */\nexport interface _PxRepeaterEffect {\n copies?: number;\n translate?: PxAnimatable<Vec2>;\n rotate?: PxAnimatable<number>;\n scale?: PxAnimatable<Vec2>; // per-copy scale, stored as PERCENT (85 → 0.85)\n origin?: PxAnimatable<Vec2>;\n}\nexport const PxRepeaterEffectSchema = implementsInterface<_PxRepeaterEffect>()(px.object({\n copies: px.number().optional(),\n translate: PxAnimatableVec2Schema.optional(),\n rotate: PxAnimatableNumberSchema.optional(),\n scale: PxAnimatableVec2Schema.optional(),\n origin: PxAnimatableVec2Schema.optional(),\n}));\nexport type PxRepeaterEffect = PxInfer<typeof PxRepeaterEffectSchema>;\nconst _ck_PxRepeaterEffect: KeysMatch<PxRepeaterEffect, _PxRepeaterEffect> = true;\n\n\n/** Mask source ref + standard `<mask>` attributes. */\nexport interface _PxMaskedByEffect {\n href?: string;\n maskType?: string;\n maskUnits?: string;\n maskContentUnits?: string;\n}\nexport const PxMaskedByEffectSchema = implementsInterface<_PxMaskedByEffect>()(px.object({\n href: px.string().optional(),\n maskType: px.string().optional(),\n maskUnits: px.string().optional(),\n maskContentUnits: px.string().optional(),\n}));\nexport type PxMaskedByEffect = PxInfer<typeof PxMaskedByEffectSchema>;\nconst _ck_PxMaskedByEffect: KeysMatch<PxMaskedByEffect, _PxMaskedByEffect> = true;\n\n\n/**\n * Clip-path effect — clips the host element to a vector path. `d` is a plain SVG\n * path-data string (one or more subpaths) — the static / frame-0 geometry. `animate`\n * (optional) carries `d` keyframes (`value:{path:\"M…\"}`) for an ANIMATED clip: at apply\n * time it lands on the minted `<path>`'s `animate.d`, so the player's frame loop rewrites\n * the clip path's `d` attribute per frame. `clip-path` is a live reference, so the browser\n * re-clips each frame (unlike `<marker>` — verified across SMIL/CSS/JS/WAAPI).\n *\n * At apply time the effect mints a `<clipPath><path d/></clipPath>` def and sets\n * `clip-path=\"url(#auto-id)\"` on the host (materialiser pattern, like `maskedBy` /\n * gradient). See `effects/clipPathEffect.ts`.\n */\nexport interface _PxClipPathEffect {\n d?: string;\n animate?: PxPropertyAnimation;\n}\nexport const PxClipPathEffectSchema = implementsInterface<_PxClipPathEffect>()(px.object({\n d: px.string().optional(),\n animate: PxPropertyAnimationSchema.optional(),\n}));\nexport type PxClipPathEffect = PxInfer<typeof PxClipPathEffectSchema>;\nconst _ck_PxClipPathEffect: KeysMatch<PxClipPathEffect, _PxClipPathEffect> = true;\n\n\n/**\n * Trim-path effect. `range[0..1]` is the visible fraction of the stroke; `offset`\n * shifts the visible window along the path (also a fraction). Both are animatable.\n * `trimAllAsOne=true` chains all descendant subpath lengths into one virtual path\n * (\"Trim All As One\"): the trim window slides across siblings instead of being\n * applied to each subpath independently — see `effects/trimPathEffect.ts`.\n */\nexport interface _PxTrimPathEffect {\n offset?: PxAnimatable<number>;\n range?: PxAnimatable<Vec2>;\n trimAllAsOne?: boolean;\n}\nexport const PxTrimPathEffectSchema = implementsInterface<_PxTrimPathEffect>()(px.object({\n offset: PxAnimatableNumberSchema.optional(),\n range: PxAnimatableVec2Schema.optional(),\n trimAllAsOne: px.boolean().optional(),\n}));\nexport type PxTrimPathEffect = PxInfer<typeof PxTrimPathEffectSchema>;\nconst _ck_PxTrimPathEffect: KeysMatch<PxTrimPathEffect, _PxTrimPathEffect> = true;\n\n\n/** `<use>` retime: `baseId` = source; `start`/`timeCrop` in ms.\n * NOTE: `timeCrop` is accepted on the wire but not implemented yet — the\n * applier warns and ignores it (see `effects/retimeEffect.ts`). */\nexport interface _PxRetimeEffect {\n baseId?: string;\n start?: number;\n stretch?: number;\n timeCrop?: [number, number];\n}\nexport const PxRetimeEffectSchema = implementsInterface<_PxRetimeEffect>()(px.object({\n baseId: px.string().optional(),\n start: px.number().optional(),\n stretch: px.number().optional(),\n timeCrop: px.tuple([px.number(), px.number()] as const).optional(),\n}));\nexport type PxRetimeEffect = PxInfer<typeof PxRetimeEffectSchema>;\nconst _ck_PxRetimeEffect: KeysMatch<PxRetimeEffect, _PxRetimeEffect> = true;\n\n\n/**\n * `<use>` CLONE — merges the former `ref` + `retime` effects. A `<use>` is a clone\n * of something: `type`/`baseId` say WHAT it clones, `retime` says WHEN.\n * - `type: 'content'` → content-ref (excludes the target's own translate);\n * `type` absent → direct / whole-element link (keeps translate).\n * - `baseId` = the source element id (lives once here; the player follows `href`).\n * - `retime` = optional time-shift (nested).\n * Omitted entirely when all-default (a bare `<use href>` carries no `clone` bucket).\n */\nexport interface _PxCloneEffect {\n type?: string;\n baseId?: string;\n retime?: _PxRetimeEffect;\n}\nexport const PxCloneEffectSchema = implementsInterface<_PxCloneEffect>()(px.object({\n type: px.string().optional(),\n baseId: px.string().optional(),\n retime: PxRetimeEffectSchema.optional(),\n}));\nexport type PxCloneEffect = PxInfer<typeof PxCloneEffectSchema>;\nconst _ck_PxCloneEffect: KeysMatch<PxCloneEffect, _PxCloneEffect> = true;\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Gradient paint effect — `fillGradient` / `strokeGradient`.\n//\n// Materialiser pattern mirrors `maskedByEffect`: at apply time the gradient\n// effect mints a `<linearGradient>` / `<radialGradient>` def into `ctx.defs`,\n// then sets the host element's `fill` / `stroke` to `url(#auto-id)`. The wire\n// gradient is geometry as static parts + a stop sequence that is either static\n// (bare array) or animated (a single `{keyframes}` block whose each kf's `value`\n// is the FULL `Array<{offset, color}>` snapshot at that time). Per-stop\n// independent timelines are intentionally NOT modelled — the source is a single\n// stop-colour keyframe group.\n//\n// Stop count is constant across kfs. `gradientTransform` is captured as static\n// only (animated transform is vanishingly rare).\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Loose enums for `gradientUnits` / `spreadMethod` — kept on the wire as\n * plain strings (matches the rest of the schema's loose-enum stance) but\n * collected here so call sites use named constants instead of bare literals. */\nexport const PxGradientUnits = {\n userSpaceOnUse: 'userSpaceOnUse',\n objectBoundingBox: 'objectBoundingBox',\n} as const;\nexport type PxGradientUnits = typeof PxGradientUnits[keyof typeof PxGradientUnits];\n\nexport const PxGradientSpreadMethod = {\n pad: 'pad',\n reflect: 'reflect',\n repeat: 'repeat',\n} as const;\nexport type PxGradientSpreadMethod = typeof PxGradientSpreadMethod[keyof typeof PxGradientSpreadMethod];\n\nexport const PxGradientType = {\n linear: 'linear',\n radial: 'radial',\n} as const;\nexport type PxGradientType = typeof PxGradientType[keyof typeof PxGradientType];\n\n/** A single colour stop. `offset` is in `[0, 1]`; `color` is a CSS colour\n * string (`#rrggbb`, `rgb(…)`, `rgba(…)`, or named). */\nexport interface _PxGradientStop {\n offset: number;\n color: string;\n}\nexport const PxGradientStopSchema = implementsInterface<_PxGradientStop>()(px.object({\n offset: px.number(),\n color: px.string(),\n}));\nexport type PxGradientStop = PxInfer<typeof PxGradientStopSchema>;\nconst _ck_PxGradientStop: KeysMatch<PxGradientStop, _PxGradientStop> = true;\n\n/** `PxAnimatable<Array<PxGradientStop>>` schema. Static is the bare array;\n * `{value: […]}` wraps the same; `{keyframes}` is a single timeline whose\n * each kf's `value` is the FULL stops array at that time. */\nconst PxAnimatableGradientStopsSchema = px.union([\n px.array(PxGradientStopSchema),\n px.object({ value: px.array(PxGradientStopSchema) }),\n px.object({ keyframes: px.array(PxKeyframeSchema) }),\n]);\n\n/** Gradient paint effect — used by both `fillGradient` and `strokeGradient`\n * (same shape, different host attribute). Linear: `p1`/`p2`. Radial:\n * `c`/`r`/`fp`. Stops animate as one timeline; geometry stays static. */\n/**\n * Animatable gradient GEOMETRY channels. Keyed by wire name; the applier maps\n * each onto the real SVG attribute of the gradient def it mints:\n *\n * | wire key | linear | radial |\n * |---------------|--------|--------|\n * | `gradientX1` | `x1` | — |\n * | `gradientY1` | `y1` | — |\n * | `gradientX2` | `x2` | — |\n * | `gradientY2` | `y2` | — |\n * | `gradientCx` | — | `cx` |\n * | `gradientCy` | — | `cy` |\n * | `gradientFx` | — | `fx` |\n * | `gradientFy` | — | `fy` |\n * | `gradientR` | — | `r` |\n *\n * Frames-engine only: CSS/WAAPI cannot animate gradient endpoints, so a document\n * using these falls back to the frames engine (`mode: 'auto'` handles that).\n * See `effects/gradientEffect.ts` (`GRADIENT_ANIM_CHANNEL_TO_ATTR`).\n */\nexport interface _PxGradientGeometryAnimation {\n gradientX1?: PxPropertyAnimation;\n gradientY1?: PxPropertyAnimation;\n gradientX2?: PxPropertyAnimation;\n gradientY2?: PxPropertyAnimation;\n gradientCx?: PxPropertyAnimation;\n gradientCy?: PxPropertyAnimation;\n gradientFx?: PxPropertyAnimation;\n gradientFy?: PxPropertyAnimation;\n gradientR?: PxPropertyAnimation;\n}\nexport const PxGradientGeometryAnimationSchema = implementsInterface<_PxGradientGeometryAnimation>()(px.object({\n gradientX1: PxPropertyAnimationSchema.optional(),\n gradientY1: PxPropertyAnimationSchema.optional(),\n gradientX2: PxPropertyAnimationSchema.optional(),\n gradientY2: PxPropertyAnimationSchema.optional(),\n gradientCx: PxPropertyAnimationSchema.optional(),\n gradientCy: PxPropertyAnimationSchema.optional(),\n gradientFx: PxPropertyAnimationSchema.optional(),\n gradientFy: PxPropertyAnimationSchema.optional(),\n gradientR: PxPropertyAnimationSchema.optional(),\n}));\nexport type PxGradientGeometryAnimation = PxInfer<typeof PxGradientGeometryAnimationSchema>;\nconst _ck_PxGradientGeometryAnimation: KeysMatch<PxGradientGeometryAnimation, _PxGradientGeometryAnimation> = true;\n\nexport interface _PxFillGradientEffect {\n type: PxGradientType; // 'linear' | 'radial'\n p1?: Vec2; // linear start\n p2?: Vec2; // linear end\n c?: Vec2; // radial centre\n r?: number; // radial radius\n fp?: Vec2; // radial focal point\n stops?: PxAnimatable<Array<_PxGradientStop>>; // single animation timeline\n gradientUnits?: string; // PxGradientUnits values\n spreadMethod?: string; // PxGradientSpreadMethod values\n gradientTransform?: string; // static only in v1\n /** Animated gradient GEOMETRY (endpoints / centre / focal / radius).\n * Frames-engine only — see {@link _PxGradientGeometryAnimation}. */\n animate?: _PxGradientGeometryAnimation;\n}\nexport const PxFillGradientEffectSchema = implementsInterface<_PxFillGradientEffect>()(px.object({\n type: px.enum([PxGradientType.linear, PxGradientType.radial] as const),\n p1: px.tuple([px.number(), px.number()] as const).optional(),\n p2: px.tuple([px.number(), px.number()] as const).optional(),\n c: px.tuple([px.number(), px.number()] as const).optional(),\n r: px.number().optional(),\n fp: px.tuple([px.number(), px.number()] as const).optional(),\n stops: PxAnimatableGradientStopsSchema.optional(),\n gradientUnits: px.string().optional(),\n spreadMethod: px.string().optional(),\n gradientTransform: px.string().optional(),\n animate: PxGradientGeometryAnimationSchema.optional(),\n}));\nexport type PxFillGradientEffect = PxInfer<typeof PxFillGradientEffectSchema>;\nconst _ck_PxFillGradientEffect: KeysMatch<PxFillGradientEffect, _PxFillGradientEffect> = true;\n\n/** Stroke gradient is the same shape as fill gradient; the difference is\n * only which host attribute (`fill` vs `stroke`) the applier rewrites. */\nexport type _PxStrokeGradientEffect = _PxFillGradientEffect;\nexport const PxStrokeGradientEffectSchema = PxFillGradientEffectSchema;\nexport type PxStrokeGradientEffect = PxFillGradientEffect;\n\n/** Text-path effect on a `<text>` host. The path geometry is carried INLINE as\n * `path` (an SVG `d`; static for now, keyframed animation is a later step) — the\n * applier mints a `<path>` def from it and wraps the text's children in a native\n * `<textPath href=\"#…\">` at apply time. All SVG-native textPath attrs\n * (`lengthAdjust`, `method`, `spacing`, `startOffset`, `textLength`) ride on this\n * effect; `startOffset`/`textLength` accept the full `PxAnimatable<number>` shape.\n *\n * `pathOverflow` controls what happens to glyphs past the end of an OPEN path:\n * - `'extend'` (default): glyphs continue straight along the endpoint tangent\n * (Lottie / native-glyph behavior).\n * - `'clip'`: glyphs past the end disappear (native `<textPath>` behavior). */\nexport interface _PxTextPathEffect {\n path: string; // inline SVG `d`\n pathOverflow?: string; // 'clip' | 'extend' (default 'extend')\n lengthAdjust?: string; // 'spacing' | 'spacingAndGlyphs'\n method?: string; // 'align' | 'stretch'\n spacing?: string; // 'auto' | 'exact'\n startOffset?: PxAnimatable<number>;\n textLength?: PxAnimatable<number>;\n}\nexport const PxTextPathEffectSchema = implementsInterface<_PxTextPathEffect>()(px.object({\n path: px.string(),\n pathOverflow: px.string().optional(),\n lengthAdjust: px.string().optional(),\n method: px.string().optional(),\n spacing: px.string().optional(),\n startOffset: PxAnimatableNumberSchema.optional(),\n textLength: PxAnimatableNumberSchema.optional(),\n}));\nexport type PxTextPathEffect = PxInfer<typeof PxTextPathEffectSchema>;\nconst _ck_PxTextPathEffect: KeysMatch<PxTextPathEffect, _PxTextPathEffect> = true;\n\n\n/**\n * `effects.text` — text-rendering options for a `<text>` node.\n *\n * `useGlyphs: true` tells the player to render this text from the embedded\n * per-glyph outlines in `definitions.glyphs` (self-contained, no external\n * font) instead of a native `<text>`. See svga.text.design.md.\n */\nexport interface _PxTextEffect {\n useGlyphs?: boolean;\n}\nexport const PxTextEffectSchema = implementsInterface<_PxTextEffect>()(px.object({\n useGlyphs: px.boolean().optional(),\n}));\nexport type PxTextEffect = PxInfer<typeof PxTextEffectSchema>;\nconst _ck_PxTextEffect: KeysMatch<PxTextEffect, _PxTextEffect> = true;\n\n\n/** The full `node.effects` bucket. Closed — each known effect is declared\n * (strict-mode validation flags an unknown effect key as a wire-format drift). */\nexport interface _PxEffects {\n transformation?: _PxTransformationEffect;\n repeater?: _PxRepeaterEffect;\n maskedBy?: _PxMaskedByEffect;\n clipPath?: _PxClipPathEffect;\n trimPath?: _PxTrimPathEffect;\n clone?: _PxCloneEffect;\n isCombinedShape?: boolean;\n fillGradient?: _PxFillGradientEffect;\n strokeGradient?: _PxStrokeGradientEffect;\n textPath?: _PxTextPathEffect;\n text?: _PxTextEffect;\n}\nexport const PxEffectsSchema = implementsInterface<_PxEffects>()(px.object({\n transformation: PxTransformationEffectSchema.optional(),\n repeater: PxRepeaterEffectSchema.optional(),\n maskedBy: PxMaskedByEffectSchema.optional(),\n clipPath: PxClipPathEffectSchema.optional(),\n trimPath: PxTrimPathEffectSchema.optional(),\n clone: PxCloneEffectSchema.optional(),\n isCombinedShape: px.boolean().optional(),\n fillGradient: PxFillGradientEffectSchema.optional(),\n strokeGradient: PxStrokeGradientEffectSchema.optional(),\n textPath: PxTextPathEffectSchema.optional(),\n text: PxTextEffectSchema.optional(),\n}));\nexport type PxEffects = PxInfer<typeof PxEffectsSchema>;\nconst _ck_PxEffects: KeysMatch<PxEffects, _PxEffects> = true;\n\n/**\n * Walks `root` and validates every `node.effects` bucket against `PxEffectsSchema`.\n * Returns an array of human-readable warning strings (empty when all good).\n * Doesn't mutate the tree. Called by `createAnimatorImpl` before applying effects.\n *\n * Pass `strict: true` to also flag undeclared keys (useful in dev / tests).\n */\nexport function validateNodeEffects(root: PxNode, opts?: { strict?: boolean }): Array<string> {\n const warnings: Array<string> = [];\n // `path` is a human-readable breadcrumb prepended to each warning so the\n // reader can locate the offending node in the tree (e.g.\n // `root.children[0].children[2].effects.transformation.translate: …`).\n const walk = (node: PxNode, path: string): void => {\n if (node && node.effects) {\n const ctx: PxValidationContext = { errors: [], warnings: [], strict: !!opts?.strict };\n const ok = PxEffectsSchema.isValid(node.effects, ctx, [path + '.effects']);\n if (!ok) {\n for (const err of ctx.errors) warnings.push(err);\n }\n }\n if (node && Array.isArray(node.children)) {\n node.children.forEach((c, i) => walk(c, path + '.children[' + i + ']'));\n }\n };\n walk(root, 'root');\n return warnings;\n}\n\n\n// ============================================================================\n// NODE\n// ============================================================================\n\n/**\n * Base shape for all SVG element nodes.\n * Open object: validated known keys + arbitrary SVG attributes whose values are\n * either primitives (static) or PxPropertyAnimation objects (in-place animation).\n * Non-recursive — excludes `children` (circular reference). Used for type extraction via PxInfer.\n *\n * `{ type:string, style?:…, [key:string]: string|number|PxPropertyAnimation }`\n */\nexport const PxNodeBase = px.openObject({\n type: px.string(),\n id: px.string().optional(),\n meta: px.any().optional(),\n // Player-effects bucket emitted by the Editor's lightweight design format.\n // Consumed and removed by `applyPlayerEffects` before any other normalisation\n // (see `createAnimatorImpl`), so downstream code never sees it.\n effects: PxEffectsSchema.optional(),\n // `PxElementAnimation` (not just `PxAnimationDefinition`) — accepts\n // string ref / array of refs / inline definition / mixed array; mirrors\n // `animator.animate` map values and what `processNode` resolves at runtime.\n animate: PxElementAnimationSchema.optional(),\n style: px.union([px.string(), px.record(px.union([px.string(), px.number()]))]).optional(),\n}, PxAttrValueSchema);\n\n// `let` so the lazy closure can capture the variable reference after assignment.\n// By the time the lazy resolves (first isValid/sanitize call), PxNodeSchema is assigned.\n// `PxNodeBase & { children?:PxNode[] }`\nlet PxNodeSchema: PxSchema<any> = px.openObject({\n ...PxNodeBase._shape,\n children: px.lazy(() => px.array(PxNodeSchema), []).optional(),\n}, PxAttrValueSchema);\nexport { PxNodeSchema };\n\n/**\n * Base interface for all SVG elements.\n * Extends schema-derived typed fields; adds recursive children and the open\n * index signature for arbitrary SVG attributes (cx, cy, r, fill, etc.).\n * Named properties take precedence over the index signature when accessed.\n */\nexport interface PxNode extends PxInfer<typeof PxNodeBase> {\n children?: PxNode[];\n [key: string]: any;\n}\n\n\n// ============================================================================\n// SVG NODE (ROOT)\n// ============================================================================\n\n/**\n * Root SVG element containing the entire animated graphic.\n * Extends PxNode with SVG-specific properties and global configuration.\n */\nexport interface _PxSvgNode extends PxNode {\n\n /** FIXME - do we need it? SVG viewport width */\n width?: number;\n\n /** FIXME - do we need it? SVG viewport height */\n height?: number;\n\n /** FIXME - do we need it? SVG viewBox attribute defining coordinate system */\n viewBox?: string;\n\n /** Global animation configuration */\n animator?: PxAnimatorConfig;\n}\n\n/**\n * Extra fields present on the root SVG node, on top of PxNode.\n * Used for type extraction via PxInfer.\n *\n * `{ width?:number, height?:number, viewBox?:string, animator?:AnimatorConfig }`\n */\nexport const PxSvgNodeExtra = px.object({\n width: px.number().optional(),\n height: px.number().optional(),\n viewBox: px.string().optional(),\n animator: PxAnimatorConfigSchema.optional(),\n});\n\n/**\n * Root SVG element containing the entire animated graphic.\n * Extends PxNode (inheriting the open index signature) plus schema-derived\n * SVG-root fields.\n */\nexport interface PxSvgNode extends PxNode, PxInfer<typeof PxSvgNodeExtra> {\n}\n\n\n// ============================================================================\n// DOCUMENT\n// ============================================================================\n\n/**\n * Root SVG document schema. Enforces `type === 'svg'` to distinguish from child nodes.\n * This is the root type for the entire file format.\n *\n * `{ type:'svg', style?:…, width?:number, height?:number,\n * viewBox?:string, animator?:AnimatorConfig, children?:PxNode[],\n * [svgAttr]: string|number|PxPropertyAnimation }`\n */\nexport const PxAnimatedSvgDocumentSchema = px.openObject({\n ...PxNodeBase._shape,\n ...PxSvgNodeExtra._shape,\n type: px.literal('svg'), // override string → literal to require 'svg'\n children: px.array(PxNodeSchema).optional()\n}, PxAttrValueSchema);\n\n/**\n * The complete animated SVG document.\n * This is the root type for the entire file format.\n */\nexport interface PxAnimatedSvgDocument extends PxSvgNode {\n}\n\n\n// ============================================================================\n// API INTERFACES\n// ============================================================================\n\n/** A configuration object for animation lifecycle callbacks. */\nexport interface PxAnimatorCallbacksConfig {\n\n /** Callback executed when the animation starts or resumes. */\n onPlay?: () => void;\n\n /** Callback executed when the animation is paused. */\n onPause?: () => void;\n\n /** Callback executed when the animation is cancelled. */\n onCancel?: () => void;\n\n /** Callback executed when the animation finishes naturally. */\n onFinish?: () => void;\n\n /** Callback executed when the animation is removed. */\n onRemove?: () => void;\n}\n\n\nexport type PxPoint2D = Array<number>;\n\n\n// ============================================================================\n// BEZIER PATH\n// ============================================================================\n\n/** Represents a vector path for SVG shape animations. */\nexport interface _PxBezierPath {\n\n /** An array of vertex points [[x, y], ...]. */\n v: Array<PxPoint2D>;\n\n /** An array of 'in' tangent handles for each vertex [[x, y], ...]. */\n i?: Array<PxPoint2D>;\n\n /** An array of 'out' tangent handles for each vertex [[x, y], ...]. */\n o?: Array<PxPoint2D>;\n\n /** A boolean indicating if the path is closed. */\n c?: boolean;\n}\n\n// `{ v:number[][], i?:number[][], o?:number[][], c?:boolean }`\nexport const PxBezierPathSchema = implementsInterface<_PxBezierPath>()(px.object({\n v: px.array(px.array(px.number())),\n i: px.array(px.array(px.number())).optional(),\n o: px.array(px.array(px.number())).optional(),\n c: px.boolean().optional(),\n}));\n\n/** Represents a vector path for SVG shape animations. */\nexport type PxBezierPath = PxInfer<typeof PxBezierPathSchema>;\nconst _ck_PxBezierPath: KeysMatch<PxBezierPath, _PxBezierPath> = true; // the key sets are identical\n\n\n// ============================================================================\n// ANIMATOR API\n// ============================================================================\n\n/**\n * Basic animation controls common to all animator types.\n *\n * Generic over the platform's root-element type (`TRoot`) so this package stays\n * platform-neutral: the web player specialises it to the DOM `Element`, a\n * React Native player to its own view handle. Defaults to `unknown`.\n */\nexport interface PxBasicAnimatorAPI<TRoot = unknown> {\n\n isReady(): boolean;\n\n /** Returns the root element for the animation (platform-specific type). */\n getRootElement(): TRoot | null;\n\n /** Returns true if the animation is currently running. */\n isPlaying(): boolean;\n\n /** Starts or resumes the animation. */\n play(): void;\n\n /** Pauses the animation at its current state. */\n pause(): void;\n\n /** Stops the animation and resets it to its initial state. */\n cancel(): void;\n\n}\n\n/** The full programmatic control interface for an animation. */\nexport interface PxAnimatorAPI<TRoot = unknown> extends PxBasicAnimatorAPI<TRoot> {\n\n /** Jumps to the end of the animation and holds the final state. */\n finish(): void;\n\n /** Changes the speed of the animation. 1 is normal, 2 is double, -1 is reverse. */\n setPlaybackRate(rate: number): void;\n\n /** Returns the current playback time in milliseconds. */\n getCurrentTime(): number | null;\n\n /** Jumps to a specific time (in milliseconds) in the animation. */\n setCurrentTime(time: number): void;\n\n /** Stops the animation and cleans up all associated resources. */\n destroy(): void;\n}\n\n\n// ============================================================================\n// HELPER FUNCTIONS\n// ============================================================================\n\nexport function isPxElementFileFormat(fileJson: any): fileJson is PxAnimatedSvgDocument {\n if (!(\n fileJson &&\n typeof fileJson === 'object' &&\n !Array.isArray(fileJson)\n )) {\n return false;\n }\n\n return fileJson['type'] === 'svg' || fileJson['tagName'] === 'svg';\n}\n\n\n// ============================================================================\n// DEEP VALIDATION\n// ============================================================================\n\nexport interface PxValidationResult {\n valid: boolean;\n errors: string[];\n}\n\n/**\n * Deep validation of PxAnimatedSvgDocument using the PxAnimatedSvgDocumentSchema.\n * @returns PxValidationResult with valid flag and array of error messages\n */\nexport function isPxElementFileFormatDeep(fileJson: any): PxValidationResult {\n const valid: boolean = PxAnimatedSvgDocumentSchema.isValid(fileJson);\n return { valid, errors: valid ? [] : ['Document failed schema validation'] };\n}\n\nexport function getAnimatorConfig(doc: PxAnimatedSvgDocument): PxAnimatorConfig | undefined {\n return (\n doc?.animator || doc?.meta?.animator ||\n doc?.animation || doc?.meta?.animation // FIXME - decide on the name\n );\n}\n\nexport function getDefs(doc: PxAnimatedSvgDocument): PxDefs | undefined {\n if (!doc) return undefined;\n return getAnimatorConfig(doc)?.definitions;\n}\n\nexport function getBindings(doc: PxAnimatedSvgDocument): PxBinding[] | undefined {\n if (!doc) return undefined;\n const animate = getAnimatorConfig(doc)?.animate;\n if (!animate) return undefined;\n return Object.entries(animate).map(([id, anim]) => ({ id, animate: anim }));\n}\n\n// FIXME - do we need it?\nexport function getChildren(doc: PxAnimatedSvgDocument): PxNode[] | undefined {\n return doc?.children;\n}","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport type { PxBezierPath, PxTransformParts } from './PxAnimatorTypes';\n\n\n/**\n * Converts a PxBezierPath to an SVG path string.\n * Control points (i, o) are treated as ABSOLUTE coordinates.\n * @param {PxBezierPath} path\n * @returns {string}\n */\n/**\n * @param forceCurves Emit EVERY segment (incl. the closing one) as a cubic `C`, even when\n * its control points are degenerate (a straight line). Needed for keyframe values the\n * BROWSER interpolates (WAAPI / CSS `path()`): CSS only interpolates paths with\n * IDENTICAL command sequences, so an opportunistic `L` in one keyframe vs a `C` in the\n * next (e.g. a round-corner radius animating from 0) turns the whole animation\n * DISCRETE — it flips at 50% instead of morphing.\n */\nexport function bezierToSvgPath(path: PxBezierPath, forceCurves = false): string {\n const v = path.v;\n const i = path.i;\n const o = path.o;\n const c = path.c;\n\n if (!v.length) return \"\";\n\n const d: Array<string> = [];\n const len = v.length;\n d.push(\"M\" + v[0][0] + \",\" + v[0][1]);\n\n for (let idx = 1; idx < len; idx++) {\n const prevV = v[idx - 1];\n const prevO = o?.[idx - 1] ?? prevV;\n const currI = i?.[idx] ?? v[idx];\n const currV = v[idx];\n\n // Check if it's a straight line (control points coincide with vertices)\n const isLine = !forceCurves && (prevO[0] === prevV[0] && prevO[1] === prevV[1]) &&\n (currI[0] === currV[0] && currI[1] === currV[1]);\n\n if (isLine) {\n d.push(\"L\" + currV[0] + \",\" + currV[1]);\n } else {\n // Control points are absolute coordinates\n d.push(\"C\" + prevO[0] + \",\" + prevO[1] + \",\" + currI[0] + \",\" + currI[1] + \",\" + currV[0] + \",\" + currV[1]);\n }\n }\n\n if (c && len > 0) {\n const lastV = v[len - 1];\n const lastO = o?.[len - 1] ?? lastV;\n const firstI = i?.[0] ?? v[0];\n const firstV = v[0];\n\n // Check if closing segment is a straight line\n const isLine = !forceCurves && (lastO[0] === lastV[0] && lastO[1] === lastV[1]) &&\n (firstI[0] === firstV[0] && firstI[1] === firstV[1]);\n\n if (!isLine) {\n d.push(\"C\" + lastO[0] + \",\" + lastO[1] + \",\" + firstI[0] + \",\" + firstI[1] + \",\" + firstV[0] + \",\" + firstV[1]);\n }\n\n d.push(\"z\");\n }\n\n return d.join(\"\");\n}\n\n/**\n * @param {number} a \n * @param {number} b \n * @param {number} t \n * @returns {number}\n */\nexport function interpolateNum(a: number, b: number, t: number): number {\n return a + (b - a) * t;\n}\n\n\n/**\n * @param {Array<number>} a \n * @param {Array<number>} b \n * @param {number} t \n * @returns {Array<number>}\n */\nexport function interpolateVec(a: Array<number>, b: Array<number>, t: number): Array<number> {\n const res: Array<number> = [];\n const count = Math.max(a.length, b.length);\n for (let i = 0; i < count; i++) {\n res[i] = interpolateNum(a[i] || 0, b[i] || 0, t);\n }\n return res;\n}\n\n/**\n * Interpolates between two color arrays [r, g, b] or [r, g, b, a].\n * Normalizes both colors to 4 elements, defaulting alpha to 1 if missing.\n */\nexport function interpolateColor(a: Array<number>, b: Array<number>, t: number): Array<number> {\n return [\n interpolateNum(a[0] || 0, b[0] || 0, t),\n interpolateNum(a[1] || 0, b[1] || 0, t),\n interpolateNum(a[2] || 0, b[2] || 0, t),\n interpolateNum(a[3] === undefined ? 1 : a[3], b[3] === undefined ? 1 : b[3], t)\n ];\n}\n\n/**\n * Interpolates between two arrays of bezier paths.\n * @param paths1 The starting array of paths.\n * @param paths2 The ending array of paths.\n * @param progress The interpolation progress from 0.0 to 1.0.\n */\nexport function interpolateBeziers(\n paths1: Array<PxBezierPath>,\n paths2: Array<PxBezierPath>,\n progress: number\n): Array<PxBezierPath> {\n const count = Math.max(paths1.length, paths2.length);\n const res: Array<PxBezierPath> = [];\n for (let i = 0; i < count; i++) {\n res.push(interpolateBezier(paths1[i], paths2[i], progress));\n }\n return res;\n}\n\n/**\n * Interpolates between two bezier paths.\n * Control points (i, o) are treated as ABSOLUTE coordinates.\n * When control points are missing, they default to the vertex position.\n * @param {PxBezierPath} path1\n * @param {PxBezierPath} path2\n * @param {number} progress\n * @returns {PxBezierPath}\n */\nexport function interpolateBezier(\n path1: PxBezierPath | undefined,\n path2: PxBezierPath | undefined,\n progress: number\n): PxBezierPath {\n if (!path1 || !path2) return path1 || path2 || { v: [] };\n\n const t = Math.min(Math.max(progress, 0), 1);\n const len = Math.min(path1.v.length, path2.v.length);\n\n const v: Array<Array<number>> = [];\n const i: Array<Array<number>> = [];\n const o: Array<Array<number>> = [];\n\n for (let idx = 0; idx < len; idx++) {\n const v1 = path1.v[idx];\n const v2 = path2.v[idx];\n v.push(interpolateVec(v1, v2, t));\n\n // For absolute control points, default to vertex position (straight line)\n const i1 = path1.i?.[idx] ?? v1;\n const i2 = path2.i?.[idx] ?? v2;\n i.push(interpolateVec(i1, i2, t));\n\n const o1 = path1.o?.[idx] ?? v1;\n const o2 = path2.o?.[idx] ?? v2;\n o.push(interpolateVec(o1, o2, t));\n }\n\n return { v, i: i.length ? i : undefined, o: o.length ? o : undefined, c: path1.c ?? path2.c };\n}\n\n\n/**\n * Remap a number from one range to another.\n *\n * @param {number} value - The input value.\n * @param {number} inMin - Lower bound of the input range.\n * @param {number} inMax - Upper bound of the input range.\n * @param {number} outMin - Lower bound of the output range.\n * @param {number} outMax - Upper bound of the output range.\n * @returns The remapped value.\n */\nexport function remap(\n value: number,\n inMin: number,\n inMax: number,\n outMin: number,\n outMax: number\n): number {\n if (inMax === inMin) return outMin; // avoid divide-by-zero\n const t = (value - inMin) / (inMax - inMin);\n return outMin + t * (outMax - outMin);\n}\n\n/**\n * Solves for the parameter t such that the cubic bezier X(t) = x,\n * where the bezier has control point x-coordinates p1x and p2x\n * (endpoints are fixed at x=0 and x=1).\n * Uses Newton-Raphson with bisection fallback.\n */\nexport function solveCubicBezierX(p1x: number, p2x: number, x: number): number {\n if (x <= 0) return 0;\n if (x >= 1) return 1;\n\n const cx = 3 * p1x;\n const bx = 3 * (p2x - p1x) - cx;\n const ax = 1 - cx - bx;\n\n function sampleX(t: number) { return ((ax * t + bx) * t + cx) * t; }\n function sampleDX(t: number) { return (3 * ax * t + 2 * bx) * t + cx; }\n\n let t2 = x;\n let t0 = 0;\n let t1 = 1;\n\n for (let i = 0; i < 8; i++) {\n const x2 = sampleX(t2) - x;\n if (Math.abs(x2) < 1e-6) return t2;\n const d2 = sampleDX(t2);\n if (Math.abs(d2) < 1e-6) break;\n t2 -= x2 / d2;\n }\n\n t2 = x;\n while (t0 < t1) {\n const x2 = sampleX(t2);\n if (Math.abs(x2 - x) < 1e-6) return t2;\n if (x > x2) t0 = t2;\n else t1 = t2;\n t2 = (t1 + t0) / 2;\n }\n\n return t2;\n}\n\n/**\n * Creates a cubic-bezier easing function.\n * @param easing An array of four numbers [x1, y1, x2, y2] defining the bezier curve.\n * @returns A function that takes a progress value (0-1) and returns an eased value.\n */\nexport function cubicBezier(easing: [number, number, number, number]) {\n const [p1x, p1y, p2x, p2y] = easing;\n\n const cy = 3 * p1y;\n const by = 3 * (p2y - p1y) - cy;\n const ay = 1 - cy - by;\n\n function sampleCurveY(t: number) { return ((ay * t + by) * t + cy) * t; }\n\n return function (x: number) {\n return sampleCurveY(solveCubicBezierX(p1x, p2x, x));\n };\n}\n\ntype Point2 = [number, number];\n\nfunction lerp2(a: Point2, b: Point2, t: number): Point2 {\n return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t];\n}\n\n/**\n * Splits a cubic bezier curve at parameter t using De Casteljau's algorithm.\n * Returns the left and right sub-curves as 4-point tuples.\n */\nexport function subdivideCubicBezier(\n p0: Point2, p1: Point2, p2: Point2, p3: Point2, t: number\n): { left: [Point2, Point2, Point2, Point2], right: [Point2, Point2, Point2, Point2] } {\n const q0 = lerp2(p0, p1, t);\n const q1 = lerp2(p1, p2, t);\n const q2 = lerp2(p2, p3, t);\n const r0 = lerp2(q0, q1, t);\n const r1 = lerp2(q1, q2, t);\n const s = lerp2(r0, r1, t);\n return {\n left: [p0, q0, r0, s],\n right: [s, r1, q2, p3]\n };\n}\n\ntype Easing = [number, number, number, number];\n\n/**\n * Splits a CSS cubic-bezier easing [x1,y1,x2,y2] at a given x-axis fraction.\n * Each half is re-normalized to map [0,0]→[1,1].\n * Returns undefined for either half if the input is undefined (linear) or the split is degenerate.\n */\nexport function splitEasing(\n easing: Easing | undefined,\n xFraction: number\n): { left: Easing | undefined, right: Easing | undefined } {\n if (!easing) return { left: undefined, right: undefined };\n if (xFraction <= 0) return { left: undefined, right: easing };\n if (xFraction >= 1) return { left: easing, right: undefined };\n\n const [x1, y1, x2, y2] = easing;\n const t = solveCubicBezierX(x1, x2, xFraction);\n\n const p0: Point2 = [0, 0];\n const p1: Point2 = [x1, y1];\n const p2: Point2 = [x2, y2];\n const p3: Point2 = [1, 1];\n\n const { left, right } = subdivideCubicBezier(p0, p1, p2, p3, t);\n\n // Split point coordinates\n const sx = left[3][0];\n const sy = left[3][1];\n\n let leftEasing: Easing | undefined;\n if (sx > 1e-9 && Math.abs(sy) > 1e-9) {\n leftEasing = [\n left[1][0] / sx, left[1][1] / sy,\n left[2][0] / sx, left[2][1] / sy\n ];\n }\n\n let rightEasing: Easing | undefined;\n const rx = 1 - sx;\n const ry = 1 - sy;\n if (rx > 1e-9 && Math.abs(ry) > 1e-9) {\n rightEasing = [\n (right[1][0] - sx) / rx, (right[1][1] - sy) / ry,\n (right[2][0] - sx) / rx, (right[2][1] - sy) / ry\n ];\n }\n\n return { left: leftEasing, right: rightEasing };\n}\n\n/**\n * Reverses a cubic-bezier easing for backward playback.\n * [x1,y1,x2,y2] → [1-x2, 1-y2, 1-x1, 1-y1].\n */\nexport function reverseEasing(easing: Easing | undefined): Easing | undefined {\n if (!easing) return undefined;\n return [1 - easing[2], 1 - easing[3], 1 - easing[0], 1 - easing[1]];\n}\n\n/**\n * Converts a color from a [r, g, b, a] array (where values are 0-1) to an rgba() or rgb() CSS string.\n * @param color The color array.\n */\nexport function toRGBA(color: Array<number>): string {\n const r = Math.round(color[0] * 255);\n const g = Math.round(color[1] * 255);\n const b = Math.round(color[2] * 255);\n return color.length === 4 ?\n 'rgba(' + r + ',' + g + ',' + b + ',' + color[3] + ')' :\n 'rgb(' + r + ',' + g + ',' + b + ')';\n}\n\n/** Parse rgb/rgba string to normalized array */\nexport function parseRgba(s: string): number[] {\n const inner = s.match(/rgba?\\((.*)\\)/)?.[1];\n if (!inner) throw new Error('Invalid rgb/rgba format');\n const parts = inner.split(',').map(v => +v.trim());\n return [parts[0] / 255, parts[1] / 255, parts[2] / 255, ...(parts[3] !== undefined ? [parts[3]] : [])];\n}\n\n/** Parse hex string to normalized array (#RGB, #RGBA, #RRGGBB, #RRGGBBAA) */\nfunction parseHex(s: string): number[] {\n const hex = s.slice(1); // Remove '#'\n const isShort = hex.length <= 4; // #RGB or #RGBA vs #RRGGBB or #RRGGBBAA\n\n const r = isShort ? hex[0] + hex[0] : hex.slice(0, 2);\n const g = isShort ? hex[1] + hex[1] : hex.slice(2, 4);\n const b = isShort ? hex[2] + hex[2] : hex.slice(4, 6);\n const a = hex.length === 4 ? hex[3] + hex[3] : hex.length === 8 ? hex.slice(6, 8) : null;\n\n const result = [\n parseInt(r, 16) / 255,\n parseInt(g, 16) / 255,\n parseInt(b, 16) / 255\n ];\n\n if (a !== null) {\n result.push(parseInt(a, 16) / 255);\n }\n\n return result;\n}\n\n//// FIXME - support normalisation of config from different formats\n/** Parse color string (hex or rgb/rgba) to normalized [r, g, b] or [r, g, b, a] array (0-1 range) */\nexport function parseColor(s: any): number[] | undefined {\n if (!s) return undefined;\n if (Array.isArray(s)) return s;\n if (typeof s !== 'string') return undefined;\n if (s.startsWith('#')) {\n return parseHex(s);\n } else if (s.startsWith('rgb')) {\n return parseRgba(s);\n } else {\n // FIXME - come up with some solution how to report errors...\n console.warn('Unsupported color format: ' + s);\n }\n return undefined;\n}\n\nexport const COLOUR_ATTR_NAMES = new Set([\"color\", \"fill\", \"flood-color\", \"lighting-color\", \"stop-color\", \"stroke\"]);\nexport const TRANSFORM_FN_NAMES = new Set([\"translate\", \"rotate\", \"scale\", \"skew\"]);\nexport const PCT_BASED_ATTR_NAMES = new Set([\"offset-distance\", \"offsetDistance\"]);\n\n/**\n * Compose a `PxTransformParts` record into a single SVG/CSS transform string in\n * the canonical order:\n *\n * translate, translate(+origin), rotate, scale, translate(-origin)\n *\n * Each part is omitted when not present. `origin` becomes a `translate(+o)` /\n * `translate(-o)` pair surrounding the rotate/scale segment — the SVG-native\n * way to render a transform-origin pivot.\n *\n * @param parts the parts record (translate / rotate / scale / origin)\n * @param opts.withUnits when true (default), translates use `px` and rotate\n * uses `deg` — required for CSS / WebAnimations keyframes. When false, no\n * units are emitted — required for the SVG `transform` attribute.\n */\nexport function composeTransformParts(\n parts: PxTransformParts | null | undefined,\n opts?: { withUnits?: boolean }\n): string {\n if (!parts) return '';\n const withUnits = opts?.withUnits ?? true;\n const segs: Array<string> = [];\n const t = parts.translate;\n const o = parts.origin;\n const r = parts.rotate;\n const k = parts.skew;\n const s = parts.scale;\n const tu = withUnits ? 'px' : '';\n const ru = withUnits ? 'deg' : '';\n if (t) segs.push('translate(' + t[0] + tu + ',' + t[1] + tu + ')');\n if (o) segs.push('translate(' + o[0] + tu + ',' + o[1] + tu + ')');\n if (r !== undefined && r !== null) segs.push('rotate(' + r + ru + ')');\n // Canonical slot: between rotate and scale (Lottie-compatible; pivots at origin).\n if (k !== undefined && k !== null) segs.push('skewX(' + k + ru + ')');\n if (s) segs.push('scale(' + s[0] + ',' + s[1] + ')');\n if (o) segs.push('translate(' + (-o[0]) + tu + ',' + (-o[1]) + tu + ')');\n return segs.join('');\n}\nexport const STYLE_ATTR_NAMES = new Set([\"offset-distance\", \"offsetDistance\"]); // Props that need to go to style\nexport const DEFAULT_DURATION_MS = 1000;\n\n/**\n * Converts a kebab-case string to camelCase.\n * @param kebab The kebab-case string.\n */\nexport function kebabToCamelCaseWord(kebab: string): string {\n return kebab.includes('-') ? kebab.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase()) : kebab;\n}\n\n/**\n * Checks if a string is in camelCase.\n * @param word The string to check.\n */\nexport function isCamelCaseWord(word: string): boolean {\n return !word.includes('-') && /[a-z][A-Z]/.test(word);\n}\n\n// FIXME - docs, rename?\nconst SVG_CAMEL_CASE_ATTRS = new Set([\n // Transform/positioning\n 'viewBox',\n 'preserveAspectRatio',\n\n // Gradient\n 'gradientUnits',\n 'gradientTransform',\n 'spreadMethod',\n\n // Pattern\n 'patternUnits',\n 'patternContentUnits',\n 'patternTransform',\n\n // Clipping/masking\n 'clipPathUnits',\n 'maskUnits',\n 'maskContentUnits',\n\n // Marker (SVG spec keeps these camelCase, like viewBox)\n 'markerUnits',\n 'markerWidth',\n 'markerHeight',\n 'refX',\n 'refY',\n\n // Text\n 'textLength',\n 'lengthAdjust',\n 'startOffset',\n\n // Filter\n 'filterUnits',\n 'primitiveUnits',\n 'tableValues', // feFuncR/G/B/A transfer table (type=\"table\")\n 'stdDeviation',\n 'baseFrequency',\n 'numOctaves',\n 'surfaceScale',\n 'diffuseConstant',\n 'specularConstant',\n 'specularExponent',\n 'kernelMatrix',\n 'kernelUnitLength',\n 'edgeMode',\n 'preserveAlpha',\n 'targetX',\n 'targetY',\n\n // // Animation\n // 'attributeName',\n // 'attributeType',\n // 'calcMode',\n // 'keyTimes',\n // 'keySplines',\n // 'repeatCount',\n // 'repeatDur' \n]);\n\n/**\n * Converts a camelCase string to kebab-case.\n * @param camel The camelCase string.\n */\nexport function camelCaseToKebabWordIfNeeded(camel: string): string { // FIXME - docs, rename function?\n return SVG_CAMEL_CASE_ATTRS.has(camel) ?\n camel :\n camel.replace(/([a-z0-9])([A-Z])/g, '$1-$2').toLowerCase();\n}\n\n/**\n * Checks if a CSS property is set inline on an element's style.\n *\n * Typed structurally (not as the DOM `CSSStyleDeclaration`) so this package\n * stays platform-neutral; a real `element.style` satisfies the shape.\n *\n * @param style - element.style (CSSStyleDeclaration-shaped)\n * @param propName - property name (camelCase or kebab-case)\n */\nexport function hasStyleProp(\n style: { getPropertyValue(propName: string): string },\n propName: string\n): boolean {\n return style.getPropertyValue(propName) !== '';\n}\n\n/**\n * Clamps a number between a minimum and maximum value.\n * @param value The number to clamp.\n * @param min The minimum value.\n * @param max The maximum value.\n */\nexport function clamp(value: number, min: number, max: number): number {\n return Math.max(min, Math.min(value, max));\n}\n\n\n// ============================================================================\n// 2D CUBIC BÉZIER PRIMITIVES — motion-along-path support\n// ============================================================================\n//\n// Hand-written, dependency-free 2D Bézier maths used by the motion-along-path\n// playback paths (both WAAPI normalisation and frames-mode direct compute).\n// See `fix-motion-along-path--fix-plan.md` for the wider plan.\n//\n// Conventions:\n// - Points are `[x, y]` tuples (`Point2`) — matches the wire format.\n// - A cubic segment is `(P0, P1, P2, P3)` where `P0` and `P3` are the\n// endpoints and `P1`, `P2` are the control points in ABSOLUTE coordinates.\n// - The Lottie-style tangent storage convention is `kf.to` =\n// outgoing-from-kf-as-a-delta, `kf.ti` = incoming-at-the-next-kf-as-a-delta.\n// The wire format re-attaches them to the natural endpoints as\n// `tangentOut` on the FROM keyframe and `tangentIn` on the TO keyframe.\n// Caller is responsible for the position-to-control-point lift, i.e.\n// `P1 = fromKf.value + fromKf.tangentOut`, `P2 = toKf.value + toKf.tangentIn`.\n\n\n/**\n * Evaluate a 2D cubic Bézier at parameter `t ∈ [0, 1]` via Bernstein form:\n *\n * B(t) = (1-t)³ P0 + 3t(1-t)² P1 + 3t²(1-t) P2 + t³ P3\n *\n * `t` is the curve PARAMETER, not arc-length. For arc-length (CSS Motion Path\n * / `offset-distance`) semantics, use `bezier2D_tForDistance` first to convert\n * a distance to its parameter, then call this. Out-of-range `t` is clamped.\n */\nexport function bezier2D_pointAt(\n P0: Point2, P1: Point2, P2: Point2, P3: Point2,\n t: number\n): Point2 {\n if (t <= 0) return [P0[0], P0[1]];\n if (t >= 1) return [P3[0], P3[1]];\n const u = 1 - t;\n const u2 = u * u;\n const u3 = u2 * u;\n const t2 = t * t;\n const t3 = t2 * t;\n const w0 = u3;\n const w1 = 3 * t * u2;\n const w2 = 3 * t2 * u;\n const w3 = t3;\n return [\n w0 * P0[0] + w1 * P1[0] + w2 * P2[0] + w3 * P3[0],\n w0 * P0[1] + w1 * P1[1] + w2 * P2[1] + w3 * P3[1],\n ];\n}\n\n\n/**\n * Evaluate the derivative `B'(t)` of a 2D cubic Bézier at parameter `t`.\n *\n * B'(t) = 3(1-t)² (P1-P0) + 6t(1-t) (P2-P1) + 3t² (P3-P2)\n *\n * Returns the tangent VECTOR (not a unit vector). For auto-orient rotation,\n * caller computes `Math.atan2(d.y, d.x)`.\n *\n * Epsilon-nudge for degenerate endpoints: when a handle coincides with its\n * endpoint (e.g. `P1 === P0` and `t === 0`, common for the start/end of a\n * Lottie spatial-tangent path), the derivative collapses to zero. The\n * exact-endpoint value is then meaningless; we nudge `t` inward by `1e-4`\n * and retry.\n */\nconst BEZIER_T_NUDGE = 1e-4;\nexport function bezier2D_derivativeAt(\n P0: Point2, P1: Point2, P2: Point2, P3: Point2,\n t: number\n): Point2 {\n const result = _bezier2D_derivativeAtRaw(P0, P1, P2, P3, t);\n if (result[0] === 0 && result[1] === 0) {\n // Degenerate (handle = endpoint). Nudge inward and retry.\n const nudgedT = t < 0.5 ? t + BEZIER_T_NUDGE : t - BEZIER_T_NUDGE;\n return _bezier2D_derivativeAtRaw(P0, P1, P2, P3, nudgedT);\n }\n return result;\n}\n\nfunction _bezier2D_derivativeAtRaw(\n P0: Point2, P1: Point2, P2: Point2, P3: Point2,\n t: number\n): Point2 {\n const u = 1 - t;\n const a = 3 * u * u;\n const b = 6 * t * u;\n const c = 3 * t * t;\n return [\n a * (P1[0] - P0[0]) + b * (P2[0] - P1[0]) + c * (P3[0] - P2[0]),\n a * (P1[1] - P0[1]) + b * (P2[1] - P1[1]) + c * (P3[1] - P2[1]),\n ];\n}\n\n\n/**\n * Arc-length lookup table for a 2D cubic Bézier.\n *\n * Samples the curve at `steps + 1` evenly-spaced parameter values\n * (`t = 0, 1/steps, 2/steps, …, 1`), computes the cumulative Euclidean\n * distance between consecutive samples, and returns parallel\n * `Float64Array`s for parameter (`ts`) and arc length (`ds`). `ds[steps]`\n * is the total arc length of the curve.\n *\n * The LUT shape is `{ts, ds}` with parallel Float64Arrays rather than\n * `Array<{t, d}>` because:\n * - One contiguous allocation per array instead of `steps+1` objects.\n * - Binary search in `bezier2D_tForDistance` reads `Float64Array` directly.\n * - The structure is read-only after construction — no need for per-sample\n * field access.\n *\n * Approximation error is roughly `O((1/steps)²)` for smooth curves; the\n * default 100 samples gives <1% error vs analytic arc length on typical\n * motion paths.\n */\nexport interface ArcLengthLUT {\n readonly ts: Float64Array;\n readonly ds: Float64Array;\n}\n\nexport function bezier2D_arcLengthLUT(\n P0: Point2, P1: Point2, P2: Point2, P3: Point2,\n steps: number = 100\n): ArcLengthLUT {\n const n = steps + 1;\n const ts = new Float64Array(n);\n const ds = new Float64Array(n);\n\n let prev = bezier2D_pointAt(P0, P1, P2, P3, 0);\n ts[0] = 0;\n ds[0] = 0;\n\n let cum = 0;\n for (let i = 1; i < n; i++) {\n const t = i / steps;\n const cur = bezier2D_pointAt(P0, P1, P2, P3, t);\n const dx = cur[0] - prev[0];\n const dy = cur[1] - prev[1];\n cum += Math.sqrt(dx * dx + dy * dy);\n ts[i] = t;\n ds[i] = cum;\n prev = cur;\n }\n return { ts, ds };\n}\n\n\n/**\n * Inverse of `bezier2D_arcLengthLUT` lookup: given a distance along the\n * curve, return the curve parameter `t` reached at that distance via\n * binary search on `lut.ds` + linear interpolation between adjacent\n * samples.\n *\n * Distance is clamped to `[0, lut.ds[last]]`. The returned `t` is in\n * `[0, 1]`. Pair with `bezier2D_pointAt` to get the point at that\n * arc-length distance:\n *\n * const t = bezier2D_tForDistance(lut, distance);\n * const point = bezier2D_pointAt(P0, P1, P2, P3, t);\n */\nexport function bezier2D_tForDistance(lut: ArcLengthLUT, distance: number): number {\n const { ts, ds } = lut;\n const last = ds.length - 1;\n if (distance <= 0) return ts[0];\n if (distance >= ds[last]) return ts[last];\n\n // Binary search for the upper-bound index `hi` such that ds[hi-1] <= distance < ds[hi].\n let lo = 1;\n let hi = last;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n if (ds[mid] < distance) lo = mid + 1;\n else hi = mid;\n }\n // Linear interpolate between the bracketing samples.\n const dPrev = ds[hi - 1];\n const dCur = ds[hi];\n const span = dCur - dPrev;\n const frac = span > 0 ? (distance - dPrev) / span : 0;\n return ts[hi - 1] + frac * (ts[hi] - ts[hi - 1]);\n}\n\n\n/**\n * `bezier2D_tForDistance` convenience taking a fraction of the total arc\n * length instead of an absolute distance. `pct` is in `[0, 1]` (CSS Motion\n * Path `offset-distance` semantics — `offset-distance: 50%` ≡\n * `bezier2D_tForDistancePct(lut, 0.5)`). Out-of-range values clamp.\n */\nexport function bezier2D_tForDistancePct(lut: ArcLengthLUT, pct: number): number {\n const total = lut.ds[lut.ds.length - 1];\n return bezier2D_tForDistance(lut, pct * total);\n}\n\n\n/**\n * Inverse of {@link bezier2D_tForDistance}: given a curve parameter `t`,\n * returns the arc length from the start. Binary searches the LUT's `ts`\n * (uniformly spaced) and linearly interpolates `ds` between adjacent samples.\n */\nexport function bezier2D_arcAtT(lut: ArcLengthLUT, t: number): number {\n const { ts, ds } = lut;\n const last = ts.length - 1;\n if (t <= ts[0]) return ds[0];\n if (t >= ts[last]) return ds[last];\n let lo = 1, hi = last;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n if (ts[mid] < t) lo = mid + 1;\n else hi = mid;\n }\n const tPrev = ts[hi - 1];\n const span = ts[hi] - tPrev;\n const frac = span > 0 ? (t - tPrev) / span : 0;\n return ds[hi - 1] + frac * (ds[hi] - ds[hi - 1]);\n}\n\n\n/**\n * Inverse of {@link cubicBezier}: for a CSS easing `[x1,y1,x2,y2]` and a\n * target output `y`, returns the input `x` such that\n * `cubicBezier(easing)(x) ≈ y`. Works for monotonic easings (the CSS\n * default) by swapping the easing's x/y axes — the inverse easing has\n * controls `[y1, x1, y2, x2]`, which `cubicBezier` evaluates directly.\n *\n * `undefined` easing (linear) → identity function.\n */\nexport function invertEasing(easing: Easing | undefined): (y: number) => number {\n if (!easing) return (y) => y;\n const flipped: Easing = [easing[1], easing[0], easing[3], easing[2]];\n return cubicBezier(flipped);\n}","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport type { PxAnimatedSvgDocument } from './PxAnimatorTypes';\n\n\n/**\n * Generates a unique ID with a random suffix.\n * Format: _px_{random base36 string}\n */\nlet _idCounter = 0;\nexport function generateUniqueId(): string {\n const timestamp = Date.now().toString(36);\n const counter = (++_idCounter).toString(36);\n const random = Math.random().toString(36).substring(2, 6);\n return '_px_' + timestamp + counter + random;\n}\n\n/**\n * Deep clones a JSON-like value (objects, arrays, primitives).\n * Does not handle special types like Date, Map, Set, functions, etc.\n */\nexport function deepClone<T>(value: T): T {\n if (value === null || typeof value !== 'object') return value;\n if (Array.isArray(value)) return value.map(item => deepClone(item)) as T;\n\n const obj = value as Record<string, unknown>;\n\n const cloned: Record<string, unknown> = {};\n for (const key of Object.keys(obj)) {\n cloned[key] = deepClone(obj[key]);\n }\n return cloned as T;\n}\n\n/**\n * Regenerates all IDs in the document and updates references.\n *\n * This function:\n * 1. Deep clones the document to avoid mutating the original\n * 2. Traverses all nodes and regenerates IDs, keeping a mapping of old → new\n * 3. Updates all references to old IDs in attributes:\n * - Hash references: \"#old-id\" → \"#new-id\" (href, xlink:href)\n * - URL references: \"url(#old-id)\" → \"url(#new-id)\" (fill, clip-path, mask, marker, etc.)\n * - Style URL references: { offsetPath: \"url(#old-id)\" }\n *\n * @param doc - The animated SVG document to process\n * @returns A new document with regenerated IDs\n */\nexport function generateNewIds(doc: PxAnimatedSvgDocument): PxAnimatedSvgDocument {\n // Deep clone the document\n const cloned: PxAnimatedSvgDocument = deepClone(doc);\n\n // Map of old ID → new ID\n const idMap = new Map<string, string>();\n\n // Attributes that contain hash references (#id)\n const hashRefAttrs = new Set(['href', 'xlink:href']);\n\n // Attributes that contain url(#id) references\n const urlRefAttrs = new Set([\n 'fill', 'stroke', 'clip-path', 'clipPath', 'mask',\n 'marker', 'marker-start', 'marker-mid', 'marker-end',\n 'filter', 'flood-color', 'lighting-color'\n ]);\n\n // Attributes that contain direct ID references (no # or url())\n const directIdRefAttrs = new Set(['baseId', 'targetId', 'boundElementId']);\n\n // Phase 1: Collect all IDs and generate new ones\n function collectIds(node: any): void {\n if (!node || typeof node !== 'object') return;\n\n if (node.id && typeof node.id === 'string') {\n const oldId = node.id;\n const newId = generateUniqueId();\n idMap.set(oldId, newId);\n node.id = newId;\n } else if (node.animate) {\n // An animated node needs an id so the animation can bind to its rendered element.\n node.id = generateUniqueId();\n }\n\n // Process children\n if (Array.isArray(node.children)) {\n for (const child of node.children) {\n collectIds(child);\n }\n }\n }\n\n // Phase 2: Update all references to old IDs\n function updateRefs(node: any): void {\n if (!node || typeof node !== 'object') return;\n\n for (const [key, value] of Object.entries(node)) {\n if (key === 'children') {\n if (Array.isArray(value)) {\n for (const child of value) {\n updateRefs(child);\n }\n }\n continue;\n }\n\n if (typeof value === 'string') {\n // Check for hash references: href=\"#old-id\"\n if (hashRefAttrs.has(key) && value.startsWith('#')) {\n const oldId = value.slice(1);\n const newId = idMap.get(oldId);\n if (newId) {\n node[key] = '#' + newId;\n }\n }\n // Check for url() references: fill=\"url(#old-id)\"\n else if (urlRefAttrs.has(key)) {\n node[key] = replaceUrlRefs(value, idMap);\n }\n // Check for direct ID references: baseId=\"_px_xxx\"\n else if (directIdRefAttrs.has(key)) {\n const newId = idMap.get(value);\n if (newId) {\n node[key] = newId;\n }\n }\n // Check for url() in any string value (e.g., in style strings)\n else if (value.includes('url(#')) {\n node[key] = replaceUrlRefs(value, idMap);\n }\n }\n // Check style object for url() references\n else if (key === 'style' && typeof value === 'object' && value !== null) {\n for (const [styleProp, styleValue] of Object.entries(value)) {\n if (typeof styleValue === 'string') {\n (value as any)[styleProp] = replaceUrlRefs(styleValue, idMap);\n }\n }\n }\n // Recursively process nested objects (meta contains baseId/targetId refs;\n // in-place animated values like { keyframes: [{ value: \"url(#grad)\" }] }\n // also need ref rewriting on string values they contain).\n else if (typeof value === 'object' && value !== null) {\n updateRefs(value);\n }\n }\n }\n\n collectIds(cloned);\n updateRefs(cloned);\n\n // Update IDs in animator.animate map\n const docAnimate = cloned.animator?.animate;\n if (docAnimate && typeof docAnimate === 'object') {\n const updatedAnimate: Record<string, any> = {};\n for (const [id, anim] of Object.entries(docAnimate)) {\n const newId = idMap.get(id) ?? id;\n updatedAnimate[newId] = anim;\n }\n cloned.animator = { ...cloned.animator, animate: updatedAnimate };\n }\n\n return cloned;\n}\n\n/**\n * Replaces url(#old-id) references in a string with new IDs from the map.\n */\nfunction replaceUrlRefs(value: string, idMap: Map<string, string>): string {\n return value.replace(/url\\(#([^)]+)\\)/g, (match, oldId) => {\n const newId = idMap.get(oldId);\n return newId ? 'url(#' + newId + ')' : match;\n });\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { INTERNAL_ATTRS, type PxDefs } from './PxAnimatorTypes';\nimport { COLOUR_ATTR_NAMES, composeTransformParts, kebabToCamelCaseWord, toRGBA, TRANSFORM_FN_NAMES } from './PxAnimatorUtil';\n\n\n/**\n * Tags that MUST never be created — the only real XSS surfaces in SVG:\n * - `<script>` — direct JS execution.\n * - `<foreignObject>` — embeds arbitrary HTML (incl. `<script>`, `<iframe>`).\n *\n * Everything else (shape elements, gradients, patterns, markers, filters\n * including `feComponentTransfer` / `feFuncA` / `feFlood` / `feComposite` /\n * `feImage`, SMIL `<animate>` family, `<a>` hyperlinks, …) is allowed. URL\n * sanitisation in `sanitiseAttributeValue` blocks `javascript:` / external\n * refs on `href` / `src` / `mask` / `marker*`.\n */\nexport const DISALLOWED_SVG_TAGS_LOWER = new Set([\n 'script',\n 'foreignobject',\n]);\n\n\n/**\n * URL-valued attributes that must reference an internal `#id` / `url(#id)`\n * only — never an external URL, `javascript:`, etc. Values for these names\n * are sanitised in `sanitiseAttributeValue`; non-internal refs are dropped.\n *\n * Exception: image-ref attributes (`href` / `xlink:href` / `src`) ALSO\n * accept `data:image/…` URIs — base64 raster (`image/png`, `image/jpeg`,\n * `image/gif`, `image/webp`, `image/bmp`) and `image/svg+xml` (base64 or\n * URL-encoded). Browsers render any image referenced from `<image>` in\n * SVG \"secure static mode\": scripts inside the referenced SVG do NOT\n * execute, external resources don't load, and interaction is disabled —\n * the same sandbox `<img src=…svg>` uses. The `image/svg+xml` form is\n * therefore safe as an image source even though a top-level SVG document\n * with the same bytes could embed scripts.\n *\n * Stored lowercased so `sanitiseAttributeValue`'s `name.toLowerCase()`\n * lookup matches regardless of input casing (`href` / `xlink:href` /\n * `clipPath` / `clip-path` all hit the same entry).\n */\nconst URL_VALUE_ATTRS_LOWER = new Set([\n 'href', // <use>, <image>\n 'xlink:href', // legacy <use>\n 'src', // <image>\n 'filter', // url(#filterId)\n 'clippath', // clip-path=\"url(#…)\"\n 'mask', // url(#maskId)\n 'markerstart', // marker-start=\"url(#…)\"\n 'markermid', // marker-mid=\"url(#…)\"\n 'markerend', // marker-end=\"url(#…)\"\n]);\n\n/** Attrs where a `data:image/…` URI is a legitimate value (i.e. the SVG\n * element actually renders the bytes — `<image>`). Other URL-valued\n * attrs ignore data URIs at the browser layer, so widening the allow-\n * list there would be cargo-culted and noisy. */\nconst IMAGE_REF_ATTRS_LOWER = new Set(['href', 'xlink:href', 'src']);\n\n/** CSS-only properties that are NOT SVG presentation attributes — the browser\n * ignores them via `setAttribute`, so they must be applied through `element.style`.\n * Keyed camelCase to match the normalised prop names (`element.style.mixBlendMode`). */\nexport const CSS_ONLY_STYLE_PROPS = new Set<string>(['mixBlendMode', 'isolation']);\n\n/** Matches `data:image/{png|jpeg|jpg|gif|webp|bmp};base64,<payload>`.\n * Rejects any non-base64-encoded raster form. */\nconst DATA_RASTER_IMAGE_RE = /^data:image\\/(?:png|jpe?g|gif|webp|bmp);base64,/i;\n\n/** Matches `data:image/svg+xml[;params],<payload>` — base64\n * (`;base64,`), `;utf8,` / `;charset=UTF-8,`, and bare `,` (URL-encoded)\n * forms. Safe because the browser sandboxes any SVG referenced from an\n * image source (no scripts, no external loads, no interaction). */\nconst DATA_SVG_IMAGE_RE = /^data:image\\/svg\\+xml(?:;[^,]*)?,/i;\n\n/** Content-sniff fallback for `data:image/*;base64,…` URIs whose declared\n * subtype isn't a known raster type — e.g. `data:image/undefined;base64,<png>`,\n * which some Lottie exporters emit. The browser (and lottie-web) render these by\n * sniffing the leading bytes; we mirror that by matching the base64 payload\n * against common raster magic numbers (PNG `\\x89PNG`, JPEG `\\xFF\\xD8\\xFF`, GIF\n * `GIF8`, WebP/RIFF, BMP `BM`). Accepting on real image bytes keeps the\n * sanitiser's safety guarantee — raster bytes are inert — without trusting the\n * (here bogus) subtype, so the image renders instead of being dropped. */\nconst DATA_IMAGE_BASE64_PAYLOAD_RE = /^data:image\\/[^;,]*;base64,([A-Za-z0-9+/]{8})/i;\nconst BASE64_RASTER_MAGICS = ['iVBORw0K', '/9j/', 'R0lGOD', 'UklGR', 'Qk'];\nfunction isContentSniffedRasterImage(str: string): boolean {\n const m = DATA_IMAGE_BASE64_PAYLOAD_RE.exec(str);\n return !!m && BASE64_RASTER_MAGICS.some(magic => m[1].startsWith(magic));\n}\n\n\n/**\n * Attribute-name predicate: anything `name` matching this is dropped at\n * `setAttribute` time. The list is intentionally small — SVG's real\n * security surface is event handlers; every other concerning attribute\n * (URL refs, fill/stroke `url(…)`) is value-sanitised below, not name-\n * blocked. Adding entries here is a structural decision, not whack-a-mole.\n */\nfunction isDangerousAttrName(nameLower: string): boolean {\n // Event handlers — `onclick`, `onload`, `onerror`, `onmouseover`,\n // `onfocus`, `onfocusin`, SMIL `onbegin`/`onend`/`onrepeat`, … and any\n // future one. No legitimate SVG attribute starts with `on`, so this\n // prefix is a safe blanket block.\n if (nameLower.startsWith('on')) return true;\n return false;\n}\n\n\n/**\n * Returns the value to pass to `setAttribute`, or `undefined` to drop the\n * attribute entirely. Dropping leaves the DOM clean — the caller skips\n * `setAttribute` when this returns `undefined`.\n *\n * Three layers:\n * 1. Drop dangerous names (`on*` event handlers).\n * 2. Restrict `url(…)` in `fill` / `stroke` / `stop-color` to\n * internal `url(#id)` references.\n * 3. Restrict URL-valued attrs (`href`, `src`, `filter`, `clip-path`,\n * `mask`, `marker*`) to internal `#id` / `url(#id)`. Image-ref\n * attrs (`href` / `xlink:href` / `src`) additionally accept\n * `data:image/…` URIs — base64 raster (png/jpeg/gif/webp/bmp) and\n * `image/svg+xml` (sandboxed by the browser when used as an image\n * source). Blocks `javascript:` and external URLs.\n * Everything else passes through.\n */\nexport function sanitiseAttributeValue(name: string, value: any): any | undefined {\n const nameLower = name.toLowerCase();\n\n if (isDangerousAttrName(nameLower)) {\n console.warn('Attribute blocked (event handler / dangerous): ', nameLower);\n return undefined;\n }\n\n if (nameLower === 'fill' || nameLower === 'stroke' || nameLower === 'stopcolor') {\n const str = String(value);\n if (str.includes('url(') && !/^url\\(#[^)]+\\)$/.test(str)) {\n console.warn('Attribute \"' + nameLower + '\" blocked: url() must be internal url(#id), got:', value);\n return undefined;\n }\n return value;\n }\n\n if (URL_VALUE_ATTRS_LOWER.has(nameLower)) {\n const str = String(value);\n if (str.startsWith('#')) return value; // internal fragment ref\n if (/^url\\(#[^)]+\\)$/.test(str)) return value; // internal `url(#id)`\n // Image-ref attrs accept `data:image/…` URIs — raster bytes are\n // inert, and SVG referenced via an image source is sandboxed by\n // the browser (no script execution).\n if (IMAGE_REF_ATTRS_LOWER.has(nameLower) && (DATA_RASTER_IMAGE_RE.test(str) || DATA_SVG_IMAGE_RE.test(str) || isContentSniffedRasterImage(str))) return value;\n console.warn('Attribute \"' + nameLower + '\" blocked: must be #id, url(#id), or data:image/… URI, got:', value);\n return undefined;\n }\n\n return value;\n}\n\n/** FIXME - do we need this?\n * Resolves a style reference to an actual style object.\n */\nexport function resolveStyle(\n style: string | Record<string, string | number> | undefined,\n defs?: PxDefs\n): Record<string, string | number> | undefined {\n if (!style) return undefined;\n\n if (typeof style === 'string') {\n // Look up named style in defs\n return defs?.styles?.[style];\n }\n\n return style;\n}\n\n\nexport function getNormalizedProps(props: Record<string, any>) {\n const propsCopy: Record<string, any> = {};\n\n // Process regular attributes\n for (const rawKey of Object.keys(props)) {\n // Wire-format inputs may use kebab-case SVG attribute names (e.g.\n // `stroke-width`); normalise to camelCase up-front so the whitelist\n // (camelCase) and the `camelCaseToKebabWordIfNeeded` re-conversion\n // at write time both work. `kebabToCamelCaseWord` is a no-op for\n // keys with no `-`, leaving camelCase inputs untouched.\n const key = kebabToCamelCaseWord(rawKey);\n if (INTERNAL_ATTRS.has(key)) continue;\n if (key === 'style') continue;\n\n let value = props[rawKey];\n\n if (COLOUR_ATTR_NAMES.has(key) && Array.isArray(value)) {\n propsCopy[key] = toRGBA(value);\n } else if (\n key === 'transform' && value !== null && typeof value === 'object' &&\n !Array.isArray(value) && value.value && typeof value.value === 'object'\n ) {\n // Unified transform structured-static form: { value: PxTransformParts }.\n // Compose into an SVG transform string (no units — SVG transform attribute).\n propsCopy['transform'] = composeTransformParts(value.value, { withUnits: false });\n } else if (TRANSFORM_FN_NAMES.has(key)) {\n if (Array.isArray(value)) {\n if (key === 'translate') value = value.map((v: number) => v + 'px');\n value = value.join(',');\n }\n if (key === 'rotate') value = value + 'deg';\n propsCopy['transform'] = key + '(' + value + ')';\n } else if (value !== undefined && value !== null) {\n propsCopy[key] = String(value);\n }\n }\n\n return propsCopy;\n}\n\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n/**\n * Motion-along-path → plain transform keyframes.\n *\n * Editor wire format for a curved-translation (and/or `autoOrient`) animation\n * carries per-kf `tangentIn` / `tangentOut` plus an animation-level `autoOrient`\n * flag — a parametric representation that any consumer must evaluate per frame.\n *\n * This module DESUGARS that shape into a regular unified-transform animation:\n * extra `{ translate, rotate? }` keyframes are inserted at curve extrema and\n * adaptive bisection points so the linear chord between adjacent samples stays\n * within `flatnessTolerance` of the true Bezier, and the original easing is\n * SPLIT (via De Casteljau, `splitEasing` in `PxAnimatorUtil`) across the\n * sub-segments so the combined timing reproduces the input easing exactly.\n *\n * Output kfs have no tangents and no `autoOrient` — both engines (`frames` and\n * `webapi`) and any future renderer (e.g. react-native-svg) consume them via\n * their normal unified-transform code path.\n *\n * The plan + rationale (extremes-aware sampling, easing-split, full pipeline\n * order) is in `motion-along-path-waapi-rework.md`.\n */\n\n\nimport { bezier2D_arcAtT, bezier2D_arcLengthLUT, bezier2D_derivativeAt, bezier2D_pointAt, clamp, invertEasing, splitEasing } from './PxAnimatorUtil';\nimport type { ArcLengthLUT } from './PxAnimatorUtil';\nimport type { PxKeyframe, PxNode, PxPropertyAnimation, PxTransformParts } from './PxAnimatorTypes';\n\n\ntype Point2 = [number, number];\ntype Easing = [number, number, number, number];\n\n\nfunction getKfTranslate(kf: PxKeyframe): Point2 | undefined {\n const v = kf.value ?? kf.v;\n if (!v) return undefined;\n if (Array.isArray(v) && v.length >= 2 && typeof v[0] === 'number' && typeof v[1] === 'number') {\n // Composite per-part shape: `value: [x, y]` directly.\n return [v[0], v[1]];\n }\n const tr = (v as PxTransformParts).translate;\n if (Array.isArray(tr) && tr.length >= 2) return [tr[0], tr[1]];\n return undefined;\n}\n\nfunction getKfTime(kf: PxKeyframe): number {\n return (kf.time ?? kf.t ?? 0) as number;\n}\n\nfunction getKfEasing(kf: PxKeyframe): Easing | undefined {\n return (kf.easing ?? kf.e) as Easing | undefined;\n}\n\n\n/**\n * True when `anim` is a motion-along-path animation — at least one keyframe\n * carries spatial tangents (`tangentIn` / `tangentOut`) and/or the animation\n * has `autoOrient` set. Animation-level helper; works for either the body\n * `transform` slot or a composite per-part `translate` slot.\n */\nexport function propAnimIsMotionPath(anim: PxPropertyAnimation): boolean {\n const kfs: Array<PxKeyframe> | undefined = anim.keyframes ?? anim.kfs;\n if (!Array.isArray(kfs)) return false;\n if (anim.autoOrient) return true;\n for (const kf of kfs) {\n if ((kf.tangentIn ?? kf.ti) || (kf.tangentOut ?? kf.to)) return true;\n }\n return false;\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Segment cache — shared by `evaluateMotionPathSegment` (frames-mode kernel)\n// and the materialiser. Keyed by FROM-keyframe identity (WeakMap), so cache\n// entries vanish automatically when keyframes are replaced.\n// ─────────────────────────────────────────────────────────────────────────────\n\n\ninterface MotionPathSegmentCache {\n readonly P0: Point2;\n readonly P1: Point2;\n readonly P2: Point2;\n readonly P3: Point2;\n readonly lut: ArcLengthLUT;\n readonly totalArc: number;\n}\n\n// Keyed on the PAIR, not on `prevKf` alone: one keyframe can start different segments\n// across evaluations (a lookup that falls outside the keyframe range answers with a\n// first→last pair), and a `prevKf`-only key let that bogus segment's Bezier be served\n// for every later evaluation of the real `prevKf`→next segment.\nconst _segmentCache = new WeakMap<PxKeyframe, WeakMap<PxKeyframe, MotionPathSegmentCache>>();\n\nfunction getSegmentCache(\n prevKf: PxKeyframe,\n nextKf: PxKeyframe,\n prevPos: Point2,\n nextPos: Point2,\n): MotionPathSegmentCache {\n let byNext = _segmentCache.get(prevKf);\n const existing = byNext?.get(nextKf);\n if (existing) return existing;\n const to = prevKf.tangentOut ?? prevKf.to;\n const ti = nextKf.tangentIn ?? nextKf.ti;\n const P1: Point2 = [prevPos[0] + (to ? to[0] : 0), prevPos[1] + (to ? to[1] : 0)];\n const P2: Point2 = [nextPos[0] + (ti ? ti[0] : 0), nextPos[1] + (ti ? ti[1] : 0)];\n const lut = bezier2D_arcLengthLUT(prevPos, P1, P2, nextPos);\n const entry: MotionPathSegmentCache = {\n P0: prevPos, P1, P2, P3: nextPos,\n lut,\n totalArc: lut.ds[lut.ds.length - 1],\n };\n if (!byNext) { byNext = new WeakMap<PxKeyframe, MotionPathSegmentCache>(); _segmentCache.set(prevKf, byNext); }\n byNext.set(nextKf, entry);\n return entry;\n}\n\n/** Test helper. No-op in production (WeakMap; entries self-evict). Tests\n * should use fresh keyframe objects to force cache misses. */\nexport function _resetMotionPathSegmentCache(): void {\n // Intentionally empty — kept for backwards-compat with any callers.\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Frames-mode kernel — preserved for any caller that still wants parametric\n// evaluation. The binding pipeline no longer needs it (motion-path is\n// materialised at `getNormalisedBindings` time), but it's a useful primitive\n// on its own.\n// ─────────────────────────────────────────────────────────────────────────────\n\n\nexport interface MotionPathSample {\n /** Translate at the current time (motion-path arc-length-parametrised). */\n readonly translate: Point2;\n /** Auto-orient rotation in degrees (only when `autoOrient` is set). */\n readonly rotateDeg?: number;\n}\n\n/**\n * Evaluates the motion-path position (and optional auto-orient rotation) for a\n * single segment kf[i] → kf[i+1], given local progress already remapped to\n * `[0, 1]` and eased. Builds (or reuses cached) Bezier control points\n * `P1 = P0 + tangentOut`, `P2 = P3 + tangentIn`, maps `localProgress` to arc\n * length, then to curve parameter `t` via the arc-length LUT.\n */\nexport function evaluateMotionPathSegment(\n prevKf: PxKeyframe,\n nextKf: PxKeyframe,\n prevPos: Point2,\n nextPos: Point2,\n localProgress: number,\n autoOrient: boolean,\n): MotionPathSample {\n const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);\n const t = seg.totalArc === 0\n ? localProgress\n : tFromArcFraction(seg.lut, localProgress);\n const point = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);\n if (!autoOrient) return { translate: point };\n const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);\n const rotateDeg = Math.atan2(tan[1], tan[0]) * 180 / Math.PI;\n return { translate: point, rotateDeg };\n}\n\nfunction tFromArcFraction(lut: ArcLengthLUT, arcFrac: number): number {\n const total = lut.ds[lut.ds.length - 1];\n // Binary search on `ds` for `arcFrac * total` (mirrors bezier2D_tForDistance).\n const target = arcFrac * total;\n const { ts, ds } = lut;\n const last = ds.length - 1;\n if (target <= 0) return ts[0];\n if (target >= ds[last]) return ts[last];\n let lo = 1, hi = last;\n while (lo < hi) {\n const mid = (lo + hi) >>> 1;\n if (ds[mid] < target) lo = mid + 1;\n else hi = mid;\n }\n const dPrev = ds[hi - 1];\n const span = ds[hi] - dPrev;\n const frac = span > 0 ? (target - dPrev) / span : 0;\n return ts[hi - 1] + frac * (ts[hi] - ts[hi - 1]);\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Public API — materialise parametric motion-path into plain transform kfs\n// ─────────────────────────────────────────────────────────────────────────────\n\n\n/** Sampling configuration shared by `materialiseMotionPathInPropAnim` + `materialiseMotionPathsInTree`. */\nexport interface MotionPathMaterialisationOptions {\n /** Max chord-to-curve deviation per sub-interval, in user units (default 0.5). */\n flatnessTolerance?: number;\n /** Max rotation delta (in degrees) between adjacent samples when `autoOrient`\n * is set (default 5). */\n rotationTolerance?: number;\n /** Hard cap on samples per original segment; prevents runaway recursion on\n * pathological inputs (default 32). */\n maxSamplesPerSegment?: number;\n}\n\nconst DEFAULT_FLATNESS_TOL = 0.5;\nconst DEFAULT_ROTATION_TOL = 5;\nconst DEFAULT_MAX_SAMPLES = 32;\n\n\n/**\n * Converts ONE animated property to sampled transform kfs.\n *\n * Returns a NEW `PxPropertyAnimation` whose `kfs` are flat\n * `{ translate, rotate? }` records placed at curve extrema and adaptive\n * bisection points. Positions are arc-length-parametrised; easing is split via\n * De Casteljau so per-sub-segment easings reproduce the input easing exactly.\n * Original `loop` is carried across; `autoOrient` and per-kf `tangentIn` /\n * `tangentOut` are consumed.\n *\n * Returns the input unchanged (by reference) when it's not a motion-path\n * animation — callers can blindly run it through every propAnim.\n */\nexport function materialiseMotionPathInPropAnim(\n anim: PxPropertyAnimation,\n opts?: MotionPathMaterialisationOptions,\n): PxPropertyAnimation {\n if (!propAnimIsMotionPath(anim)) return anim;\n const kfs = (anim.keyframes ?? anim.kfs) as Array<PxKeyframe> | undefined;\n if (!Array.isArray(kfs) || kfs.length < 2) return anim;\n\n const autoOrient = !!anim.autoOrient;\n const flatnessTol = opts?.flatnessTolerance ?? DEFAULT_FLATNESS_TOL;\n const rotationTol = opts?.rotationTolerance ?? DEFAULT_ROTATION_TOL;\n const maxSamples = opts?.maxSamplesPerSegment ?? DEFAULT_MAX_SAMPLES;\n\n const out: Array<PxKeyframe> = [];\n\n // First output kf — translate from input; rotate from segment-0 derivative\n // at t=0 if autoOrient. All other transform parts (`origin`, `scale`, an\n // explicit `rotate` when `autoOrient` is false, …) come from kfs[0].value.\n const firstPos = getKfTranslate(kfs[0]);\n if (!firstPos) return anim;\n const firstRotate = autoOrient ? derivAngleForFirstKf(kfs[0], kfs[1]) : undefined;\n out.push(makeOutKf(\n getKfTime(kfs[0]),\n buildOutKfValue(getKfValueParts(kfs[0]), getKfValueParts(kfs[0]), 0, firstPos, firstRotate, autoOrient),\n ));\n\n for (let i = 0; i < kfs.length - 1; i++) {\n const prevKf = kfs[i];\n const nextKf = kfs[i + 1];\n const prevPos = getKfTranslate(prevKf);\n const nextPos = getKfTranslate(nextKf);\n if (!prevPos || !nextPos) {\n // Skip undefined translate kfs — just push next as-is.\n out.push(makeOutKf(\n getKfTime(nextKf),\n buildOutKfValue(getKfValueParts(nextKf), getKfValueParts(nextKf), 1, nextPos ?? [0, 0], undefined, autoOrient),\n ));\n continue;\n }\n\n // Sharp-corner step: between adjacent segments, the prev-segment's\n // exit tangent angle (already on out[last]) can differ from this\n // segment's entry tangent angle (deriv at t=0 of the segment about to\n // start) by a lot — e.g. a rectangular path has 90° steps at each\n // corner. Linear interp from prev-exit to the FAR-END kf of this\n // segment would slide rotation through the whole segment instead of\n // stepping at the boundary. Fix: insert a duplicate kf at the\n // boundary time carrying this segment's entry angle. With `e=undef`\n // on the prior kf, the engines render an instant step boundary then\n // constant rotation through the segment.\n if (autoOrient && i > 0) {\n insertSharpCornerStepKfIfNeeded(out, prevKf, nextKf, prevPos, nextPos, rotationTol);\n }\n\n materialiseSegment(out, prevKf, nextKf, prevPos, nextPos, autoOrient, flatnessTol, rotationTol, maxSamples);\n }\n\n // The very last out-kf inherits the original last kf's `easing` (which\n // applies to the NEXT segment after this animation, or nothing — but the\n // wire format preserves it regardless).\n const lastInE = getKfEasing(kfs[kfs.length - 1]);\n if (lastInE) out[out.length - 1].e = lastInE;\n\n // Unwrap autoOrient rotations so linear interp between samples doesn't\n // take the long way around the circle. atan2 returns in (-180°, 180°];\n // a tangent rotating slowly across the +X axis (e.g. -179° → +179°)\n // would otherwise be lerp'd as a ~358° spin instead of a ~2° step.\n if (autoOrient) unwrapAutoOrientRotations(out);\n\n const result: PxPropertyAnimation = { kfs: out } as PxPropertyAnimation;\n if (anim.loop !== undefined) (result as { loop?: unknown }).loop = anim.loop;\n return result;\n}\n\n\n/** Walks `kfs` in order; for each kf with a `rotate` value, shifts it by ±360°\n * multiples so the delta from the previous kf's rotate stays within ±180°.\n * Linear interpolation between consecutive samples then always takes the\n * shorter arc. The accumulated shift means a continuously-rotating element\n * may end up with rotate values well outside [-180°, 180°], which is fine —\n * CSS / SVG rotation accepts any range. Exported — the glyph along-path baker\n * (`buildAnimatedAlongPath`) needs the identical seam fix for its sampled\n * per-glyph tangent rotations. */\nexport function unwrapAutoOrientRotations(kfs: Array<PxKeyframe>): void {\n let prev: number | undefined;\n for (const kf of kfs) {\n const v = (kf.v ?? kf.value) as { rotate?: number } | undefined;\n if (!v || typeof v.rotate !== 'number') continue;\n if (prev === undefined) { prev = v.rotate; continue; }\n let r = v.rotate;\n while (r - prev > 180) r -= 360;\n while (r - prev < -180) r += 360;\n v.rotate = r;\n prev = r;\n }\n}\n\n\nfunction makeOutKf(time: number, value: PxTransformParts): PxKeyframe {\n return { t: time, v: value } as PxKeyframe;\n}\n\n/** Reads the kf's value-as-parts (object form). Returns `undefined` if the kf\n * has no value or it's an array form (single-part composite). */\nfunction getKfValueParts(kf: PxKeyframe): PxTransformParts | undefined {\n const v = kf.value ?? kf.v;\n if (!v || typeof v !== 'object' || Array.isArray(v)) return undefined;\n return v as PxTransformParts;\n}\n\n/** Linearly interpolates one transform-part value (number / Vec2). Returns the\n * non-undefined input when only one side is present, falls back to `prev`\n * for unsupported types. */\nfunction interpolatePart(prev: unknown, next: unknown, p: number): unknown {\n if (prev === undefined) return next;\n if (next === undefined) return prev;\n if (typeof prev === 'number' && typeof next === 'number') {\n return prev + (next - prev) * p;\n }\n if (Array.isArray(prev) && Array.isArray(next) && prev.length === next.length) {\n const out: Array<number> = new Array(prev.length);\n for (let i = 0; i < prev.length; i++) {\n const a = typeof prev[i] === 'number' ? prev[i] : 0;\n const b = typeof next[i] === 'number' ? next[i] : 0;\n out[i] = a + (b - a) * p;\n }\n return out;\n }\n return p < 0.5 ? prev : next;\n}\n\n/** Builds the value-record for one sampled output kf. `translate` overrides\n * whatever the per-part interpolation would have produced (motion path is the\n * source of truth for position); `rotateDegFromAutoOrient`, when defined, is\n * ADDED on top of the (interpolated) explicit animated `rotate` — auto-orient\n * and a user-set rotation compose, matching After Effects / Lottie semantics.\n * All OTHER parts present on `prevV` / `nextV` (origin, scale, etc.) are\n * interpolated at the eased arc-progress `p` — mirroring the frames-mode\n * `calcPropertyValue` loop. */\nfunction buildOutKfValue(\n prevV: PxTransformParts | undefined,\n nextV: PxTransformParts | undefined,\n p: number,\n translate: Point2,\n rotateDegFromAutoOrient: number | undefined,\n autoOrient: boolean,\n): PxTransformParts {\n const value: { [k: string]: unknown } = { translate };\n const keys = new Set<string>();\n if (prevV) for (const k of Object.keys(prevV)) keys.add(k);\n if (nextV) for (const k of Object.keys(nextV)) keys.add(k);\n for (const k of keys) {\n if (k === 'translate') continue; // overridden by motion path\n if (k === 'rotate' && autoOrient) continue; // composed below with autoOrient\n const pv = (prevV as Record<string, unknown> | undefined)?.[k];\n const nv = (nextV as Record<string, unknown> | undefined)?.[k];\n if (pv === undefined && nv === undefined) continue;\n value[k] = interpolatePart(pv, nv, p);\n }\n if (rotateDegFromAutoOrient !== undefined) {\n // Sum the auto-orient tangent angle with the element's own animated\n // rotation (interpolated at `p`, 0 when absent) rather than discarding it.\n value.rotate = rotateDegFromAutoOrient + explicitRotateAt(prevV, nextV, p);\n }\n return value as PxTransformParts;\n}\n\n/** Interpolated explicit `rotate` from a transform-parts pair at arc-progress\n * `p`; 0 when neither side carries a numeric rotate. */\nfunction explicitRotateAt(\n prevV: PxTransformParts | undefined,\n nextV: PxTransformParts | undefined,\n p: number,\n): number {\n const pv = typeof prevV?.rotate === 'number' ? prevV.rotate : undefined;\n const nv = typeof nextV?.rotate === 'number' ? nextV.rotate : undefined;\n if (pv === undefined && nv === undefined) return 0;\n const r = interpolatePart(pv, nv, p);\n return typeof r === 'number' ? r : 0;\n}\n\n\n/** Derivative angle at t=0 of segment kf[0] → kf[1]. Used to seed the first\n * output kf's rotation; without this the very first frame would render with\n * no rotation while every subsequent sample has one. */\nfunction derivAngleForFirstKf(kf0: PxKeyframe, kf1: PxKeyframe): number {\n const p0 = getKfTranslate(kf0);\n const p1 = getKfTranslate(kf1);\n if (!p0 || !p1) return 0;\n const seg = getSegmentCache(kf0, kf1, p0, p1);\n const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, 0);\n return Math.atan2(tan[1], tan[0]) * 180 / Math.PI;\n}\n\n\n/** Shortest signed difference of `a − b` wrapped into (-180°, 180°]. */\nfunction wrappedAngleDelta(a: number, b: number): number {\n let d = a - b;\n while (d > 180) d -= 360;\n while (d < -180) d += 360;\n return d;\n}\n\n\n/**\n * Appends a \"step\" kf to `out` at the boundary time iff the next segment's\n * entry tangent direction differs from the last emitted kf's rotation by more\n * than `rotationTol`. The new kf carries the SAME translate / origin / scale\n * as the boundary kf already in `out` (continuous in space), but a different\n * `rotate` — making engines render an instant rotation snap at the boundary\n * rather than linearly sliding rotation across the whole next segment.\n *\n * Called between `materialiseSegment` calls. The boundary kf already in `out`\n * keeps its outgoing easing as undefined (no easing between the two duplicates\n * — the step is instant); the next `materialiseSegment` will then attach its\n * sequential-split easing to the newly-inserted duplicate, so the per-sample\n * easing on segment `i+1` works exactly as before.\n */\nfunction insertSharpCornerStepKfIfNeeded(\n out: Array<PxKeyframe>,\n prevKf: PxKeyframe, nextKf: PxKeyframe,\n prevPos: Point2, nextPos: Point2,\n rotationTol: number,\n): void {\n const lastKf = out[out.length - 1];\n const lastV = (lastKf.v ?? lastKf.value) as { rotate?: number } | undefined;\n const prevExit = lastV?.rotate;\n if (typeof prevExit !== 'number') return;\n\n // `prevExit` is the SUMMED rotation (tangent + explicit). Compare pure\n // tangent-to-tangent by subtracting the boundary kf's explicit rotate,\n // which is shared by both adjoining segments at this shared keyframe.\n const boundaryV = getKfValueParts(prevKf);\n const prevExitTangent = prevExit - explicitRotateAt(boundaryV, boundaryV, 0);\n\n const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);\n const tanAtStart = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, 0);\n const nextEntry = Math.atan2(tanAtStart[1], tanAtStart[0]) * 180 / Math.PI;\n const delta = wrappedAngleDelta(nextEntry, prevExitTangent);\n if (Math.abs(delta) <= rotationTol) return; // continuous within tolerance\n\n // Step kf carrying the new entry angle, a hair AFTER the boundary — the boundary\n // time itself must render the PREVIOUS segment's exit pose. A duplicate at the exact\n // boundary time made CSS/WAAPI resolve the LATER keyframe there, so scrubbing to\n // exactly the corner showed the next segment's angle while the editor (and the\n // parametric frames engine, whose segment lookup treats a boundary as the END of the\n // segment before it) showed the previous one. The offset is far below a frame, so\n // playback still reads as an instant step at the corner.\n const prevTime = getKfTime(prevKf);\n const stepTime = Math.min(prevTime + CORNER_STEP_AFTER_BOUNDARY_MS, (prevTime + getKfTime(nextKf)) / 2);\n const dupValue = buildOutKfValue(\n getKfValueParts(prevKf), getKfValueParts(prevKf), 0,\n prevPos, nextEntry, true,\n );\n out.push(makeOutKf(stepTime, dupValue));\n}\n\n/** How far past a sharp corner the entry-angle step kf sits (ms). Small enough to be\n * invisible in playback (a frame is ~16 ms) — and strictly under the 0.1 ms step-width\n * budget the corner-step CSS spec asserts — while still a distinct WAAPI offset. */\nconst CORNER_STEP_AFTER_BOUNDARY_MS = 0.05;\n\n\n/** Materialises a single segment into `out`. Appends one kf per sample (interior\n * critical/adaptive points + the next-kf endpoint), with positions, optional\n * rotations, and split easings. */\nfunction materialiseSegment(\n out: Array<PxKeyframe>,\n prevKf: PxKeyframe, nextKf: PxKeyframe,\n prevPos: Point2, nextPos: Point2,\n autoOrient: boolean,\n flatnessTol: number, rotationTol: number, maxSamples: number,\n): void {\n const seg = getSegmentCache(prevKf, nextKf, prevPos, nextPos);\n const prevTime = getKfTime(prevKf);\n const nextTime = getKfTime(nextKf);\n const prevEasing = getKfEasing(prevKf);\n const invertFn = invertEasing(prevEasing);\n const prevV = getKfValueParts(prevKf);\n const nextV = getKfValueParts(nextKf);\n\n // 1. Critical t-values: axis extrema + endpoints.\n const interiorTs = computeSampleTs(seg, autoOrient, flatnessTol, rotationTol, maxSamples);\n // `interiorTs` is the list of t in (0, 1] in ascending order, ending with t=1.\n\n // 2. For each sample t, compute position, rotation, the eased arc-fraction\n // `p` (= the value frames-mode would use for non-translate part interp),\n // and the linear-time fraction `u` (via invertEasing of `p`).\n interface Sample { u: number; p: number; pos: Point2; rotateDeg?: number; }\n const samples: Array<Sample> = [];\n for (const t of interiorTs) {\n const arc = bezier2D_arcAtT(seg.lut, t);\n const p = clamp(seg.totalArc > 0 ? arc / seg.totalArc : t, 0, 1);\n const u = clamp(invertFn(p), 0, 1);\n const pos = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);\n const sample: Sample = { u, p, pos };\n if (autoOrient) {\n const tan = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);\n sample.rotateDeg = Math.atan2(tan[1], tan[0]) * 180 / Math.PI;\n }\n samples.push(sample);\n }\n\n // 3. Sequential easing split. The easing for sub-segment k (out[L+k-1] → out[L+k])\n // is the `left` half of splitting the still-unconsumed easing at\n // `(u_k - u_{k-1}) / (1 - u_{k-1})`.\n let remaining = prevEasing;\n let prevU = 0;\n const startIdx = out.length - 1; // out[startIdx] is the prev kf — it owns the FIRST sub-easing.\n for (let i = 0; i < samples.length; i++) {\n const s = samples[i];\n const xFrac = prevU < 1 ? clamp((s.u - prevU) / (1 - prevU), 0, 1) : 1;\n const { left, right } = splitEasing(remaining, xFrac);\n\n // Assign `left` as the outgoing easing of the kf at the end of `out`\n // (which is the kf that PRECEDES this sub-kf — the prev kf for i=0,\n // or the previously-emitted sub-kf for i>0).\n const ownerIdx = i === 0 ? startIdx : out.length - 1;\n if (left) out[ownerIdx].e = left;\n else delete out[ownerIdx].e;\n\n const tGlobal = prevTime + s.u * (nextTime - prevTime);\n const value = buildOutKfValue(prevV, nextV, s.p, s.pos, s.rotateDeg, autoOrient);\n out.push(makeOutKf(tGlobal, value));\n\n remaining = right;\n prevU = s.u;\n }\n}\n\n\n/** Returns t-values in (0, 1], sorted ascending, ending with t=1. The list\n * always includes the input segment's axis extrema interior to (0, 1), plus\n * adaptive bisection samples wherever the chord deviates from the curve by\n * more than `flatnessTol` (or the rotation delta exceeds `rotationTol` for\n * autoOrient). Capped at `maxSamples`. */\nfunction computeSampleTs(\n seg: MotionPathSegmentCache, autoOrient: boolean,\n flatnessTol: number, rotationTol: number, maxSamples: number,\n): Array<number> {\n // Axis extrema (interior to (0, 1)).\n const extremes: Array<number> = [];\n addAxisExtremes(seg.P0[0], seg.P1[0], seg.P2[0], seg.P3[0], extremes);\n addAxisExtremes(seg.P0[1], seg.P1[1], seg.P2[1], seg.P3[1], extremes);\n extremes.sort((a, b) => a - b);\n\n const critical: Array<number> = [0];\n for (const t of extremes) {\n if (t > critical[critical.length - 1] + 1e-6 && t < 1 - 1e-6) {\n critical.push(t);\n }\n }\n critical.push(1);\n\n const out: Array<number> = [];\n const budget = { remaining: maxSamples - critical.length }; // already-committed critical points count against the budget\n for (let i = 0; i < critical.length - 1; i++) {\n bisect(critical[i], critical[i + 1], out, seg, autoOrient, flatnessTol, rotationTol, budget);\n }\n return out;\n}\n\n\n/** Solves `P'(t).axis = 0` for one axis (a quadratic in t). Pushes any real\n * roots in `(0, 1)` into `out`. Coefficients via standard cubic Bezier\n * derivative: with `a = p1 − p0, b = p2 − p1, c = p3 − p2`, the equation is\n * `(a − 2b + c)·t² + 2(b − a)·t + a = 0`. */\nfunction addAxisExtremes(p0: number, p1: number, p2: number, p3: number, out: Array<number>): void {\n const a = p1 - p0;\n const b = p2 - p1;\n const c = p3 - p2;\n const A = a - 2 * b + c;\n const B = 2 * (b - a);\n const C = a;\n if (Math.abs(A) < 1e-10) {\n if (Math.abs(B) > 1e-10) {\n const t = -C / B;\n if (t > 1e-6 && t < 1 - 1e-6) out.push(t);\n }\n return;\n }\n const disc = B * B - 4 * A * C;\n if (disc < 0) return;\n const sq = Math.sqrt(disc);\n const t1 = (-B - sq) / (2 * A);\n const t2 = (-B + sq) / (2 * A);\n if (t1 > 1e-6 && t1 < 1 - 1e-6) out.push(t1);\n if (t2 > 1e-6 && t2 < 1 - 1e-6) out.push(t2);\n}\n\n\n/** Adaptive bisection between `tA` and `tB`. Always appends `tB` exactly once\n * (either directly when the chord is flat enough, or via recursion).\n *\n * Flatness is tested at THREE interior points (t = 0.25, 0.5, 0.75 of the\n * sub-interval), not just the midpoint. Symmetric Bezier segments often have\n * the curve crossing the chord exactly at t=0.5 — a single-midpoint check\n * would mistake that for flatness and skip subdivision, leaving visible\n * chord deviation between samples. */\nfunction bisect(\n tA: number, tB: number,\n out: Array<number>,\n seg: MotionPathSegmentCache,\n autoOrient: boolean,\n flatnessTol: number, rotationTol: number,\n budget: { remaining: number },\n): void {\n const tMid = (tA + tB) / 2;\n const pA = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA);\n const pB = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tB);\n const span = tB - tA;\n const p25 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA + span * 0.25);\n const p50 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tMid);\n const p75 = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, tA + span * 0.75);\n\n const dev = Math.max(\n perpDist(p25, pA, pB),\n perpDist(p50, pA, pB),\n perpDist(p75, pA, pB),\n );\n let rotOk = true;\n if (autoOrient) {\n const tanA = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, tA);\n const tanB = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, tB);\n const angA = Math.atan2(tanA[1], tanA[0]) * 180 / Math.PI;\n const angB = Math.atan2(tanB[1], tanB[0]) * 180 / Math.PI;\n let delta = Math.abs(angA - angB);\n if (delta > 180) delta = 360 - delta;\n if (delta > rotationTol) rotOk = false;\n }\n\n if ((dev <= flatnessTol && rotOk) || budget.remaining <= 0 || span < 1e-6) {\n out.push(tB);\n return;\n }\n\n budget.remaining -= 1;\n bisect(tA, tMid, out, seg, autoOrient, flatnessTol, rotationTol, budget);\n bisect(tMid, tB, out, seg, autoOrient, flatnessTol, rotationTol, budget);\n}\n\n\nfunction perpDist(q: Point2, pA: Point2, pB: Point2): number {\n const dx = pB[0] - pA[0];\n const dy = pB[1] - pA[1];\n const len2 = dx * dx + dy * dy;\n if (len2 < 1e-20) {\n const qdx = q[0] - pA[0];\n const qdy = q[1] - pA[1];\n return Math.sqrt(qdx * qdx + qdy * qdy);\n }\n const cross = (q[0] - pA[0]) * dy - (q[1] - pA[1]) * dx;\n return Math.abs(cross) / Math.sqrt(len2);\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Tree walker — applies `materialiseMotionPathInPropAnim` to every `node.animate.transform`\n// whose propAnim is a motion-path. Immutable: returns the input by reference\n// when no changes were needed; otherwise clones along the path to each\n// converted node and shares all other sub-trees.\n// ─────────────────────────────────────────────────────────────────────────────\n\n\nexport function materialiseMotionPathsInTree(\n root: PxNode,\n opts?: MotionPathMaterialisationOptions,\n): PxNode {\n const out = walkAndMaterialise(root, opts);\n return out ?? root;\n}\n\nfunction walkAndMaterialise(node: PxNode, opts?: MotionPathMaterialisationOptions): PxNode | null {\n let newChildren: Array<PxNode> | undefined;\n if (node.children) {\n for (let i = 0; i < node.children.length; i++) {\n const ch = node.children[i];\n const ret = walkAndMaterialise(ch, opts);\n if (ret !== null) {\n if (!newChildren) newChildren = node.children.slice();\n newChildren[i] = ret;\n }\n }\n }\n\n let newAnimate: Record<string, PxPropertyAnimation> | undefined;\n const animBucket = node.animate;\n if (animBucket && typeof animBucket === 'object' && !Array.isArray(animBucket)) {\n const animDef = animBucket as Record<string, PxPropertyAnimation>;\n const transformAnim = animDef.transform;\n if (transformAnim && typeof transformAnim === 'object' && propAnimIsMotionPath(transformAnim)) {\n const materialised = materialiseMotionPathInPropAnim(transformAnim, opts);\n if (materialised !== transformAnim) {\n newAnimate = { ...animDef, transform: materialised };\n }\n }\n }\n\n if (!newChildren && !newAnimate) return null;\n const cloned: PxNode = { ...node };\n if (newChildren) cloned.children = newChildren;\n if (newAnimate) cloned.animate = newAnimate as PxNode['animate'];\n return cloned;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport {\n getAnimatorConfig,\n getBindings,\n getDefs,\n PxAnimatorEngine,\n type PxAnimatedSvgDocument,\n type PxAnimationDefinition,\n type PxBezierPath,\n type PxBinding,\n type PxDefs,\n type PxElementAnimation,\n type PxKeyframe,\n type PxLoop,\n type PxNode,\n type PxPropertyAnimation,\n type PxTransformParts\n} from './PxAnimatorTypes';\nimport { bezierToSvgPath, camelCaseToKebabWordIfNeeded, clamp, COLOUR_ATTR_NAMES, composeTransformParts, cubicBezier, interpolateBeziers, interpolateColor, interpolateNum, interpolateVec, isCamelCaseWord, parseColor, PCT_BASED_ATTR_NAMES, remap, reverseEasing, splitEasing, toRGBA, TRANSFORM_FN_NAMES } from './PxAnimatorUtil';\nimport { evaluateMotionPathSegment, materialiseMotionPathInPropAnim, propAnimIsMotionPath } from './PxMotionPath';\n\n\n// ============================================================================\n// PATH PARSING: Convert \"path(...)\" strings to PxBezierPath format\n// ============================================================================\n\ninterface PathCommand {\n type: string;\n values: Array<number>;\n}\n\n/**\n * Parses an SVG path string into command tokens.\n * Supports M, L, C, Z commands (case-insensitive).\n */\nfunction parsePathCommands(d: string): Array<PathCommand> {\n const tokens = d.split(/([MLCZmlcz]|[\\s,]+)/).map(t => t.trim()).filter(t => t && t !== ',');\n\n const commands: Array<PathCommand> = [];\n let currentCommand: PathCommand | null = null;\n\n for (const token of tokens) {\n if (/[MLCZmlcz]/.test(token)) {\n currentCommand = { type: token, values: [] };\n commands.push(currentCommand);\n } else if (currentCommand) {\n const value = +token;\n currentCommand.values.push(Number.isNaN(value) ? 0 : value);\n }\n }\n\n return commands;\n}\n\n/**\n * Parses an internal SVG path string into PxBezierPath array.\n * Handles M (moveto), L (lineto), C (curveto), Z (close) commands.\n */\nexport function parseSvgPathToBezier(d: string): Array<PxBezierPath> {\n const res: Array<PxBezierPath> = [];\n let currentPath: PxBezierPath | undefined;\n\n const commands = parsePathCommands(d);\n\n for (const command of commands) {\n const type = command.type;\n const values = command.values;\n\n if (type === 'M' || type === 'm') {\n const x = values[0] || 0;\n const y = values[1] || 0;\n currentPath = {\n v: [[x, y]],\n i: [[x, y]],\n o: [[x, y]],\n c: false\n };\n res.push(currentPath);\n continue;\n }\n\n // Ensure we have a current path\n if (!currentPath) {\n currentPath = {\n v: [[0, 0]],\n i: [[0, 0]],\n o: [[0, 0]],\n c: false\n };\n res.push(currentPath);\n }\n\n if (type === 'L') {\n const x = values[0] || 0;\n const y = values[1] || 0;\n currentPath.v.push([x, y]);\n currentPath.i!.push([x, y]);\n currentPath.o!.push([x, y]);\n\n } else if (type === 'C') {\n const outX = values[0] || 0;\n const outY = values[1] || 0;\n const inX2 = values[2] || 0;\n const inY2 = values[3] || 0;\n const x2 = values[4] || 0;\n const y2 = values[5] || 0;\n\n // Update out-point of previous vertex\n currentPath.o![currentPath.o!.length - 1] = [outX, outY];\n\n // Add new vertex with its in-point\n currentPath.v.push([x2, y2]);\n currentPath.i!.push([inX2, inY2]);\n currentPath.o!.push([x2, y2]);\n\n } else if (type === 'Z' || type === 'z') {\n currentPath.c = true;\n\n } else {\n console.warn('Unsupported path command \"' + type + '\"');\n }\n }\n\n return res;\n}\n\n/**\n * Extracts SVG path data from a string.\n * Handles both \"path(M...)\" wrapper format and raw \"M...\" format.\n * @returns The path data string, or undefined if not a valid path string\n */\nfunction extractPathData(str: string): string | undefined {\n if (str.startsWith('path(') && str.endsWith(')')) {\n return str.slice(5, -1); // Remove \"path(\" and \")\"\n }\n // Raw path string starting with a path command (M, m, or other commands)\n if (/^[MmZzLlHhVvCcSsQqTtAa]/.test(str)) {\n return str;\n }\n return undefined;\n}\n\n/**\n * Checks if the value is a path string (either \"path(...)\" or raw \"M...\").\n */\nfunction isPathString(value: any): value is string {\n return typeof value === 'string' && extractPathData(value) !== undefined;\n}\n\n/**\n * Normalizes a 'd' attribute value to { paths: PxBezierPath[] } format.\n * Handles:\n * - { path: \"M...\" } / { path: \"path(...)\" } -> { paths: [PxBezierPath] } (unified single-string form)\n * - { paths: [\"path(...)\"] } -> { paths: [PxBezierPath] }\n * - { paths: [\"M...\"] } -> { paths: [PxBezierPath] }\n * - [\"path(...)\"] -> { paths: [PxBezierPath] }\n * - [\"M...\"] -> { paths: [PxBezierPath] }\n * - \"path(...)\" -> { paths: [PxBezierPath] }\n * - \"M...\" -> { paths: [PxBezierPath] }\n * - { paths: [PxBezierPath] } -> as-is\n */\nfunction normalizePathValue(value: any): { paths: Array<PxBezierPath> } | any {\n // Unified single-string form: { path: \"M...\" } (compound = multiple `M…` sub-paths in one string).\n if (value && typeof value === 'object' && typeof value.path === 'string') {\n const d = extractPathData(value.path);\n return d ? { paths: parseSvgPathToBezier(d) } : value;\n }\n\n // If already in { paths: [...] } format\n if (value && typeof value === 'object' && 'paths' in value) {\n const pathsArray = value.paths;\n if (Array.isArray(pathsArray) && pathsArray.length > 0) {\n // Check if paths contain path strings that need parsing\n if (isPathString(pathsArray[0])) {\n const paths: Array<PxBezierPath> = [];\n for (const pathStr of pathsArray) {\n const d = extractPathData(pathStr);\n if (d) {\n paths.push(...parseSvgPathToBezier(d));\n }\n }\n return { paths };\n }\n }\n // Already in correct format\n return value;\n }\n\n // If it's an array of path strings\n if (Array.isArray(value)) {\n if (value.length > 0 && isPathString(value[0])) {\n const paths: Array<PxBezierPath> = [];\n for (const pathStr of value) {\n const d = extractPathData(pathStr);\n if (d) {\n paths.push(...parseSvgPathToBezier(d));\n }\n }\n return { paths };\n }\n // Already an array of PxBezierPath - wrap in { paths: }\n return { paths: value };\n }\n\n // If it's a single path string\n if (isPathString(value)) {\n const d = extractPathData(value)!;\n return { paths: parseSvgPathToBezier(d) };\n }\n\n return value;\n}\n\n\n// ============================================================================\n// NORMALIZATION: Convert new API format to internal normalized format\n// ============================================================================\n\n/**\n * Resolves an easing reference to a cubic-bezier array.\n * @param easing The easing reference (string name or bezier array)\n * @param defs The definitions containing named easings\n * @returns The resolved cubic-bezier array or undefined\n */\nfunction resolveEasing(\n easing: string | [number, number, number, number] | undefined,\n defs?: PxDefs\n): [number, number, number, number] | undefined {\n if (!easing) return undefined;\n\n if (Array.isArray(easing)) {\n return easing;\n }\n\n // Look up named easing in defs\n if (defs?.easings?.[easing]) {\n return defs.easings[easing];\n }\n\n // Unknown easing name - return undefined\n console.warn('Unknown easing name: ' + easing);\n return undefined;\n}\n\n/**\n * Resolves an animation reference to an AnimationDefinition.\n * @param animRef The animation reference (string name or inline definition)\n * @param defs The definitions containing named animations\n * @returns The resolved animation definition\n */\nfunction resolveAnimation(\n animRef: string | PxAnimationDefinition,\n defs?: PxDefs\n): PxAnimationDefinition | undefined {\n if (typeof animRef === 'string') {\n // Look up named animation in defs\n const resolved = defs?.animations?.[animRef];\n if (!resolved) {\n console.warn('Unknown animation name: ' + animRef);\n }\n return resolved;\n }\n\n // It's an inline definition\n return animRef;\n}\n\n/**\n * Resolves an element animation (which can be string, array, or inline) to an array of AnimationDefinitions.\n * @param animate The element animation specification\n * @param defs The definitions containing named animations\n * @returns Array of resolved animation definitions\n */\nfunction resolveElementAnimation(\n animate: PxElementAnimation | undefined,\n defs?: PxDefs\n): PxAnimationDefinition[] {\n if (!animate) return [];\n\n const results: PxAnimationDefinition[] = [];\n\n if (typeof animate === 'string') {\n const resolved = resolveAnimation(animate, defs);\n if (resolved) results.push(resolved);\n } else if (Array.isArray(animate)) {\n for (const item of animate) {\n const resolved = resolveAnimation(item, defs);\n if (resolved) results.push(resolved);\n }\n } else {\n // It's an inline AnimationDefinition\n results.push(animate);\n }\n\n return results;\n}\n\n// ============================================================================\n// LOOP EXPANSION: Duplicate keyframe segments to fill gaps in the timeline\n// ============================================================================\n\n/**\n * Interpolates between two keyframe values based on property type.\n * Returns the raw interpolated value (not a CSS string).\n *\n * Dispatch order matters — the unified-transform-record branch must run\n * BEFORE the standalone-`rotate` branch, otherwise a `transform`-named\n * animation whose kfs are number-typed (rare but valid) would be routed\n * through the vec path.\n */\nexport function interpolateValue(propName: string, a: any, b: any, t: number): any {\n if (propName === 'd') {\n const aPaths = a?.paths ?? (Array.isArray(a) ? a : []);\n const bPaths = b?.paths ?? (Array.isArray(b) ? b : []);\n return { paths: interpolateBeziers(aPaths, bPaths, t) };\n }\n if (COLOUR_ATTR_NAMES.has(propName)) {\n return interpolateColor(a || [0, 0, 0, 1], b || [0, 0, 0, 1], t);\n }\n // Unified-transform record (`{translate, rotate, scale, origin}`) — the\n // most common animated `propName === 'transform'` shape. Per-part interp\n // so `+({}) = NaN` (the old fall-through) doesn't poison the boundary kf\n // at a loop seam.\n if (propName === 'transform'\n && typeof a === 'object' && a !== null && !Array.isArray(a)\n && typeof b === 'object' && b !== null && !Array.isArray(b)\n ) {\n return interpolateTransformParts(a as PxTransformParts, b as PxTransformParts, t);\n }\n // Standalone `rotate` as a propAnim — value is a NUMBER, not a vector.\n // The general TRANSFORM_FN_NAMES branch below would route it through\n // `interpolateVec`, which on a scalar returns `[]` (length NaN → no loop)\n // — wrong CSS output.\n if (propName === 'rotate' && typeof a === 'number' && typeof b === 'number') {\n return interpolateNum(a, b, t);\n }\n if (TRANSFORM_FN_NAMES.has(propName) || propName === 'stroke-dasharray' || propName === 'strokeDasharray') {\n return interpolateVec(a || [], b || [], t);\n }\n return interpolateNum(+(a || 0), +(b || 0), t);\n}\n\n/** Per-part interpolation for a unified-transform parts record. Mirrors the\n * inline logic in `calcPropertyValue`'s transform branch. */\nfunction interpolateTransformParts(a: PxTransformParts, b: PxTransformParts, t: number): PxTransformParts {\n const keys = new Set<string>([...Object.keys(a ?? {}), ...Object.keys(b ?? {})]);\n const out: { [k: string]: unknown } = {};\n for (const k of keys) {\n const av = (a as { [k: string]: unknown })?.[k];\n const bv = (b as { [k: string]: unknown })?.[k];\n if (k === 'rotate' || k === 'skew') {\n out[k] = interpolateNum(+(av ?? 0), +(bv ?? 0), t);\n } else if (k === 'translate' || k === 'scale' || k === 'origin') {\n const fallback: Array<number> = k === 'scale' ? [1, 1] : [0, 0];\n out[k] = interpolateVec((av as Array<number>) || fallback, (bv as Array<number>) || fallback, t);\n } else {\n // Unknown part — prefer next if present, otherwise prev.\n out[k] = bv ?? av;\n }\n }\n return out as PxTransformParts;\n}\n\ninterface LoopTemplateEntry {\n relT: number; // 0..1 relative position within segment\n v: any;\n e: [number, number, number, number] | undefined;\n // Per-vertex spatial tangents (motion-along-path). Carried so repeated\n // segments keep their curvature; reversed reps swap in<->out (see appendRep).\n tangentIn?: [number, number];\n tangentOut?: [number, number];\n}\n\n/**\n * Expands keyframes by repeating a segment to fill the gap between the keyframe\n * range and the global animation duration, implementing PxLoop \"local loop\" behavior.\n */\nfunction expandLoopKeyframes(\n propName: string,\n keyframes: PxKeyframe[],\n loop: PxLoop,\n duration: number\n): PxKeyframe[] {\n const totalIntervals = keyframes.length - 1;\n const segCount = clamp(loop.segmentCount ?? totalIntervals, 1, totalIntervals);\n\n // Extract segment keyframes\n let segKfs: PxKeyframe[];\n if (loop.before) {\n segKfs = keyframes.slice(0, segCount + 1);\n } else {\n segKfs = keyframes.slice(totalIntervals - segCount);\n }\n\n // Determine fill region\n const firstT = keyframes[0].t ?? 0;\n const lastT = keyframes[keyframes.length - 1].t ?? 0;\n\n let fillStart: number, fillEnd: number;\n if (loop.before) {\n fillStart = 0;\n fillEnd = firstT;\n } else {\n fillStart = lastT;\n fillEnd = duration;\n }\n\n const fillDuration = fillEnd - fillStart;\n if (fillDuration <= 0) return keyframes;\n\n // Segment timing\n const segStartT = segKfs[0].t ?? 0;\n const segEndT = segKfs[segKfs.length - 1].t ?? 0;\n const segDuration = segEndT - segStartT;\n if (segDuration <= 0) return keyframes;\n\n // Build template with relative offsets (0..1)\n const template: LoopTemplateEntry[] = segKfs.map(kf => ({\n relT: (kf.t! - segStartT) / segDuration,\n v: kf.v,\n e: kf.e as [number, number, number, number] | undefined,\n tangentIn: (kf.tangentIn ?? kf.ti) as [number, number] | undefined,\n tangentOut: (kf.tangentOut ?? kf.to) as [number, number] | undefined\n }));\n\n const fullReps = Math.floor(fillDuration / segDuration);\n const remainder = fillDuration - fullReps * segDuration;\n const partialFraction = remainder / segDuration;\n\n const looped: PxKeyframe[] = [];\n\n // Helper: append one full or partial repetition\n function appendRep(repStart: number, isReversed: boolean, partial?: number) {\n let entries: LoopTemplateEntry[];\n if (isReversed) {\n // Reverse keyframe order and reverse easings\n entries = [];\n for (let i = template.length - 1; i >= 0; i--) {\n entries.push({\n relT: 1 - template[i].relT,\n v: template[i].v,\n // Easing for reversed transition: use reversed easing from the forward \"from\" keyframe\n e: i > 0 ? reverseEasing(template[i - 1].e) : undefined,\n // Reversed traversal swaps each vertex's in/out spatial tangents\n // (geometry is identical, walked backwards), so curvature and\n // auto-orientation survive the reversed rep.\n tangentIn: template[i].tangentOut,\n tangentOut: template[i].tangentIn\n });\n }\n } else {\n entries = template;\n }\n\n const cutRelT = partial !== undefined ? partial : 1;\n\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n if (entry.relT > cutRelT + 1e-9) {\n // Past the cut point — insert interpolated keyframe\n const prev = entries[i - 1];\n const intervalSpan = entry.relT - prev.relT;\n const localFrac = (cutRelT - prev.relT) / intervalSpan;\n\n // Apply easing to get the eased progress for value interpolation\n const easedFrac = prev.e ? cubicBezier(prev.e)(localFrac) : localFrac;\n const cutValue = interpolateValue(propName, prev.v, entry.v, easedFrac);\n\n // Split easing — use left portion for the truncated interval\n const { left: leftEasing } = splitEasing(prev.e, localFrac);\n\n // Update previous keyframe's easing to the left portion\n if (looped.length > 0 && prev.relT <= cutRelT) {\n looped[looped.length - 1].e = leftEasing;\n }\n\n looped.push({ t: repStart + cutRelT * segDuration, v: cutValue, e: undefined });\n return;\n }\n\n const pushed: PxKeyframe = {\n t: repStart + entry.relT * segDuration,\n v: entry.v,\n e: i < entries.length - 1 ? entry.e : undefined\n };\n // Carry per-vertex spatial tangents so the repeated segment keeps its\n // motion-path curvature (reversed reps already have in/out swapped above).\n if (entry.tangentIn) pushed.tangentIn = entry.tangentIn;\n if (entry.tangentOut) pushed.tangentOut = entry.tangentOut;\n looped.push(pushed);\n }\n }\n\n // Like {@link appendRep} but emits only the TAIL of the segment — relT ∈\n // [1-tailFraction, 1] — over [repStart, repStart + tailFraction*segDuration].\n // Used for the leftover (partial) rep of a `before` loop: it sits at fillStart\n // and runs UP TO the segment-end value, so the full reps after it align to end\n // exactly at the first original keyframe (firstT). A head-truncated partial here\n // (as appendRep does) would land the leftover ADJACENT to firstT and desync the\n // whole backward fill — the loopIn `f0` bug.\n function appendRepTail(repStart: number, isReversed: boolean, tailFraction: number) {\n let entries: LoopTemplateEntry[];\n if (isReversed) {\n entries = [];\n for (let i = template.length - 1; i >= 0; i--) {\n entries.push({\n relT: 1 - template[i].relT,\n v: template[i].v,\n e: i > 0 ? reverseEasing(template[i - 1].e) : undefined,\n tangentIn: template[i].tangentOut,\n tangentOut: template[i].tangentIn\n });\n }\n } else {\n entries = template;\n }\n\n const startRelT = 1 - tailFraction;\n\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n if (entry.relT < startRelT - 1e-9) continue; // wholly before the tail window\n const prev = entries[i - 1];\n\n // If startRelT falls strictly inside (prev, entry), the tail begins\n // mid-interval — emit an interpolated keyframe at repStart carrying the\n // RIGHT split of prev's easing.\n if (prev && prev.relT < startRelT - 1e-9 && entry.relT > startRelT + 1e-9) {\n const intervalSpan = entry.relT - prev.relT;\n const localFrac = (startRelT - prev.relT) / intervalSpan;\n const easedFrac = prev.e ? cubicBezier(prev.e)(localFrac) : localFrac;\n const startValue = interpolateValue(propName, prev.v, entry.v, easedFrac);\n const { right: rightEasing } = splitEasing(prev.e, localFrac);\n looped.push({ t: repStart, v: startValue, e: rightEasing });\n }\n\n const pushed: PxKeyframe = {\n t: repStart + (entry.relT - startRelT) * segDuration,\n v: entry.v,\n e: i < entries.length - 1 ? entry.e : undefined\n };\n if (entry.tangentIn) pushed.tangentIn = entry.tangentIn;\n if (entry.tangentOut) pushed.tangentOut = entry.tangentOut;\n looped.push(pushed);\n }\n }\n\n // Generate repetitions.\n // The rep closest to the original keyframes boundary must be reversed first\n // in pingpong mode (the animation just finished going forward, so the next\n // iteration goes backward).\n if (loop.before) {\n // loopIn — the fill must END exactly at the first keyframe (firstT), so the\n // reps tile BACKWARD from that boundary: the leftover (partial) rep sits at\n // fillStart showing the segment's tail, then `fullReps` full reps run up to\n // firstT. (Forward-tiling — as loopOut does — would push the partial next to\n // firstT and desync the fill: the loopIn `f0` regression.)\n if (partialFraction > 1e-9) {\n const isReversed = !!loop.alternate && (fullReps % 2 === 0);\n appendRepTail(fillStart, isReversed, partialFraction);\n }\n for (let rep = 0; rep < fullReps; rep++) {\n const distFromBoundary = fullReps - 1 - rep;\n const isReversed = !!loop.alternate && (distFromBoundary % 2 === 0);\n const repStart = fillStart + remainder + rep * segDuration;\n appendRep(repStart, isReversed);\n }\n } else {\n // loopOut — boundary is at fillStart (lastT); tile forward, partial at the end.\n for (let rep = 0; rep < fullReps; rep++) {\n const isReversed = !!loop.alternate && (rep % 2 === 0);\n const repStart = fillStart + rep * segDuration;\n appendRep(repStart, isReversed);\n }\n if (partialFraction > 1e-9) {\n const isReversed = !!loop.alternate && (fullReps % 2 === 0);\n const repStart = fillStart + fullReps * segDuration;\n appendRep(repStart, isReversed, partialFraction);\n }\n }\n\n // Assemble: looped keyframes go before or after the original keyframes.\n // No junction deduplication — cycle mode relies on value jumps at boundaries.\n if (loop.before) {\n return [...looped, ...keyframes];\n } else {\n return [...keyframes, ...looped];\n }\n}\n\n\n// ============================================================================\n// KEYFRAME NORMALIZATION\n// ============================================================================\n\n/**\n * Normalizes keyframes from the new API format (time in ms) to internal format (time as 0-1 fraction).\n * Resolves easing references, normalizes times, and converts path strings for 'd' attribute.\n * If a loop configuration is present, expands the keyframes to fill the global duration.\n * @param propName The property name (e.g., 'd' for path)\n * @param propAnim The property animation with keyframes\n * @param duration The total animation duration in ms\n * @param defs The definitions containing named easings\n * @returns Array of normalized keyframes (same structure, resolved refs, normalized times)\n */\nfunction normalizeKeyframes(\n propName: string,\n propAnim: PxPropertyAnimation,\n duration: number,\n defs?: PxDefs\n): PxKeyframe[] {\n const keyframes = propAnim.keyframes || propAnim.kfs || [];\n\n const normalized: PxKeyframe[] = [];\n\n for (const kf of keyframes) {\n const timePct = kf.time ?? kf.t ?? 0;\n let value = kf.value ?? kf.v;\n const easing = kf.easing ?? kf.e;\n\n // Normalize path values for 'd' attribute\n if (propName === 'd') {\n value = normalizePathValue(value);\n }\n\n // Normalize color values (hex/rgb/rgba strings to [0-1] vectors).\n // `COLOUR_ATTR_NAMES` is keyed in kebab-case (`stop-color`, `flood-color`,\n // `lighting-color`); the wire format uses both kebab AND camelCase\n // (`stopColor`) for these props. Without converting, frames-mode would\n // call `interpolateColor` on the raw strings and produce `NaN` channels\n // — the visible \"rgba(NaN,NaN,NaN,…)\" bug on stop-color animations.\n const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;\n if (COLOUR_ATTR_NAMES.has(propNameKebab)) {\n value = parseColor(value) ?? value;\n }\n\n const normKf: PxKeyframe = {\n t: timePct,\n v: value,\n e: resolveEasing(easing, defs)\n };\n // Motion-along-path: keep the spatial tangents so the downstream\n // `materialiseMotionPathInPropAnim` (called in `normalizeAnimationDefinition`) can\n // sample them into transform kfs. Short aliases `ti` / `to` collapse\n // into their canonical names.\n const tIn = kf.tangentIn ?? kf.ti;\n const tOut = kf.tangentOut ?? kf.to;\n if (tIn) normKf.tangentIn = tIn;\n if (tOut) normKf.tangentOut = tOut;\n\n normalized.push(normKf);\n }\n\n // Sort by time\n normalized.sort((a, b) => (a.t ?? 0) - (b.t ?? 0));\n\n // Expand loop if configured (loop:true is shorthand for default PxLoop)\n const loopRaw = propAnim.loop;\n const loop: PxLoop | undefined = loopRaw === true ? {} : loopRaw || undefined;\n if (loop && normalized.length >= 2) {\n return expandLoopKeyframes(propName, normalized, loop, duration);\n }\n\n return normalized;\n}\n\n/**\n * Merges multiple animation definitions into a single combined definition.\n * Later definitions override earlier ones for the same property.\n */\nfunction mergeAnimationDefinitions(\n animations: PxAnimationDefinition[]\n): PxAnimationDefinition {\n const merged: PxAnimationDefinition = {};\n\n for (const anim of animations) {\n for (const [prop, propAnim] of Object.entries(anim)) {\n merged[prop] = propAnim;\n }\n }\n\n return merged;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Public loop-materialisation API\n//\n// Used internally by `normalizeKeyframes` (where `expandLoopKeyframes` is\n// already called at the tail of normalisation). Exposed here at the propAnim\n// and tree levels so the Editor (or any external caller) can compose:\n// root = applyPlayerEffects(root).root;\n// root = materialiseInternalLoopsInTree(root, duration);\n// root = materialiseMotionPathsInTree(root);\n// to produce a fully-flat document with no `loop`, no `effects`, no tangents.\n// ─────────────────────────────────────────────────────────────────────────────\n\n\n/**\n * Replaces `propAnim.loop` with explicit repeated keyframes via\n * `expandLoopKeyframes`. Returns the input by reference when no loop is\n * configured (no-op). Output drops the `loop` field (consumed).\n */\nexport function materialiseInternalLoopsInPropAnim(\n propName: string,\n propAnim: PxPropertyAnimation,\n duration: number,\n): PxPropertyAnimation {\n const loopRaw = propAnim.loop;\n if (loopRaw === undefined || loopRaw === null || loopRaw === false) return propAnim;\n const loop: PxLoop = loopRaw === true ? {} : (loopRaw as PxLoop);\n const rawKfs = (propAnim.keyframes ?? propAnim.kfs) as PxKeyframe[] | undefined;\n if (!Array.isArray(rawKfs) || rawKfs.length < 2) return propAnim;\n\n // `expandLoopKeyframes` reads kf.t / kf.v / kf.e (short form). When this\n // function is called from the materialisation pipeline OUTSIDE the\n // binding-normalisation path (e.g. by `materialiseAllInTree`), the input\n // kfs may still be in long form (`time` / `value` / `easing`) AND the\n // values may be unparsed (hex colour strings, raw path-`d`). Normalise\n // both here so `interpolateValue` (called by `expandLoopKeyframes` at the\n // loop seam) sees structured data — without this, a colour boundary kf\n // ends up `[NaN,NaN,NaN,NaN]` and the bug stays visible until the\n // animation cycle restarts.\n const propNameKebab = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;\n const isColour = COLOUR_ATTR_NAMES.has(propNameKebab);\n const kfs: PxKeyframe[] = rawKfs.map(kf => {\n const t = kf.t ?? kf.time;\n let v: unknown = kf.v ?? kf.value;\n if (propName === 'd') v = normalizePathValue(v);\n if (isColour) v = parseColor(v) ?? v;\n const e = kf.e ?? kf.easing;\n const out: PxKeyframe = { t, v, e } as PxKeyframe;\n if (kf.tangentIn ?? kf.ti) out.tangentIn = (kf.tangentIn ?? kf.ti) as [number, number];\n if (kf.tangentOut ?? kf.to) out.tangentOut = (kf.tangentOut ?? kf.to) as [number, number];\n return out;\n });\n\n const expanded = expandLoopKeyframes(propName, kfs, loop, duration);\n const out: PxPropertyAnimation = { kfs: expanded } as PxPropertyAnimation;\n if (propAnim.autoOrient !== undefined) (out as { autoOrient?: unknown }).autoOrient = propAnim.autoOrient;\n return out;\n}\n\n\n/**\n * Walks `root` and materialises every animated property's `loop` via\n * `materialiseInternalLoopsInPropAnim`. Immutable — returns the input by\n * reference when no loop was found anywhere; otherwise clones along the path\n * to each affected node, sharing untouched sub-trees.\n */\nexport function materialiseInternalLoopsInTree(\n root: PxNode,\n duration: number,\n): PxNode {\n const ret = walkAndMaterialiseLoops(root, duration);\n return ret ?? root;\n}\n\nfunction walkAndMaterialiseLoops(node: PxNode, duration: number): PxNode | null {\n let newChildren: Array<PxNode> | undefined;\n if (node.children) {\n for (let i = 0; i < node.children.length; i++) {\n const ret = walkAndMaterialiseLoops(node.children[i], duration);\n if (ret !== null) {\n if (!newChildren) newChildren = node.children.slice();\n newChildren[i] = ret;\n }\n }\n }\n let newAnimate: Record<string, PxPropertyAnimation> | undefined;\n const animBucket = node.animate;\n if (animBucket && typeof animBucket === 'object' && !Array.isArray(animBucket)) {\n const animDef = animBucket as Record<string, PxPropertyAnimation>;\n for (const propName of Object.keys(animDef)) {\n const propAnim = animDef[propName];\n const materialised = materialiseInternalLoopsInPropAnim(propName, propAnim, duration);\n if (materialised !== propAnim) {\n if (!newAnimate) newAnimate = { ...animDef };\n newAnimate[propName] = materialised;\n }\n }\n }\n if (!newChildren && !newAnimate) return null;\n const cloned: PxNode = { ...node };\n if (newChildren) cloned.children = newChildren;\n if (newAnimate) cloned.animate = newAnimate as PxNode['animate'];\n return cloned;\n}\n\n\n/**\n * Generates a unique element ID for internal tracking during DOM rendering.\n */\nlet _elementIdCounter = 0;\nexport function generateElementId(): string {\n return '_px_el_' + (++_elementIdCounter);\n}\n\n/**\n * Resets the element ID counter (useful for testing).\n */\nexport function resetElementIdCounter(): void {\n _elementIdCounter = 0;\n}\n\n/**\n * Normalizes an animation definition by resolving easing references and normalizing keyframe times.\n * Keeps the key/value mapping structure. `engine` controls motion-along-path\n * handling — see {@link PxAnimatorEngine}.\n */\nfunction normalizeAnimationDefinition(\n animDef: PxAnimationDefinition,\n duration: number,\n defs?: PxDefs,\n engine: PxAnimatorEngine = PxAnimatorEngine.webapi,\n): PxAnimationDefinition {\n const normalized: PxAnimationDefinition = {};\n\n for (const [propName, propAnim] of Object.entries(animDef)) {\n const normalizedKfs = normalizeKeyframes(propName, propAnim, duration, defs);\n if (normalizedKfs.length > 0) {\n const out: PxPropertyAnimation = { kfs: normalizedKfs };\n // Carry top-level animation flags through normalization — `materialiseMotionPathInPropAnim`\n // and the runtime evaluators need `autoOrient` / `loop` to be present\n // alongside the kfs.\n if (propAnim.autoOrient !== undefined) out.autoOrient = propAnim.autoOrient;\n if (propAnim.loop !== undefined) out.loop = propAnim.loop;\n\n // Pipeline: loops are already expanded by `normalizeKeyframes` above.\n // For the `webapi` engine ONLY, materialise motion-along-path\n // (tangented `transform` kfs + autoOrient) into plain sampled\n // `{ translate, rotate? }` kfs — CSS WAAPI can't evaluate parametric\n // tangents at runtime. Frames-mode keeps the parametric form so the\n // frame-loop kernel `evaluateMotionPathSegment` can sample per frame\n // (better spatial fidelity than any finite sampling).\n // `materialiseMotionPathInPropAnim` is a no-op for non-motion-path\n // animations, so non-transform props pay zero cost.\n normalized[propName] = (engine === PxAnimatorEngine.webapi && propName === 'transform')\n ? materialiseMotionPathInPropAnim(out)\n : out;\n }\n }\n\n return normalized;\n}\n\n/**\n * Normalizes a PxAnimatedSvgDocument to a PxAnimatorConfig for the animation engines.\n * This is the main entry point for converting the new API format to internal format.\n * Resolves animation/easing references. `engine` controls motion-along-path\n * handling — see {@link PxAnimatorEngine}.\n */\nexport function getNormalisedBindings(\n doc: PxAnimatedSvgDocument,\n engine: PxAnimatorEngine = PxAnimatorEngine.webapi,\n): PxBinding[] {\n const animatorConfig = getAnimatorConfig(doc) || {};\n const defs = getDefs(doc);\n const duration = animatorConfig.duration || 1000; // FIXME - get rid of 1000 here\n\n const bindings: PxBinding[] = [];\n\n // Helper to resolve and normalize animation for a binding\n const processAnimation = (\n id: string,\n animate: PxElementAnimation | undefined\n ): PxBinding | null => {\n if (!animate) return null;\n\n const animDefs = resolveElementAnimation(animate, defs);\n if (animDefs.length === 0) return null;\n\n const merged = mergeAnimationDefinitions(animDefs);\n const normalizedAnim = normalizeAnimationDefinition(merged, duration, defs, engine);\n\n if (Object.keys(normalizedAnim).length === 0) return null;\n\n return {\n id,\n animate: normalizedAnim\n };\n };\n\n // Process bindings (for pre-rendered DOM)\n const docBindings = getBindings(doc);\n if (docBindings) {\n for (const binding of docBindings) {\n const normalized = processAnimation(binding.id, binding.animate);\n if (normalized) bindings.push(normalized);\n }\n }\n\n // Process children (for rendered DOM).\n //\n // Per-element animations live under the node's `animate` bucket, keyed by\n // SVG/CSS property name — a PxAnimationDefinition (`{ transform: {keyframes},\n // fill: {keyframes}, … }`). The static initial value of each animated\n // property is carried separately as a plain attribute on the element body.\n // On-disk locations: top-level `node.animate` (JSON form).\n const processNode = (node: PxNode) => {\n const inlineAnim = node.animate;\n if (inlineAnim && Object.keys(inlineAnim).length > 0) {\n const nodeId = node.id || generateElementId();\n node.id = nodeId; // Ensure the node has an ID\n const normalized = processAnimation(nodeId, inlineAnim);\n if (normalized) bindings.push(normalized);\n }\n\n // Process children\n if (node.children) {\n for (let i = 0; i < node.children.length; i++) {\n processNode(node.children[i]);\n }\n }\n };\n\n // Process children of the root\n if (doc.children) {\n for (let i = 0; i < doc.children.length; i++) {\n processNode(doc.children[i]);\n }\n }\n\n return bindings;\n}\n\n\n// ============================================================================\n// ATTRIBUTE VALUE CALCULATION (used by frame loop animator)\n// ============================================================================\n\n/**\n * Finds prev/next keyframes for a given progress.\n */\nfunction getKeyframesPair(keyframes: PxKeyframe[], progress: number) {\n // Outside the keyframe range, clamp to the NEAREST REAL segment (the caller clamps\n // `localProgress` to 0/1, so that holds the boundary pose). Spanning first→last\n // instead would invent a segment that exists nowhere in the animation: for keyframes\n // that start part-way into the timeline, the pre-start frames used to interpolate\n // straight from the first to the LAST keyframe — skipping everything between, and\n // handing motion-path evaluation a chord it then cached (see `getSegmentCache`).\n const last = keyframes.length - 1;\n let prevKf = keyframes[0];\n let nextKf = keyframes[last > 0 ? 1 : 0];\n\n for (let j = 0; j < last; j++) {\n const aOff = (keyframes[j].t ?? 0);\n const bOff = (keyframes[j + 1].t ?? 0);\n if (aOff <= progress && progress <= bOff) {\n prevKf = keyframes[j];\n nextKf = keyframes[j + 1];\n break;\n }\n // Past this segment and not bracketed by any later one → hold the final segment.\n if (progress > bOff && j === last - 1) {\n prevKf = keyframes[last > 0 ? last - 1 : 0];\n nextKf = keyframes[last];\n }\n }\n return { prevKf, nextKf };\n}\n\n/**\n * Calculates interpolated value for a single property animation.\n */\nfunction calcPropertyValue(\n propName: string,\n propAnim: PxPropertyAnimation,\n progress: number\n): { k: string, v: string } | null {\n const keyframes = propAnim.kfs || propAnim.keyframes || [];\n if (keyframes.length === 0) return null;\n\n const { prevKf, nextKf } = getKeyframesPair(keyframes, progress);\n\n // remap to local 0..1 within prevKf..nextKf\n let localProgress = (prevKf === nextKf) ? 0 : remap(progress, prevKf.t ?? 0, nextKf.t ?? 0, 0, 1);\n localProgress = clamp(localProgress, 0, 1);\n const easing = prevKf.e ?? prevKf.easing; // e is on the source keyframe: applied from this KF to the next\n if (easing && Array.isArray(easing)) {\n try {\n localProgress = cubicBezier(easing as [number, number, number, number])(localProgress);\n } catch (e) {\n // fallback: ignore easing if parsing fails\n }\n }\n\n let cssAttrName = isCamelCaseWord(propName) ? camelCaseToKebabWordIfNeeded(propName) : propName;\n let cssValue: string | number | null = null;\n\n const prevV = prevKf?.v ?? prevKf?.value;\n const nextV = nextKf?.v ?? nextKf?.value;\n\n if (cssAttrName === 'd') {\n // Extract paths from { paths: [...] } format\n const prevPaths = prevV?.paths ?? (Array.isArray(prevV) ? prevV : []);\n const nextPaths = nextV?.paths ?? (Array.isArray(nextV) ? nextV : []);\n cssValue = interpolateBeziers(\n prevPaths,\n nextPaths,\n localProgress\n ).map(bz => bezierToSvgPath(bz)).join('');\n } else if (COLOUR_ATTR_NAMES.has(cssAttrName)) {\n cssValue = toRGBA(interpolateColor(\n prevV || [0, 0, 0, 1],\n nextV || [0, 0, 0, 1],\n localProgress\n ));\n cssAttrName = propName;\n } else if (cssAttrName === 'stroke-dasharray') {\n cssValue = interpolateVec(\n prevV || [],\n nextV || [],\n localProgress\n ).join(' ');\n cssAttrName = propName;\n } else if (\n cssAttrName === 'transform' &&\n prevV !== null && typeof prevV === 'object' && !Array.isArray(prevV)\n ) {\n // Unified transform: keyframe values are PxTransformParts records.\n // Interpolate each present part separately, then compose into a transform\n // string for the SVG `transform` attribute (no units).\n const partKeys = new Set<string>([\n ...(prevV ? Object.keys(prevV) : []),\n ...(nextV ? Object.keys(nextV) : []),\n ]);\n const partsResult: PxTransformParts = {};\n for (const partKey of partKeys) {\n const prevPart = prevV?.[partKey];\n const nextPart = nextV?.[partKey];\n if (partKey === 'rotate' || partKey === 'skew') {\n partsResult[partKey] = interpolateNum(+(prevPart ?? 0), +(nextPart ?? 0), localProgress);\n } else if (partKey === 'translate' || partKey === 'scale' || partKey === 'origin') {\n const fallback = partKey === 'scale' ? [1, 1] : [0, 0];\n const interp = interpolateVec(prevPart || fallback, nextPart || fallback, localProgress);\n (partsResult as any)[partKey] = interp;\n }\n }\n // Motion-along-path override (frames-mode only). The WAAPI binding\n // pipeline materialises tangents + autoOrient into sampled\n // `{translate, rotate}` kfs upstream (in `normalizeAnimationDefinition`),\n // so for WAAPI this branch is a no-op (`propAnimIsMotionPath` returns\n // false on already-materialised kfs). Frames-mode preserves the\n // parametric form and we evaluate the Bezier per frame here — gives\n // exact spatial fidelity vs. any finite sampling.\n if (propAnimIsMotionPath(propAnim)) {\n const prevTr = (prevV as { translate?: [number, number] }).translate;\n const nextTr = (nextV as { translate?: [number, number] }).translate;\n if (Array.isArray(prevTr) && Array.isArray(nextTr)) {\n const sample = evaluateMotionPathSegment(\n prevKf, nextKf,\n [+prevTr[0], +prevTr[1]],\n [+nextTr[0], +nextTr[1]],\n localProgress,\n !!propAnim.autoOrient,\n );\n partsResult.translate = [sample.translate[0], sample.translate[1]];\n if (sample.rotateDeg !== undefined) partsResult.rotate = sample.rotateDeg;\n }\n }\n cssValue = composeTransformParts(partsResult, { withUnits: false });\n cssAttrName = 'transform';\n } else if (cssAttrName === 'translate') {\n const v = interpolateVec(\n prevV || [0, 0],\n nextV || [0, 0],\n localProgress\n );\n cssValue = 'translate(' + v.join(',') + ')';\n cssAttrName = 'transform';\n } else if (cssAttrName === 'rotate') {\n const v = interpolateNum(\n +(prevV || 0),\n +(nextV || 0),\n localProgress\n );\n cssValue = 'rotate(' + v + ')';\n cssAttrName = 'transform';\n } else if (cssAttrName === 'scale') {\n const v = interpolateVec(\n prevV || [1, 1],\n nextV || [1, 1],\n localProgress\n );\n cssValue = 'scale(' + v.join(',') + ')';\n cssAttrName = 'transform';\n } else {\n // numeric attr\n const num = interpolateNum(\n +(prevV || 0),\n +(nextV || 0),\n localProgress\n );\n cssValue = num;\n }\n\n if (PCT_BASED_ATTR_NAMES.has(cssAttrName) && typeof cssValue === 'number') {\n cssValue = (cssValue * 100) + '%';\n }\n\n return { k: cssAttrName, v: cssValue === null ? '' : '' + cssValue };\n}\n\n/**\n * Calculates interpolated attribute values for an animation definition.\n * @param animDef The animation definition (with resolved refs and normalized times)\n * @param progress The current animation progress (0-1)\n * @returns Object with computed attribute name/value pairs\n */\nexport function calcAnimationValues(\n animDef: PxAnimationDefinition,\n progress: number\n): Record<string, string> {\n const result: Record<string, string> = {};\n\n for (const [propName, propAnim] of Object.entries(animDef)) { \n const computed = calcPropertyValue(propName, propAnim, progress);\n if (computed) {\n result[computed.k] = computed.v;\n }\n }\n\n return result;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n/**\n * Shared \"clone a subtree and rewire its internal references\" primitives.\n *\n * Used by:\n * - The retime effect's `<use>` chain materialiser (`effects/util.ts`'s\n * `clone` + `regenerateIdsInClone`, which now delegate here).\n * - `PxAnimatorUseMaterialiser` — the WAAPI-side post-pass that replaces\n * `<use>` instances referencing animated subtrees with deep clones.\n *\n * Both call sites need the exact same two operations: a structural deep clone\n * of a `PxNode` subtree, and a renumber-all-ids pass that also rewrites\n * internal `href=\"#X\"` / `url(#X)` references to the new ids while leaving\n * outward-facing references alone.\n */\n\nimport type { PxNode } from './PxAnimatorTypes';\n\n\n/** Recursive deep clone for plain JSON-shaped `PxNode` data (objects, arrays,\n * primitives). Faster than `JSON.parse(JSON.stringify(x))` for large trees,\n * no behaviour difference for our wire format (no `Date` / `Map` / functions).\n */\nexport function deepClonePxNode<T>(value: T): T {\n if (value === null || typeof value !== 'object') return value;\n if (Array.isArray(value)) return value.map(deepClonePxNode) as unknown as T;\n const out: { [k: string]: unknown } = {};\n for (const k of Object.keys(value as object)) out[k] = deepClonePxNode((value as { [k: string]: unknown })[k]);\n return out as T;\n}\n\n\n/**\n * Regenerates every `id` inside `root` (root included) using fresh ids from\n * `genId()`, then rewrites internal DOM references (`href=\"#oldId\"` and\n * `url(#oldId)` inside string attrs) to the new ids. References that point\n * OUTSIDE the cloned subtree are left untouched.\n *\n * `meta.*`, `effects.*`, `animate.*` are intentionally skipped — they don't\n * carry DOM-reference syntax, and walking them per-string is wasted work.\n *\n * Returns the old→new id map so callers can rewrite their own outward-facing\n * references (e.g. a `<use>` href pointing at the cloned subtree root).\n */\nexport function regenerateIdsAndRewriteRefs(\n root: PxNode,\n genId: () => string,\n): Map<string, string> {\n const oldToNew = new Map<string, string>();\n\n const walkAssign = (n: PxNode): void => {\n if (typeof n.id === 'string') {\n const newId = genId();\n oldToNew.set(n.id, newId);\n n.id = newId;\n }\n n.children?.forEach(walkAssign);\n };\n walkAssign(root);\n\n const rewriteUrl = (s: string): string => s.replace(/url\\(#([^)]+)\\)/g, (m, oldId) => {\n const newId = oldToNew.get(oldId);\n return newId ? 'url(#' + newId + ')' : m;\n });\n\n const walkRewrite = (n: PxNode): void => {\n if (typeof n.href === 'string' && n.href.startsWith('#')) {\n const newId = oldToNew.get(n.href.slice(1));\n if (newId) n.href = '#' + newId;\n }\n for (const k of Object.keys(n)) {\n if (k === 'children' || k === 'effects' || k === 'meta' || k === 'animate' || k === 'href' || k === 'id') continue;\n const v = (n as { [k: string]: unknown })[k];\n if (typeof v === 'string' && v.indexOf('url(#') !== -1) {\n (n as { [k: string]: unknown })[k] = rewriteUrl(v);\n }\n }\n n.children?.forEach(walkRewrite);\n };\n walkRewrite(root);\n\n return oldToNew;\n}\n\n\nfunction toFiniteNum(v: unknown): number {\n const n = typeof v === 'number' ? v : typeof v === 'string' ? parseFloat(v) : NaN;\n return Number.isFinite(n) ? n : 0;\n}\n\n/**\n * Applies a `<use>`'s `x`/`y` offset when it is materialised into a `<g>`.\n *\n * Per SVG 2, `<use x y>` is an extra `translate(x, y)` appended AFTER the use's\n * own `transform`, so it composes innermost (closest to the referenced content).\n * `<g>` has no `x`/`y`, so the offset must become a transform — and when the use\n * also carries a (possibly animated) `transform`, the two can't be merged into a\n * single attribute, so the content is wrapped in an inner offset `<g>`:\n *\n * <use transform=\"T\" x=\"X\" y=\"Y\">\n * → <g transform=\"T\"><g transform=\"translate(X,Y)\">…content…</g></g>\n *\n * With no transform/animation, a single `<g transform=\"translate(X,Y)\">` suffices.\n *\n * `gNode` is the `<g>` already derived from the use (type:'g', href dropped, the\n * use's `transform`/`animate`/etc. carried over, `x`/`y` still present). Mutates\n * and returns it; `x`/`y` are removed.\n */\nexport function applyUseOffsetToG(gNode: PxNode): PxNode {\n const x = toFiniteNum((gNode as { x?: unknown }).x);\n const y = toFiniteNum((gNode as { y?: unknown }).y);\n delete (gNode as { x?: unknown }).x;\n delete (gNode as { y?: unknown }).y;\n if (!x && !y) return gNode;\n\n const offset = 'translate(' + x + ',' + y + ')';\n\n // Any existing transform/animation on the outer <g> must apply OUTSIDE the\n // offset, so push the offset into an inner wrapper rather than risk\n // overwriting/conflicting with the carried-over `transform`/`animate`.\n const carriesTransform =\n (gNode as { transform?: unknown }).transform !== undefined ||\n (gNode as { animate?: unknown }).animate !== undefined;\n\n if (carriesTransform) {\n const inner: PxNode = { type: 'g', transform: offset, children: gNode.children ?? [] } as PxNode;\n gNode.children = [inner];\n } else {\n (gNode as { transform?: string }).transform = offset;\n }\n return gNode;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n/**\n * `<use>` instance materialiser.\n *\n * WAAPI / CSS animations applied to an SVG source element don't reliably\n * render through `<use>` shadow trees in Chrome and Safari — the source\n * animates, the `<use>` shows static. This module fixes that by deep-cloning\n * every animated target into the corresponding `<use>` site (with fresh ids\n * and rewritten internal refs), and replacing the `<use>` with a `<g>` that\n * carries the use's transform/x/y attributes. Both engines (frames + webapi)\n * then animate the cloned nodes directly.\n *\n * Shares the deep-clone + id-regen + ref-rewrite primitives with the retime\n * effect (see `PxNodeCloneUtil`).\n *\n * Immutable: returns the input by reference when no `<use>` needs\n * materialisation; otherwise returns a new tree sharing untouched sub-trees.\n */\n\nimport { applyUseOffsetToG, deepClonePxNode, regenerateIdsAndRewriteRefs } from './PxNodeCloneUtil';\nimport type { PxNode } from './PxAnimatorTypes';\n\n\n/**\n * Walks `root`. For every `<use>` whose `href` target subtree contains any\n * `animate` bucket (recursively, following further `<use>` chains and\n * children), replaces the `<use>` with a `<g>` carrying a deep clone of the\n * target. The clone gets a fresh id on every node, and any internal `href` /\n * `url(#…)` refs that pointed at ids inside the cloned subtree are rewritten\n * to the new ids. Refs that point OUTSIDE the cloned subtree (e.g. a sibling\n * gradient) are left untouched.\n *\n * Recursive: if the materialised clone itself contains a `<use>` that needs\n * materialisation, that's handled in the same pass.\n */\nexport function materialiseAnimatedUseInstances(root: PxNode): PxNode {\n const idMap = buildIdMap(root);\n const animatedIds = computeAnimatedSubtreeIds(root, idMap);\n if (animatedIds.size === 0) return root;\n\n let idCounter = 0;\n const genId = (): string => '_lw_use_mat_' + (++idCounter);\n\n // The use's default width/height resolves against its viewport (= the\n // root `<svg>`). We snapshot the root's viewBox dimensions once so the\n // symbol-rewrite below can compute the viewBox-to-use-viewport scaling\n // without re-walking the tree for each use.\n const rootViewport = readRootViewport(root);\n\n // Collects clipPath / other defs minted by the symbol-rewrite path. After\n // the walk completes, these are spliced into the root tree's `<defs>`.\n const defsCollector: Array<PxNode> = [];\n const walked = walkAndMaterialise(root, idMap, animatedIds, genId, defsCollector, rootViewport);\n if (defsCollector.length === 0) return walked;\n\n // Append a `<defs>` child carrying every collected def. Browsers honour\n // multiple `<defs>` on the same SVG root, so we don't need to splice into\n // an existing one (which would also be more invasive — defs may have been\n // shared by reference with the original tree).\n const defsNode: PxNode = { type: 'defs', children: defsCollector };\n const newChildren = [...(walked.children ?? []), defsNode];\n return { ...walked, children: newChildren };\n}\n\n\n/** Reads the root `<svg>`'s effective viewport dimensions. Used as the\n * default for `<use>` width/height (which default to 100% of viewport per\n * SVG spec). Tries `viewBox` first (the typical authored shape from our\n * serialiser), then falls back to explicit `width`/`height` attrs. */\nfunction readRootViewport(root: PxNode): [number, number] {\n const vb = parseViewBox((root as { viewBox?: unknown }).viewBox);\n if (vb) return [vb[2], vb[3]];\n const w = numericAttr((root as { width?: unknown }).width);\n const h = numericAttr((root as { height?: unknown }).height);\n if (w !== undefined && h !== undefined) return [w, h];\n // No info — fall back to a 1:1 viewport so the scale degrades to \"identity\n // along the limiting axis\" (= the historical no-scale behaviour). Better\n // than NaN; the failing case is \"root has no viewport info at all\".\n return [1, 1];\n}\n\nfunction numericAttr(v: unknown): number | undefined {\n if (typeof v === 'number') return v;\n if (typeof v === 'string') {\n // Strip a trailing `px` or `%` — for percentages we don't have an\n // outer container to resolve against, so we treat the raw number as\n // the absolute size (correct when the user only authored a viewBox\n // and width/height match it).\n const n = parseFloat(v);\n return Number.isFinite(n) ? n : undefined;\n }\n return undefined;\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Internals\n// ─────────────────────────────────────────────────────────────────────────────\n\n\nfunction buildIdMap(root: PxNode): Map<string, PxNode> {\n const map = new Map<string, PxNode>();\n const visit = (n: PxNode): void => {\n if (typeof n.id === 'string') map.set(n.id, n);\n n.children?.forEach(visit);\n };\n visit(root);\n return map;\n}\n\n\n/** Returns the set of ids whose subtree (including descendants and any\n * `<use>`-referenced sub-subtrees) contains at least one `animate` bucket.\n * Uses a per-walk `visited` set to avoid infinite recursion on `<use>` cycles. */\nfunction computeAnimatedSubtreeIds(root: PxNode, idMap: Map<string, PxNode>): Set<string> {\n const cache = new WeakMap<PxNode, boolean>();\n const result = new Set<string>();\n\n const hasAnim = (n: PxNode, visiting: Set<PxNode>): boolean => {\n const cached = cache.get(n);\n if (cached !== undefined) return cached;\n if (visiting.has(n)) return false; // cycle guard\n visiting.add(n);\n\n let r = false;\n if (n.animate && typeof n.animate === 'object' && !Array.isArray(n.animate)) {\n for (const _ in n.animate) { r = true; break; }\n }\n if (!r && n.children) {\n for (const ch of n.children) {\n if (hasAnim(ch, visiting)) { r = true; break; }\n }\n }\n if (!r && n.type === 'use' && typeof n.href === 'string') {\n const targetId = stripHash(n.href);\n const target = targetId ? idMap.get(targetId) : undefined;\n if (target) r = hasAnim(target, visiting);\n }\n\n visiting.delete(n);\n cache.set(n, r);\n return r;\n };\n\n for (const [id, node] of idMap) {\n if (hasAnim(node, new Set())) result.add(id);\n }\n return result;\n}\n\n\nfunction stripHash(href: unknown): string | undefined {\n if (typeof href !== 'string') return undefined;\n return href.startsWith('#') ? href.slice(1) : href;\n}\n\n\n/** Builds the materialised `<g>` replacement for one `<use>` whose target's\n * subtree is animated. Carries the use's transform / position attributes. */\nfunction materialiseOneUse(\n useNode: PxNode,\n target: PxNode,\n idMap: Map<string, PxNode>,\n animatedIds: Set<string>,\n genId: () => string,\n defsCollector: Array<PxNode>,\n rootViewport: [number, number],\n): PxNode {\n const clone = deepClonePxNode(target);\n regenerateIdsAndRewriteRefs(clone, genId);\n\n // Use's effective width/height — explicit attrs if set; else the referenced\n // `<symbol>`'s OWN viewBox size (a `<use>` on a symbol-with-viewBox renders at\n // the symbol's natural size, NOT 100% of the viewport — the latter scales the\n // symbol up, e.g. 80×80 → 139×139). Our serialiser now always emits explicit\n // width/height, so this fallback is the safety net for inputs that omit them.\n // Falls back to the root viewport only when there's no viewBox to size from.\n const symbolViewBox = clone.type === 'symbol' ? parseViewBox((clone as { viewBox?: unknown }).viewBox) : undefined;\n const useW = numericAttr((useNode as { width?: unknown }).width) ?? symbolViewBox?.[2] ?? rootViewport[0];\n const useH = numericAttr((useNode as { height?: unknown }).height) ?? symbolViewBox?.[3] ?? rootViewport[1];\n\n // `<symbol>` is invisible unless instantiated by `<use>` — a bare clone\n // of it inside our wrapping `<g>` would render nothing. Rewrite the\n // clone-root `<symbol>` into a `<g>` carrying the symbol's viewBox-derived\n // transform + clip (mirroring the browser's `<use href=\"#symbol\">`\n // viewport mapping). Any clipPath defs created go into `defsCollector`.\n const rewrittenClone = clone.type === 'symbol'\n ? rewriteSymbolRootToGroup(clone, genId, defsCollector, useW, useH)\n : clone;\n\n // Recurse into the clone — any nested `<use>` it contains may itself\n // reference an animated subtree and need materialisation.\n const materialisedClone = walkAndMaterialise(rewrittenClone, idMap, animatedIds, genId, defsCollector, rootViewport);\n\n // Replace `<use>` with `<g>` wrapping the clone. Keep all of use's own\n // attrs except `href` (now meaningless). `<g>` has no `x`/`y`, so the use's\n // position offset is converted to a `translate(x,y)` (applied AFTER any\n // transform — see `applyUseOffsetToG`) rather than silently dropped.\n const newNode: PxNode = { ...useNode, type: 'g', children: [materialisedClone] };\n delete (newNode as { href?: string }).href;\n // The viewport-mapping `<g>` we just emitted on the clone root already\n // carries its own width/height-derived scale/translate. Drop the use's\n // own `width`/`height` so they don't appear on the outer `<g>` (where\n // they'd be ignored anyway — `<g>` has no width/height — but emitting\n // them as attributes would be misleading).\n delete (newNode as { width?: unknown }).width;\n delete (newNode as { height?: unknown }).height;\n return applyUseOffsetToG(newNode);\n}\n\n\n/** `<symbol>` doesn't render directly. To keep the visual result when a\n * cloned `<symbol>` lands as the root of a materialised `<use>` target, we\n * rewrite it into a `<g>` whose transform + clip mirror the browser's\n * `<use href=\"#symbol-with-viewBox\">` viewport mapping:\n *\n * - `transform = \"translate(xOff, yOff) scale(s) translate(-vbX, -vbY)\"`\n * where `s` and the centering offsets are derived from the symbol's\n * `viewBox` and the use's effective width/height per `preserveAspectRatio`\n * (default `xMidYMid meet`). Without the scale the clone renders at 1:1\n * in symbol coords, which doesn't match `<use>`'s natural behaviour.\n * - `clipPath = \"url(#<fresh-id>)\"` referencing a `<rect>` matching the\n * viewBox extent (in symbol coords). With the surrounding transform\n * above the clip rect maps to the visible viewport area, matching how\n * `<symbol>` viewport clipping works.\n *\n * Symbols without a `viewBox` rewrite to a plain `<g>` — no viewport\n * mapping to preserve.\n *\n * The created clipPath defs are appended to `defsCollector`; the caller\n * splices them into the root tree once materialisation finishes.\n */\nfunction rewriteSymbolRootToGroup(\n symbolNode: PxNode,\n genId: () => string,\n defsCollector: Array<PxNode>,\n useW: number,\n useH: number,\n): PxNode {\n const viewBox = parseViewBox((symbolNode as { viewBox?: unknown }).viewBox);\n const g: PxNode = { ...symbolNode, type: 'g' };\n // Strip symbol-only attributes that don't belong on `<g>`.\n delete (g as { viewBox?: unknown }).viewBox;\n delete (g as { preserveAspectRatio?: unknown }).preserveAspectRatio;\n delete (g as { width?: unknown }).width;\n delete (g as { height?: unknown }).height;\n\n if (!viewBox) return g; // no viewBox → no transform / clip required\n\n const [vbX, vbY, vbW, vbH] = viewBox;\n // `xMidYMid meet` (SVG default) — uniform scale, fit the longer axis;\n // center the shorter axis. Mirrors what the browser does on `<use>` for\n // a symbol-with-viewBox without an explicit preserveAspectRatio override.\n const scale = vbW > 0 && vbH > 0 ? Math.min(useW / vbW, useH / vbH) : 1;\n const xOff = (useW - vbW * scale) / 2;\n const yOff = (useH - vbH * scale) / 2;\n\n const parts: Array<string> = [];\n if (xOff !== 0 || yOff !== 0) parts.push('translate(' + xOff + ',' + yOff + ')');\n if (scale !== 1) parts.push('scale(' + scale + ')');\n if (vbX !== 0 || vbY !== 0) parts.push('translate(' + (-vbX) + ',' + (-vbY) + ')');\n if (parts.length) (g as { transform?: string }).transform = parts.join('');\n\n const clipId = genId();\n defsCollector.push({\n type: 'clipPath',\n id: clipId,\n children: [{ type: 'rect', x: vbX, y: vbY, width: vbW, height: vbH }],\n } as PxNode);\n (g as { clipPath?: string }).clipPath = 'url(#' + clipId + ')';\n return g;\n}\n\n\nfunction parseViewBox(v: unknown): [number, number, number, number] | undefined {\n if (typeof v !== 'string') return undefined;\n const parts = v.trim().split(/[\\s,]+/).map(Number);\n if (parts.length < 4 || parts.some(n => !Number.isFinite(n))) return undefined;\n return [parts[0], parts[1], parts[2], parts[3]];\n}\n\n\nfunction walkAndMaterialise(\n node: PxNode,\n idMap: Map<string, PxNode>,\n animatedIds: Set<string>,\n genId: () => string,\n defsCollector: Array<PxNode>,\n rootViewport: [number, number],\n): PxNode {\n if (node.type === 'use' && typeof node.href === 'string') {\n const targetId = stripHash(node.href);\n if (targetId && animatedIds.has(targetId)) {\n const target = idMap.get(targetId);\n if (target) return materialiseOneUse(node, target, idMap, animatedIds, genId, defsCollector, rootViewport);\n }\n }\n\n if (!node.children) return node;\n let changed = false;\n const newChildren = node.children.map(ch => {\n const m = walkAndMaterialise(ch, idMap, animatedIds, genId, defsCollector, rootViewport);\n if (m !== ch) changed = true;\n return m;\n });\n return changed ? { ...node, children: newChildren } : node;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\n/**\n * Helpers for reading animatable transform parts and shaping them into the\n * player's `PxTransformParts` records. Shared by the transformation and\n * masked-by effects (the latter builds INVERSE parts).\n */\n\nimport type { PxAnimatable, PxKeyframe, PxLoop, Vec2 } from '../PxAnimatorTypes';\nimport type { ApplyContext } from './types';\n\n\n/**\n * Names of the transform parts emitted into a `PxTransformParts` record. The\n * enum's STRING VALUES double as the wire-format object keys, so callers can\n * write `rec[TransformPart.Translate] = …` and produce `{translate: …}`.\n */\nexport enum TransformPart {\n Translate = 'translate',\n Rotate = 'rotate',\n Scale = 'scale',\n Skew = 'skew',\n Origin = 'origin',\n}\n\n\n/** Result kinds for `readAnimatable` — discriminator on `ReadPart<T>`. */\nexport enum ReadKind {\n Absent = 'absent',\n Static = 'static',\n Animated = 'animated',\n}\n\n\n/** Builds a player `PxTransformParts` record for one part (+ optional origin). */\nexport function partsRecord(part: TransformPart, value: any, origin: Vec2 | undefined) {\n const rec: { translate?: Vec2; rotate?: number; skew?: number; scale?: Vec2; origin?: Vec2 } = {};\n if (part === TransformPart.Translate) rec.translate = value;\n else if (part === TransformPart.Rotate) rec.rotate = value;\n else if (part === TransformPart.Skew) rec.skew = value;\n else rec.scale = value;\n if (origin && part !== TransformPart.Translate) rec.origin = origin;\n return rec;\n}\n\nexport type ReadPart<T> =\n | { kind: ReadKind.Absent }\n | { kind: ReadKind.Static; value: T }\n | { kind: ReadKind.Animated; keyframes: Array<PxKeyframe<T>>; autoOrient?: boolean; loop?: PxLoop | boolean };\n\n/** Normalises an animatable field into a static value or a keyframe list (with\n * `autoOrient` and `loop` propagated — the latter so timeline-level loop config\n * reaches the per-attribute `animate.X.loop` emitted by callers; without it,\n * effect-driven animations would silently ignore `loop.alternate`/cycle while\n * every non-effect property loops fine). */\nexport function readAnimatable<T>(raw: PxAnimatable<T> | undefined): ReadPart<T> {\n if (raw === undefined) return { kind: ReadKind.Absent };\n if (Array.isArray(raw)) return { kind: ReadKind.Static, value: raw as unknown as T };\n if (typeof raw === 'object') {\n const obj = raw as {\n value?: T; v?: T;\n keyframes?: Array<PxKeyframe<T>>; kfs?: Array<PxKeyframe<T>>;\n autoOrient?: boolean; loop?: PxLoop | boolean;\n };\n const kfs = obj.keyframes ?? obj.kfs;\n if (kfs) {\n // Normalise the wire's short aliases ONCE, here, so every consumer\n // downstream (transformation, repeater, …) only ever sees the long\n // form. Without this a keyframe authored `{t, v}` lost both its time\n // and its value and the animation silently froze at frame 0.\n return { kind: ReadKind.Animated, keyframes: kfs.map(normaliseKeyframe), autoOrient: obj.autoOrient, loop: obj.loop };\n }\n const staticValue = obj.value ?? obj.v;\n if (staticValue !== undefined) return { kind: ReadKind.Static, value: staticValue };\n }\n return { kind: ReadKind.Static, value: raw as T };\n}\n\n/** Rewrites a keyframe's short aliases (`t`/`v`/`e`/`to`/`ti`) to their long\n * names. Long names win when both are present, matching `PxMotionPath`'s\n * `tangentIn ?? ti` precedence. */\nfunction normaliseKeyframe<T>(kf: PxKeyframe<T>): PxKeyframe<T> {\n if (!kf || typeof kf !== 'object') return kf;\n const k = kf as PxKeyframe<T> & { t?: number; v?: T; e?: unknown; to?: Vec2; ti?: Vec2 };\n if (k.t === undefined && k.v === undefined && k.e === undefined && k.to === undefined && k.ti === undefined) {\n return kf; // already long-form — keep the same object\n }\n const out: any = { ...k };\n if (out.time === undefined && k.t !== undefined) out.time = k.t;\n if (out.value === undefined && k.v !== undefined) out.value = k.v;\n if (out.easing === undefined && k.e !== undefined) out.easing = k.e;\n if (out.tangentOut === undefined && k.to !== undefined) out.tangentOut = k.to;\n if (out.tangentIn === undefined && k.ti !== undefined) out.tangentIn = k.ti;\n return out as PxKeyframe<T>;\n}\n\n/** Origin used inside rotate/scale records. Animated origin falls back to frame 0. */\nexport function readStaticOrigin(raw: PxAnimatable<Vec2> | undefined, ctx: ApplyContext): Vec2 | undefined {\n const o = readAnimatable<Vec2>(raw);\n if (o.kind === ReadKind.Absent) return undefined;\n if (o.kind === ReadKind.Static) return o.value;\n ctx.warnings.push('transformation.origin: animated origin approximated by its first keyframe');\n return o.keyframes[0]?.value;\n}\n\n/** Copies a keyframe's time / easing / motion-path tangent handles onto a new parts-record value. */\nexport function keyframeWith(kf: PxKeyframe<any>, value: any): PxKeyframe<any> {\n const out: PxKeyframe<any> = { value };\n if (kf.time !== undefined) out.time = kf.time;\n if (kf.easing !== undefined) out.easing = kf.easing;\n if (kf.tangentOut !== undefined) out.tangentOut = kf.tangentOut;\n if (kf.tangentIn !== undefined) out.tangentIn = kf.tangentIn;\n return out;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\nimport { keyframeWith, partsRecord, ReadKind, readAnimatable, TransformPart } from './transformParts';\nimport type { PxAnimatable, PxNode, PxTransformationEffect, Vec2 } from '../PxAnimatorTypes';\nimport type { ApplyContext } from './types';\n\n\n/**\n * TRANSFORMATION → one `<g>` wrapper per part (translate/rotate/scale/skew),\n * with origin emitted as SEPARATE `+origin` / `-origin` wrappers flanking the\n * rotate/scale pair.\n *\n * Per-wrapper kfs:\n * - each wrapper carries ONE animatable quantity, so animated origin / rotate /\n * scale all play correctly per their own keyframe timelines — nothing is\n * baked into another part's wrapper.\n * - the `+o · ... · -o` sandwich pivots rotate+scale around the (possibly\n * animated) origin; translates compose flat (commute).\n *\n * Wrapper nesting (outer → inner):\n *\n * translate → +origin → rotate → scale → -origin → skew → element\n *\n * Composition: `M = translate(t) · +origin(t) · rotate(t) · scale(t) · -origin(t) · skew`\n * (skew is appended innermost and not composed here).\n */\nexport function applyTransformationEffect(node: PxNode, fx: PxTransformationEffect | undefined, ctx: ApplyContext): PxNode {\n if (!fx) return node;\n\n // The element's own `transform` string is the frame-0 baseline; wrappers\n // carry the full (animated) transform, so the baseline is dropped.\n delete node.transform;\n\n // Innermost first. Order outer→inner: [+o, t, -o, +o, r, skew, s, -o] for\n // auto-orient (translate carries motion-path rotation that must pivot around\n // origin too), else [t, +o, r, skew, s, -o] (translate composes flat).\n // Skew sits BETWEEN rotate and scale, inside the origin sandwich — the canonical\n // slot shared with the unified body transform and Lottie (see skew-support.plan.md).\n let n = node;\n n = wrapOrigin(n, fx.origin, /*invert=*/true); // -origin (r/k/s sandwich)\n n = wrapTransformPart(n, TransformPart.Scale, normalizeScale(fx.scale), ctx);\n n = wrapTransformPart(n, TransformPart.Skew, fx.skew, ctx);\n n = wrapTransformPart(n, TransformPart.Rotate, fx.rotate, ctx);\n n = wrapOrigin(n, fx.origin, /*invert=*/false); // +origin (r/k/s sandwich)\n\n if (translateHasAutoOrient(fx.translate)) {\n // Sandwich translate with its own +o/-o so the motion-path tangent\n // rotation built into the translate wrapper pivots around origin\n // (the `[+o, t_path_ao, -o]` branch).\n n = wrapOrigin(n, fx.origin, /*invert=*/true); // -origin (translate sandwich)\n n = wrapTransformPart(n, TransformPart.Translate, fx.translate, ctx);\n n = wrapOrigin(n, fx.origin, /*invert=*/false); // +origin (translate sandwich)\n } else {\n n = wrapTransformPart(n, TransformPart.Translate, fx.translate, ctx);\n }\n return n;\n}\n\n/** True when the translate animation carries motion-path tangent handles or\n * `autoOrient` — the path-tangent rotation needs origin-sandwich to pivot. */\nfunction translateHasAutoOrient(translate: PxAnimatable<Vec2> | undefined): boolean {\n if (!translate || typeof translate !== 'object') return false;\n const obj = translate as { autoOrient?: boolean; keyframes?: Array<{ tangentOut?: Vec2; tangentIn?: Vec2 }> };\n if (obj.autoOrient) return true;\n return Array.isArray(obj.keyframes) && obj.keyframes.some(kf => kf.tangentOut || kf.tangentIn);\n}\n\n/**\n * The wire `effects.transformation.scale` emits **percent units** (150 = 150%)\n * for the bare-array static form, but emits **1.0-units** (1.5 = 150%) inside\n * `{keyframes: [...]}` (matching the body `transform` baseline). The bare-array\n * form is the one we have to convert.\n */\nfunction normalizeScale(raw: PxAnimatable<Vec2> | undefined): PxAnimatable<Vec2> | undefined {\n if (raw === undefined) return undefined;\n if (Array.isArray(raw)) return [raw[0] / 100, raw[1] / 100] as Vec2;\n return raw;\n}\n\n/** Wraps `inner` in a `<g>` carrying a single transform part, static or animated. */\nfunction wrapTransformPart(\n inner: PxNode, part: TransformPart,\n raw: PxAnimatable<any> | undefined, ctx: ApplyContext\n): PxNode {\n if (raw === undefined) return inner;\n\n const v = readAnimatable<any>(raw);\n if (v.kind === ReadKind.Static) {\n return { type: 'g', transform: { value: partsRecord(part, v.value, undefined) }, children: [inner] };\n }\n if (v.kind === ReadKind.Animated) {\n const animTr: any = { keyframes: v.keyframes.map(kf => keyframeWith(kf, partsRecord(part, kf.value, undefined))) };\n if (v.autoOrient) animTr.autoOrient = true;\n if (v.loop !== undefined) animTr.loop = v.loop;\n return {\n type: 'g',\n animate: { transform: animTr },\n children: [inner],\n };\n }\n return inner;\n}\n\n/**\n * Wraps `inner` in a `<g translate>` that shifts by `+origin` (invert=false) or\n * `-origin` (invert=true). Origin is animatable — keyframes are carried through.\n *\n * Emitted as a `{translate}` PartsRecord (not the `{origin}` field) so a `+o`\n * wrapper is just a plain translate in the walker's eyes: the walker composes\n * the origin-sandwich rotation/scale around origin by stacking the wrappers,\n * NOT by reading `origin` off the rotate/scale wrapper's parts record.\n */\nfunction wrapOrigin(inner: PxNode, raw: PxAnimatable<Vec2> | undefined, invert: boolean): PxNode {\n if (raw === undefined) return inner;\n const v = readAnimatable<Vec2>(raw);\n const sign = (value: Vec2): Vec2 => invert ? [-value[0], -value[1]] : value;\n\n if (v.kind === ReadKind.Absent) return inner;\n if (v.kind === ReadKind.Static) {\n if (v.value[0] === 0 && v.value[1] === 0) return inner; // identity — skip\n return { type: 'g', transform: { value: { translate: sign(v.value) } }, children: [inner] };\n }\n if (v.kind === ReadKind.Animated) {\n const animTr: any = { keyframes: v.keyframes.map(kf => keyframeWith(kf, { translate: sign(kf.value as Vec2) })) };\n if (v.loop !== undefined) animTr.loop = v.loop;\n return {\n type: 'g',\n animate: { transform: animTr },\n children: [inner],\n };\n }\n return inner;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\n/**\n * CONTENT-REF SOURCE SPLIT.\n *\n * When a `<use>` references another element with `ref:{type:'content'}` it wants\n * to render the source EXCLUDING the source's own translate (and along-path\n * positioning for auto-orient). The heavy form achieves this by materialising the\n * source as a wrapper tree\n *\n * <g translate> ← outer, holds translate (+ along-path/origin for autoOrient)\n * <g rotate scale +o-o> ← inner, holds rotate/scale (origin sandwich)\n * <element /> ← bare shape, no transform\n * </g>\n * </g>\n *\n * and points the `<use>` at the INNER `<g>`. The use's reference therefore\n * renders rotate/scale around the use's position — never the source's translate.\n *\n * In the lightweight format the source is emitted as a flat element (translate\n * baked onto the body or into `effects.transformation`). The applier's\n * `splitForContentRef` re-creates the multi-layer structure on the fly:\n * 1. extract translate parts from the source body (`transform` string,\n * `animate.transform.keyframes` PartsRecord) and from\n * `effects.transformation` → outer wrapper\n * 2. keep rotate / scale (with origin sandwich) on the inner wrapper\n * 3. assign the ORIGINAL id to the outer, a fresh id to the inner\n * 4. `applyRefAndTransformationEffect` then rewrites the use's `href`\n * to the inner id (see `ctx.contentRefInnerIds`).\n *\n * Auto-orient / motion-path: when the translate animation carries tangent\n * handles (`tangentOut`/`tangentIn`) or `autoOrient`, the path tangent produces\n * a rotation at the OUTER level — so the origin moves to the outer too, so the\n * tangent rotation pivots around it (the `[+o, t_path_ao, -o]` branch).\n *\n * \"Always-split\" simplicity: even when a layer would be empty (e.g. source has\n * no rotate/scale), the inner wrapper is still emitted as an identity `<g>`.\n * The use needs a stable target regardless of which transform parts the source\n * carries, and an extra empty `<g>` is render-neutral.\n */\n\nimport { applyTransformationEffect } from './transformationEffect';\nimport type { PxAnimatable, PxAnimationDefinition, PxKeyframe, PxNode, PxTransformationEffect, Vec2 } from '../PxAnimatorTypes';\nimport type { ApplyContext } from './types';\n\n\n/** Walks the tree and collects every id referenced by a `<use>` with `ref:{type:'content'}`. */\nexport function identifyContentRefTargets(node: PxNode, ctx: ApplyContext, allocator: (key: string) => string): void {\n if (node.type === 'use' && node.effects?.clone?.type === 'content') {\n const baseId = node.effects.clone.baseId;\n if (typeof baseId === 'string' && baseId && !ctx.contentRefInnerIds.has(baseId)) {\n ctx.contentRefInnerIds.set(baseId, allocator(baseId));\n }\n }\n node.children?.forEach(c => identifyContentRefTargets(c, ctx, allocator));\n}\n\n\n/**\n * Splits `node` into outer-translate + inner-rest + bare element. `node` is\n * mutated in place: its body translate is moved to the outer wrapper, leaving\n * the rotate/scale parts (and the element body) inside the inner wrapper.\n *\n * Outer wrapper gets `originalId` (so `idMap` and whole-element refs still\n * resolve correctly). Inner wrapper gets `innerId` (the use's `ref:content`\n * target). The returned node is the OUTER wrapper.\n */\nexport function splitForContentRef(\n node: PxNode,\n transformation: PxTransformationEffect | undefined,\n originalId: string,\n innerId: string,\n ctx: ApplyContext,\n): PxNode {\n\n // 1. Lift translate parts off the body (`transform` string + `animate.transform`)\n // onto a fresh outer-side bag. After this, `node` no longer carries them.\n // `transformation` is passed in so that when its `translate` part will go to\n // the outer wrapper, the body's baked-in translate baseline is stripped too\n // (otherwise it'd double-up against the outer wrapper's first keyframe).\n const outerBody = liftBodyTranslate(node, transformation);\n\n // Strip the bare element's `id` — the outer wrapper takes ownership of `originalId`,\n // and the inner wrapper carries `innerId`. The element itself doesn't need either;\n // leaving it would create a duplicate of `originalId` in the materialised tree.\n if (typeof node.id === 'string') delete node.id;\n\n // 2. Split `effects.transformation` between outer (translate, plus origin for\n // auto-orient/motion-path) and inner (rotate / scale, with origin sandwich).\n const { outer: outerTr, inner: innerTr } = splitTransformationEffect(transformation);\n\n // 3. Inner: apply inner transformation around the original element, then wrap\n // in an identity `<g>` with `innerId`. The extra wrapper guarantees the use\n // has a stable target regardless of what parts were present.\n let innerNode: PxNode = node;\n innerNode = applyTransformationEffect(innerNode, innerTr, ctx);\n const innerWrapper: PxNode = { type: 'g', id: innerId, children: [innerNode] };\n\n // 4. Outer: build a `<g>` carrying the lifted body translate, with `innerWrapper`\n // as its child. Then apply outer transformation (translate). Move id to the\n // outermost so whole-element refs still resolve to the full source.\n let outerWrapper: PxNode = { type: 'g', id: originalId, children: [innerWrapper] };\n if (outerBody.transform !== undefined) outerWrapper.transform = outerBody.transform;\n if (outerBody.animate !== undefined) outerWrapper.animate = outerBody.animate;\n if (outerTr) {\n delete outerWrapper.id;\n outerWrapper = applyTransformationEffect(outerWrapper, outerTr, ctx);\n outerWrapper.id = originalId;\n }\n return outerWrapper;\n}\n\n\n////////////////////////////////////////////////////////////////\n//// Body lifting (transform string + animate.transform)\n////////////////////////////////////////////////////////////////\n\ninterface OuterBody {\n transform?: string | { value?: any; keyframes?: Array<any> };\n animate?: { transform: any };\n}\n\n/** Removes translate parts from `node.transform` (string) and from `node.animate.transform`,\n * returning what was extracted (to live on the outer wrapper). When either\n * animate.transform is lifted OR `effects.transformation.translate` will be lifted\n * via the outer wrapper, the body `transform` translate becomes a redundant t=0\n * baseline and is stripped from `node` (otherwise it'd compose on top of the\n * outer's first keyframe / static translate). */\nfunction liftBodyTranslate(node: PxNode, transformation: PxTransformationEffect | undefined): OuterBody {\n const out: OuterBody = {};\n\n // 1. animate.transform — extract translate from every keyframe value.\n // `autoOrient` and `tangentOut`/`tangentIn` are motion-path metadata that\n // belong to translate; they go to the OUTER wrapper with translate, never\n // to the inner one (the inner has rotate/scale only).\n let didLiftAnimate = false;\n // In-place animations on a node body are always the record form\n // (`{propName: PxPropertyAnimation}`) at this point in the pipeline —\n // narrow the `PxElementAnimation` union accordingly.\n const animTr = (node.animate as PxAnimationDefinition | undefined)?.transform;\n if (animTr && typeof animTr === 'object' && Array.isArray(animTr.keyframes)) {\n const kfs: Array<PxKeyframe<any>> = animTr.keyframes;\n const hasTranslate = kfs.some(kf => kf.value && (kf.value as any).translate);\n if (hasTranslate) {\n const outerHasOrigin = needsOriginOnOuter(animTr as PxAnimatable<Vec2>);\n const outerKfs = kfs.map(kf => {\n const v = (kf.value || {}) as any;\n const newValue: any = {};\n if (v.translate !== undefined) newValue.translate = v.translate;\n if (outerHasOrigin && v.origin !== undefined) newValue.origin = v.origin;\n const outerKf: any = { value: newValue };\n if (kf.time !== undefined) outerKf.time = kf.time;\n if (kf.easing !== undefined) outerKf.easing = kf.easing;\n if ((kf as any).tangentOut !== undefined) outerKf.tangentOut = (kf as any).tangentOut;\n if ((kf as any).tangentIn !== undefined) outerKf.tangentIn = (kf as any).tangentIn;\n return outerKf;\n });\n const outerAnimTr: any = { keyframes: outerKfs };\n if ((animTr as any).autoOrient) outerAnimTr.autoOrient = true;\n // Forward `loop` so the split outer/inner halves keep the source\n // alternate/cycle semantics; otherwise lifting a transform with\n // `loop.alternate` silently drops the loop on translate side.\n const srcLoop = (animTr as any).loop;\n if (srcLoop !== undefined) outerAnimTr.loop = srcLoop;\n out.animate = { transform: outerAnimTr };\n\n const innerHasPivotedPart = kfs.some(kf => {\n const v = (kf.value || {}) as any;\n return v.rotate !== undefined || v.scale !== undefined;\n });\n const innerKfs = kfs.map(kf => {\n const v = (kf.value || {}) as any;\n const newValue: any = {};\n if (v.rotate !== undefined) newValue.rotate = v.rotate;\n if (v.scale !== undefined) newValue.scale = v.scale;\n // Origin lives on inner kfs whenever rotate/scale need a pivot —\n // a separate origin sandwich at the inner layer (even when origin\n // is also on outer for the auto-orient sandwich).\n if (v.origin !== undefined && (!outerHasOrigin || innerHasPivotedPart)) newValue.origin = v.origin;\n // Inner kf intentionally drops tangentOut/tangentIn (translate-only).\n const innerKf: any = { value: newValue };\n if (kf.time !== undefined) innerKf.time = kf.time;\n if (kf.easing !== undefined) innerKf.easing = kf.easing;\n return innerKf;\n });\n const allInnerEmpty = innerKfs.every(kf => Object.keys(kf.value as object).length === 0);\n if (allInnerEmpty) {\n delete (node.animate as any).transform;\n if (node.animate && Object.keys(node.animate).length === 0) delete node.animate;\n } else {\n // Inner animate keeps non-translate kfs; autoOrient flag is intentionally dropped.\n // `loop` is forwarded so the inner rotate/scale half also alternates/cycles.\n const innerAnimTr: any = { keyframes: innerKfs };\n if (srcLoop !== undefined) innerAnimTr.loop = srcLoop;\n (node.animate as any).transform = innerAnimTr;\n }\n didLiftAnimate = true;\n }\n }\n\n // 2. Body `transform` — only the string form carries baked translates. Object\n // forms ({value}/{keyframes}) come from the writer's transformation-effect\n // path and are handled via `effects.transformation`, not the body.\n const transformationHasTranslate = transformation?.translate !== undefined;\n const stripBodyTranslateOnly = didLiftAnimate || transformationHasTranslate;\n // Autoorient / motion-path lift: when the lifted animate.transform carries\n // tangents or `autoOrient`, the body baseline is the FULL t=0 matrix\n // (translate × path-tangent rotation), not just a translate. The outer\n // wrapper recomputes both at every frame (including t=0) via the lifted\n // keyframes + autoOrient, so the body baseline is redundant and would\n // double-apply on top of it.\n const liftedAnimateIsAutoOriented = didLiftAnimate && needsOriginOnOuter((node.animate as PxAnimationDefinition | undefined)?.transform as any || undefined)\n || didLiftAnimate && needsOriginOnOuter((out.animate as PxAnimationDefinition | undefined)?.transform as any || undefined);\n if (typeof node.transform === 'string') {\n const split = splitTransformString(node.transform);\n if (stripBodyTranslateOnly) {\n // Outer wrapper will carry the translate (via animate.transform or\n // effects.transformation); the body string is just a t=0 baseline.\n // Strip body translates so they don't double-up.\n if (split.translate !== undefined) {\n if (split.rest) node.transform = split.rest;\n else delete node.transform;\n } else if (isPureTranslateBody(node.transform)) {\n // Body is a single `matrix(...)` representing pure translate — same\n // redundancy as a `translate(...)` string. Wipe.\n delete node.transform;\n } else if (liftedAnimateIsAutoOriented && isSingleMatrixBody(node.transform)) {\n // Body is a non-pure `matrix(…)` — the autoOrient-materialised t=0\n // value baked by the writer. The outer wrapper reproduces it via\n // `animate.transform` + `autoOrient`; wipe to avoid double-apply.\n delete node.transform;\n }\n } else if (split.translate) {\n out.transform = split.translate;\n if (split.rest) node.transform = split.rest;\n else delete node.transform;\n }\n }\n\n return out;\n}\n\n/** True when the body string is a single `matrix(...)` op (any 6-arg matrix —\n * pure-translate is a more specific case handled by `isPureTranslateBody`). */\nfunction isSingleMatrixBody(s: string): boolean {\n const re = /(translate|rotate|scale|matrix|skewX|skewY)\\(([^)]*)\\)/g;\n let count = 0;\n let isMatrix = false;\n let m: RegExpExecArray | null;\n while ((m = re.exec(s))) {\n count++;\n if (m[1] === 'matrix') isMatrix = true;\n }\n return count === 1 && isMatrix;\n}\n\n/** True when the body transform is a single op equivalent to pure translate\n * (either `translate(...)` or a `matrix(1,0,0,1,e,f)`). Used to decide whether\n * to wipe the body when `animate.transform.translate` has already been lifted. */\nfunction isPureTranslateBody(s: string): boolean {\n const re = /(translate|rotate|scale|matrix|skewX|skewY)\\(([^)]*)\\)/g;\n const ops: Array<{ name: string; full: string }> = [];\n let m: RegExpExecArray | null;\n while ((m = re.exec(s))) ops.push({ name: m[1], full: m[0] });\n if (ops.length !== 1) return false;\n if (ops[0].name === 'translate') return true;\n if (ops[0].name !== 'matrix') return false;\n const args = /matrix\\(([^)]*)\\)/.exec(ops[0].full);\n if (!args) return false;\n const nums = args[1].split(/[\\s,]+/).filter(Boolean).map(Number);\n return nums.length >= 4 && nums[0] === 1 && nums[1] === 0 && nums[2] === 0 && nums[3] === 1;\n}\n\n/**\n * Body-string lift heuristic. The body `transform=\"\"` is the t=0 baseline that\n * the WRITER bakes in the canonical order `translate · +origin · rotate · scale · -origin`.\n *\n * Lift LEADING `translate(...)` ops ONLY when the string does NOT end with a\n * `translate(...)`. A trailing translate is the `-origin` half of an origin\n * sandwich — leaving any translate inside the sandwich would break the pivot,\n * so we leave the whole body alone in that case (the corresponding\n * `effects.transformation` is the structured source we lift from instead).\n *\n * (`matrix(...)` and `skewX/Y` are not lifted — they don't carry \"user\n * translate\" semantics. If the leading op isn't `translate`, nothing is lifted.)\n */\nfunction splitTransformString(s: string): { translate?: string; rest?: string } {\n const ops: Array<{ name: string; full: string }> = [];\n const re = /(translate|rotate|scale|matrix|skewX|skewY)\\(([^)]*)\\)/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(s))) ops.push({ name: m[1], full: m[0] });\n\n if (!ops.length) return { rest: s || undefined };\n\n // All-translate string — no origin-sandwich without rotate/scale in the\n // middle. Lift everything.\n if (ops.every(o => o.name === 'translate')) {\n return { translate: ops.map(o => o.full).join('') };\n }\n\n const leading = ops[0];\n const trailing = ops[ops.length - 1];\n\n // Origin sandwich: writer's canonical order is `translate · +origin ·\n // rotate · scale · -origin`, with `translate + +origin` typically FUSED\n // into one leading translate. We can recover the user-translate by reading\n // the trailing `-origin` value and subtracting `+origin` from the leading.\n if (trailing.name === 'translate' && leading.name === 'translate') {\n const trailingVec = parseTranslateArgs(trailing.full);\n const leadingVec = parseTranslateArgs(leading.full);\n const ox = -trailingVec[0]; // -origin → +origin\n const oy = -trailingVec[1];\n const userTx = leadingVec[0] - ox;\n const userTy = leadingVec[1] - oy;\n\n // Pure origin sandwich (user-translate cancels to 0) — leave the body alone.\n if (userTx === 0 && userTy === 0) return { rest: s };\n\n // Replace the leading translate with the bare `+origin` (=ox,oy), keep\n // the rest of the sandwich unchanged, and lift `translate(userT)`.\n const middleAndTrailing = 'translate(' + ox + ',' + oy + ')' + ops.slice(1).map(o => o.full).join('');\n return { translate: 'translate(' + userTx + ',' + userTy + ')', rest: middleAndTrailing };\n }\n\n // Trailing translate without a matching leading translate — unusual. Be\n // conservative and don't lift.\n if (trailing.name === 'translate') return { rest: s };\n\n // No trailing translate → no origin sandwich; lift all leading translates.\n const lifted: Array<string> = [];\n let i = 0;\n while (i < ops.length && ops[i].name === 'translate') {\n lifted.push(ops[i].full);\n i++;\n }\n if (!lifted.length) return { rest: s };\n\n const rest = ops.slice(i).map(o => o.full).join('');\n return {\n translate: lifted.join(''),\n rest: rest || undefined,\n };\n}\n\nfunction parseTranslateArgs(translateOp: string): [number, number] {\n const m = /translate\\(([^)]*)\\)/.exec(translateOp);\n if (!m) return [0, 0];\n const nums = m[1].split(/[\\s,]+/).filter(Boolean).map(Number);\n return [nums[0] || 0, nums[1] || 0];\n}\n\n\n////////////////////////////////////////////////////////////////\n//// effects.transformation split\n////////////////////////////////////////////////////////////////\n\nfunction splitTransformationEffect(fx: PxTransformationEffect | undefined): {\n outer?: PxTransformationEffect;\n inner?: PxTransformationEffect;\n} {\n if (!fx) return {};\n const originOnOuter = needsOriginOnOuter(fx.translate);\n const innerHasPivotedPart = fx.rotate !== undefined || fx.scale !== undefined;\n\n const outer: PxTransformationEffect = {};\n const inner: PxTransformationEffect = {};\n\n if (fx.translate !== undefined) outer.translate = fx.translate;\n // Origin lives on outer when translate carries auto-orient (so the\n // path-tangent rotation pivots around origin too).\n if (originOnOuter && fx.origin !== undefined) outer.origin = fx.origin;\n\n if (fx.rotate !== undefined) inner.rotate = fx.rotate;\n if (fx.scale !== undefined) inner.scale = fx.scale;\n if (fx.skew !== undefined) inner.skew = fx.skew;\n // Origin also lives on inner whenever rotate/scale need a pivot — duplicate\n // origin across outer + inner is fine: two separate origin sandwiches\n // ([+o, t, -o] outer + [+o, r, s, -o] inner).\n if (fx.origin !== undefined && (!originOnOuter || innerHasPivotedPart)) inner.origin = fx.origin;\n\n return {\n outer: Object.keys(outer).length ? outer : undefined,\n inner: Object.keys(inner).length ? inner : undefined,\n };\n}\n\n\n////////////////////////////////////////////////////////////////\n//// Auto-orient / motion-path detection\n////////////////////////////////////////////////////////////////\n\n/** True when the translate animation produces rotation at the outer level\n * (tangent handles or `autoOrient`) — meaning origin must sit on the outer\n * with translate so the path-tangent rotation pivots around it. */\nfunction needsOriginOnOuter(translateAnim: PxAnimatable<Vec2> | undefined): boolean {\n if (!translateAnim || typeof translateAnim !== 'object') return false;\n const obj = translateAnim as { autoOrient?: boolean; keyframes?: Array<PxKeyframe<Vec2> & { tangentOut?: Vec2; tangentIn?: Vec2 }> };\n if (obj.autoOrient) return true;\n if (Array.isArray(obj.keyframes)) {\n return obj.keyframes.some(kf => kf.tangentOut || kf.tangentIn);\n }\n return false;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\n/** Generic, effect-agnostic helpers for the player-effects applier. */\n\nimport { deepClonePxNode, regenerateIdsAndRewriteRefs } from '../PxNodeCloneUtil';\nimport type { PxNode, Vec2 } from '../PxAnimatorTypes';\nimport type { ApplyContext } from './types';\n\n/** Mints a deterministic id for a generated node (`<mask>`, retimed `<symbol>`, …). */\nexport function genId(ctx: ApplyContext, prefix: string): string {\n return '_lw_' + prefix + '_' + (ctx.nextId++);\n}\n\nexport function stripHash(href: any): string | undefined {\n return typeof href === 'string' ? href.replace(/^#/, '') : undefined;\n}\n\n/** Reads the leading `translate(x,y)` from an SVG transform string. */\nexport function readTranslateFromTransform(transform: any): Vec2 | undefined {\n if (typeof transform !== 'string') return undefined;\n const m = transform.match(/translate\\(\\s*(-?[\\d.]+)\\s*,\\s*(-?[\\d.]+)\\s*\\)/);\n return m ? [Number(m[1]), Number(m[2])] : undefined;\n}\n\n/** Records every node carrying an `id` into the lookup map. */\nexport function indexById(node: PxNode, map: Map<string, PxNode>): void {\n if (typeof node.id === 'string') map.set(node.id, node);\n node.children?.forEach(child => indexById(child, map));\n}\n\n/** Inserts generated <defs> nodes at the front of the root's children. */\nexport function spliceDefs(root: PxNode, defs: Array<PxNode>): void {\n if (!defs.length) return;\n const existing = root.children || (root.children = []);\n existing.unshift({ type: 'defs', children: defs });\n}\n\n/** Deep-clone a `PxNode` subtree. Thin wrapper around the shared\n * {@link deepClonePxNode}; retained as `clone` for the existing call sites. */\nexport const clone = deepClonePxNode;\n\n/**\n * Regenerates every `id` inside `root` (root included) using `genId(ctx, 'retimed')`\n * and rewrites internal `href=\"#X\"` / `url(#X)` refs. Thin wrapper around the\n * shared {@link regenerateIdsAndRewriteRefs}; encapsulates the retime-specific\n * id-prefix convention so retime call sites stay unchanged.\n */\nexport function regenerateIdsInClone(root: PxNode, ctx: ApplyContext): Map<string, string> {\n return regenerateIdsAndRewriteRefs(root, () => genId(ctx, 'retimed'));\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\nimport type { PxAnimatable, PxFillGradientEffect, PxGradientStop, PxKeyframe, PxLoop, PxNode, PxStrokeGradientEffect } from '../PxAnimatorTypes';\nimport { PxGradientType } from '../PxAnimatorTypes';\nimport type { ApplyContext } from './types';\nimport { genId } from './util';\n\n\n/**\n * `effects.fillGradient` / `effects.strokeGradient` materialiser.\n *\n * Mirrors `maskedByEffect`: mint a `<linearGradient>` or `<radialGradient>`\n * def into `ctx.defs`, push the host element's `fill` / `stroke` to\n * `url(#auto-id)`. Same shape used for both fill and stroke — the only\n * difference is which host attribute is rewritten.\n *\n * The wire shape is a gradient as one animatable stop timeline + static geometry\n * (see `_PxFillGradientEffect`). When materialising:\n * - geometry parts (`p1`, `p2`, `c`, `r`, `fp`) become static body attrs\n * on the gradient def;\n * - the stops array is either static (each `<stop>` is bare) or animated\n * (each `<stop>` gets `animate.stopColor.keyframes` derived from the\n * single source timeline by SLICING each kf's full snapshot at this\n * stop's index).\n *\n * The per-stop slicing produces the standard `<linearGradient>` + `<stop>`\n * def chain, so the materialised tree round-trips through the usual reader.\n */\nexport function applyFillGradientEffect(node: PxNode, fx: PxFillGradientEffect | undefined, ctx: ApplyContext): PxNode {\n return applyGradient(node, fx, ctx, 'fill');\n}\n\nexport function applyStrokeGradientEffect(node: PxNode, fx: PxStrokeGradientEffect | undefined, ctx: ApplyContext): PxNode {\n return applyGradient(node, fx, ctx, 'stroke');\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Internals\n// ─────────────────────────────────────────────────────────────────────────────\n\nfunction applyGradient(node: PxNode, fx: PxFillGradientEffect | undefined, ctx: ApplyContext, attr: 'fill' | 'stroke'): PxNode {\n if (!fx) return node;\n\n const id = genId(ctx, 'grad');\n const def = synthesiseGradientDef(fx, id, ctx);\n ctx.defs.push(def);\n node[attr] = 'url(#' + id + ')';\n return node;\n}\n\nfunction synthesiseGradientDef(fx: PxFillGradientEffect, id: string, ctx: ApplyContext): PxNode {\n const out: PxNode = {\n type: fx.type === PxGradientType.radial ? 'radialGradient' : 'linearGradient',\n id,\n };\n\n // Geometry — static base values…\n if (fx.type === PxGradientType.linear) {\n if (fx.p1) { out.x1 = String(fx.p1[0]); out.y1 = String(fx.p1[1]); }\n if (fx.p2) { out.x2 = String(fx.p2[0]); out.y2 = String(fx.p2[1]); }\n } else {\n if (fx.c) { out.cx = String(fx.c[0]); out.cy = String(fx.c[1]); }\n if (fx.r !== undefined) out.r = String(fx.r);\n if (fx.fp) { out.fx = String(fx.fp[0]); out.fy = String(fx.fp[1]); }\n }\n if (fx.gradientUnits) out.gradientUnits = fx.gradientUnits;\n if (fx.spreadMethod) out.spreadMethod = fx.spreadMethod;\n if (fx.gradientTransform) out.gradientTransform = fx.gradientTransform;\n\n // …plus ANIMATED geometry: the wire carries per-channel keyframes under\n // `fx.animate` (`gradientX1`, `gradientFy`, …). Map them onto the def node's own\n // `animate` under the real SVG attr names — the frames engine then drives the def's\n // attrs exactly like it drives the stops' `stopColor` (CSS/WAAPI can't, but this\n // materialiser feeds the JS frame loop).\n type ElementAnim = NonNullable<PxNode['animate']>;\n const animate = (fx as { animate?: ElementAnim }).animate;\n if (animate) {\n const mapped: ElementAnim = {};\n for (const wireKey of Object.keys(animate)) {\n const attr = GRADIENT_ANIM_CHANNEL_TO_ATTR[wireKey];\n if (attr) mapped[attr] = animate[wireKey];\n }\n if (Object.keys(mapped).length) out.animate = mapped;\n }\n\n out.children = buildStopChildren(fx.stops, ctx);\n return out;\n}\n\n/** Wire `fx.animate` channel → the SVG gradient-def attribute it drives. */\nconst GRADIENT_ANIM_CHANNEL_TO_ATTR: Record<string, string> = {\n gradientX1: 'x1', gradientY1: 'y1', gradientX2: 'x2', gradientY2: 'y2',\n gradientCx: 'cx', gradientCy: 'cy', gradientFx: 'fx', gradientFy: 'fy', gradientR: 'r',\n};\n\n/** Emits one `<stop>` per gradient stop. Stops come from EITHER the static\n * array form (`stops: [{offset, color}, …]`) or the animated form\n * (`stops: {keyframes:[{time, value:[stops], easing?}]}`). For the\n * animated form, each emitted `<stop>` gets `animate.stopColor.keyframes`\n * whose values are sliced out of the source timeline at this stop's\n * index — the standard `<stop>` def chain. */\nfunction buildStopChildren(stops: PxAnimatable<Array<PxGradientStop>> | undefined, ctx: ApplyContext): Array<PxNode> {\n if (!stops) return [];\n\n // Static shapes — bare array or `{value: […]}`.\n if (Array.isArray(stops)) return stops.map(staticStopNode);\n if (typeof stops === 'object' && Array.isArray((stops as { value?: any }).value)) {\n return (stops as { value: Array<PxGradientStop> }).value.map(staticStopNode);\n }\n\n // Animated — `{keyframes: [{time, value: [stops], easing?}], loop?, ...}`.\n const animBlock = stops as { keyframes?: Array<PxKeyframe>, loop?: PxLoop | boolean };\n const kfs = animBlock.keyframes;\n if (!Array.isArray(kfs) || !kfs.length) return [];\n // Per-stop animations inherit the timeline-level `loop` (alternate/cycle/etc.).\n // Without forwarding it, animating a gradient with `loop.alternate:true`\n // would slice each stop's colours into separate `animate.stopColor`\n // entries that lose the loop config → no reversal past the last kf,\n // even though every non-gradient animatable property loops fine. See\n // also: the gradient stop \"slice\" docstring above.\n const loopFromSource = animBlock.loop;\n\n // Stop count: take the LARGEST across kfs (constraint says constant\n // count, but defensive — when missing, hold the last value).\n let stopCount = 0;\n for (const kf of kfs) {\n const v = (kf.value ?? kf.v) as Array<PxGradientStop> | undefined;\n if (Array.isArray(v) && v.length > stopCount) stopCount = v.length;\n }\n if (!stopCount) return [];\n\n // Baseline stop info from kf[0] — offsets stay fixed across kfs, only\n // colours animate; offset rarely animates but if it does we sample at\n // each kf.\n const firstKfValue = (kfs[0].value ?? kfs[0].v) as Array<PxGradientStop> | undefined;\n const baselineStops: Array<PxGradientStop> = [];\n for (let i = 0; i < stopCount; i++) {\n const s = firstKfValue?.[i] ?? prevDefinedStop(kfs, 0, i) ?? { offset: i / Math.max(1, stopCount - 1), color: '#000000' };\n baselineStops.push({ offset: s.offset, color: s.color });\n }\n\n return baselineStops.map((bs, i) => animatedStopNode(bs, kfs, i, ctx, loopFromSource));\n}\n\nfunction staticStopNode(s: PxGradientStop): PxNode {\n return {\n type: 'stop',\n offset: formatOffset(s.offset),\n stopColor: s.color,\n };\n}\n\nfunction animatedStopNode(baseline: PxGradientStop, kfs: Array<PxKeyframe>, stopIdx: number, _ctx: ApplyContext, loop: PxLoop | boolean | undefined): PxNode {\n const colorKfs: Array<PxKeyframe> = [];\n const offsetKfs: Array<PxKeyframe> = [];\n // Only emit an `offset` timeline when the offset actually moves across\n // kfs — most gradients animate colour only, and a static offset attr is\n // cheaper than a runtime binding that recomputes the same value.\n let offsetVaries = false;\n for (const kf of kfs) {\n const t = kf.time ?? kf.t ?? 0;\n const arr = (kf.value ?? kf.v) as Array<PxGradientStop> | undefined;\n const sliced = arr?.[stopIdx] ?? prevDefinedStop(kfs, kfs.indexOf(kf), stopIdx);\n if (!sliced) continue;\n const easing = kf.easing ?? kf.e;\n\n const colorOut: PxKeyframe = { time: t, value: sliced.color };\n if (easing !== undefined) colorOut.easing = easing;\n colorKfs.push(colorOut);\n\n // Offset is a unitless 0..1 fraction (SVG `<stop offset>` accepts it\n // bare); the runtime interpolates it as a numeric attr.\n const offsetOut: PxKeyframe = { time: t, value: sliced.offset };\n if (easing !== undefined) offsetOut.easing = easing;\n offsetKfs.push(offsetOut);\n if (sliced.offset !== baseline.offset) offsetVaries = true;\n }\n\n const stop: PxNode = {\n type: 'stop',\n offset: formatOffset(baseline.offset),\n stopColor: baseline.color,\n };\n const animate: { [k: string]: { keyframes: Array<PxKeyframe>, loop?: PxLoop | boolean } } = {};\n if (colorKfs.length) {\n animate.stopColor = { keyframes: colorKfs };\n if (loop !== undefined) animate.stopColor.loop = loop;\n }\n if (offsetVaries && offsetKfs.length) {\n animate.offset = { keyframes: offsetKfs };\n if (loop !== undefined) animate.offset.loop = loop;\n }\n if (Object.keys(animate).length) stop.animate = animate;\n return stop;\n}\n\n/** Walks backwards from `fromIdx` looking for a kf whose stops array has\n * an entry at `stopIdx`. Used when a kf's stops array is shorter than the\n * global stop count (shouldn't happen if writer respects the constraint,\n * but degrades gracefully). */\nfunction prevDefinedStop(kfs: Array<PxKeyframe>, fromIdx: number, stopIdx: number): PxGradientStop | undefined {\n for (let i = fromIdx; i >= 0; i--) {\n const arr = (kfs[i].value ?? kfs[i].v) as Array<PxGradientStop> | undefined;\n if (arr?.[stopIdx]) return arr[stopIdx];\n }\n for (let i = fromIdx + 1; i < kfs.length; i++) {\n const arr = (kfs[i].value ?? kfs[i].v) as Array<PxGradientStop> | undefined;\n if (arr?.[stopIdx]) return arr[stopIdx];\n }\n return undefined;\n}\n\n/** `0.5` → `\"50%\"`; `1` → `\"100%\"`; `0.123` → `\"12.3%\"`. Matches SVG\n * convention for `<stop offset>`. */\nfunction formatOffset(o: number): string {\n const pct = Math.round(o * 1000) / 10;\n return pct + '%';\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\nimport type { PxClipPathEffect, PxNode } from '../PxAnimatorTypes';\nimport type { ApplyContext } from './types';\nimport { genId } from './util';\n\n\n/**\n * CLIP-PATH → a `<clipPath>` in defs holding a single `<path>` built from the effect's\n * `d`, referenced via `clip-path=\"url(#…)\"` on the host element.\n *\n * Materialiser pattern, mirroring `applyMaskedByEffect` (mint a def, set a URL ref on the\n * node) but far simpler — the clip geometry is a self-contained vector path (no ancestor\n * transform compensation, no source lookup).\n *\n * ANIMATED clip: when `fx.animate` is present it becomes the child `<path>`'s `animate.d`\n * block. The def is spliced into the walked tree, so `collectIds` auto-assigns the animated\n * path an id and the frame loop rewrites its `d` per frame. `clip-path` is a live reference\n * (verified: the browser re-clips on every `d` change across SMIL/CSS/JS/WAAPI), so the clip\n * animates without any per-frame re-binding on the host.\n */\nexport function applyClipPathEffect(\n node: PxNode,\n fx: PxClipPathEffect | undefined,\n ctx: ApplyContext,\n): PxNode {\n if (!fx || (!fx.d && !fx.animate)) return node;\n\n const clipId = genId(ctx, 'clip');\n const pathChild: PxNode = { type: 'path', d: fx.d };\n if (fx.animate) pathChild.animate = { d: fx.animate };\n ctx.defs.push({ type: 'clipPath', id: clipId, children: [pathChild] });\n node.clipPath = 'url(#' + clipId + ')';\n return node;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\nimport type { PxAnimatable, PxMaskedByEffect, PxNode, PxTransformationEffect, Vec2 } from '../PxAnimatorTypes';\nimport { keyframeWith, partsRecord, ReadKind, readAnimatable, readStaticOrigin, TransformPart } from './transformParts';\nimport type { ApplyContext, MaskAncestorTransform } from './types';\nimport { genId } from './util';\n\n\n/**\n * MASKED-BY → a `<mask>` in defs holding the source `<use>` wrapped in\n * (forward of mask source's ancestors) · (inverse of masked element's full\n * transform chain) · (inverse of masked element's own `effects.transformation`)\n *\n * The mask source must paint at its ORIGINAL world position, but\n * `maskUnits=\"userSpaceOnUse\"` (default) interprets the mask in the masked\n * element's local coord system. The wrapper sequence above first cancels\n * out the masked element's accumulated ancestor / own transforms, then\n * re-applies the mask source's ancestor transforms so the `<use>` ends up\n * at the same world matrix it would have if rendered in place.\n *\n * Composes the masked element's own transform with the mask source's, so the\n * mask renders at the right world matrix.\n *\n * Implementation note — this first cut only composes TRANSLATE parts (static\n * and animated). Rotate / scale on the ancestor chains aren't supported yet\n * and will warn if present. `effects.transformation` on the masked element\n * keeps working (passed in as `transformation` and inverted separately).\n */\nexport function applyMaskedByEffect(\n node: PxNode,\n fx: PxMaskedByEffect | undefined,\n transformation: PxTransformationEffect | undefined,\n ctx: ApplyContext,\n): PxNode {\n if (!fx) return node;\n if (!fx.href) { ctx.errors.push('maskedBy.href missing — cannot build mask'); return node; }\n\n const maskId = genId(ctx, 'mask');\n\n let content: PxNode = { type: 'use', href: '#' + fx.href };\n // `effects.transformation` (split-timing form) gets full per-part inversion\n // through `wrapInverseTransform`. With no `effects.transformation` the\n // masked element's transform lives on the body — invert the STATIC part\n // (`node.transform` string) via the same per-part machinery, then on top\n // emit an animated inverse wrapper for `node.animate.transform.keyframes`\n // (per-kf parts-record inversion). Either way, the ancestor-chain\n // compensation runs on top with translate-only composition for now.\n if (transformation) {\n content = wrapInverseTransform(content, transformation, ctx);\n } else if (hasAnimateTransform(node)) {\n // `animate.transform` overrides `node.transform` per-frame in the\n // visualModel, so inverting BOTH would double-count. Animated wins.\n content = wrapInverseAnimatedBodyTransform(content, node, ctx);\n } else {\n const bodyStatic = readTransformationFromBody(node);\n if (bodyStatic) content = wrapInverseTransform(content, bodyStatic, ctx);\n }\n // Skip `targetOwn` translate when we already inverted the body (otherwise\n // the translate would be subtracted twice).\n const includeTargetOwn = transformation === undefined && !nodeHasBodyTransform(node);\n content = wrapAncestorChainCompensation(content, node, fx.href, ctx, includeTargetOwn);\n\n const mask: PxNode = { type: 'mask', id: maskId, children: [content] };\n if (fx.maskType) mask.maskType = fx.maskType;\n if (fx.maskUnits) mask.maskUnits = fx.maskUnits;\n if (fx.maskContentUnits) mask.maskContentUnits = fx.maskContentUnits;\n ctx.defs.push(mask);\n\n node.mask = 'url(#' + maskId + ')';\n return node;\n}\n\n/** Wraps `inner` in inverse-transform `<g>`s built from the masked element's\n * own `effects.transformation` payload (translate / rotate / scale). The\n * ancestor-chain wrappers are added separately by\n * `wrapAncestorChainCompensation`. */\nfunction wrapInverseTransform(inner: PxNode, fx: PxTransformationEffect | undefined, ctx: ApplyContext): PxNode {\n if (!fx) return inner;\n const origin = readStaticOrigin(fx.origin, ctx);\n\n let n = inner;\n n = wrapInversePart(n, TransformPart.Translate, fx.translate, undefined, ctx);\n n = wrapInversePart(n, TransformPart.Rotate, fx.rotate, origin, ctx);\n n = wrapInversePart(n, TransformPart.Scale, fx.scale, origin, ctx);\n return n;\n}\n\nfunction wrapInversePart(\n inner: PxNode, part: TransformPart,\n raw: PxAnimatable<any> | undefined, origin: Vec2 | undefined, ctx: ApplyContext\n): PxNode {\n if (raw === undefined) return inner;\n // `fx.scale` in BARE-ARRAY form is PERCENT (150 = 1.5×), matching\n // `applyTransformationEffect`'s forward `normalizeScale`. Convert to\n // 1.0-units before reading, so `invertPartValue([1.5,1.5])` produces\n // the right `[2/3, 2/3]` instead of `[1/150, 1/150]`. Keyframe / {value}\n // forms already use 1.0-units per the wire convention.\n const normalisedRaw: PxAnimatable<any> | undefined = (part === TransformPart.Scale && Array.isArray(raw))\n ? [raw[0] / 100, raw[1] / 100] as unknown as PxAnimatable<any>\n : raw;\n const v = readAnimatable<any>(normalisedRaw);\n if (v.kind === ReadKind.Static) {\n return { type: 'g', transform: { value: partsRecord(part, invertPartValue(part, v.value), origin) }, children: [inner] };\n }\n if (v.kind === ReadKind.Animated) {\n const animTr: any = { keyframes: v.keyframes.map(kf => {\n const out = keyframeWith(kf, partsRecord(part, invertPartValue(part, kf.value), origin));\n return part === TransformPart.Translate ? { ...out, ...negatedSpatialTangents(kf) } : out;\n }) };\n if (v.loop !== undefined) animTr.loop = v.loop;\n return {\n type: 'g',\n animate: { transform: animTr },\n children: [inner],\n };\n }\n return inner;\n}\n\nfunction invertPartValue(part: TransformPart, value: any): any {\n if (part === TransformPart.Translate) return [-value[0], -value[1]];\n if (part === TransformPart.Rotate) return -value;\n return [1 / value[0], 1 / value[1]]; // scale\n}\n\n/**\n * Spatial tangents (`tangentOut`/`tangentIn`, wire aliases `to`/`ti`) are\n * RELATIVE control-point offsets (control = value + tangent), so an inverse\n * translate keyframe must negate them along with the value — copying them\n * verbatim keeps the ORIGINAL curve direction and the derived mask sags\n * mid-segment on a motion-along-path masked element (endpoints stay exact,\n * which is why only mid-frame sampling exposes it).\n */\nfunction negatedSpatialTangents(kf: Record<string, any>): Record<string, any> {\n const out: Record<string, any> = {};\n const to = kf.tangentOut ?? kf.to;\n const ti = kf.tangentIn ?? kf.ti;\n if (Array.isArray(to)) out.tangentOut = [-to[0], -to[1]];\n if (Array.isArray(ti)) out.tangentIn = [-ti[0], -ti[1]];\n return out;\n}\n\n\n/**\n * Wraps `inner` with the per-part INVERSE of the masked element's\n * `node.animate.transform.keyframes` records. Each kf carries a parts record\n * `{translate?, rotate?, scale?, origin?}` with matrix\n * `T(t)·T(o)·R·S·T(-o)`. The matrix inverse is\n * `T(o)·S^-1·R^-1·T(-o)·T(-t)` — which can't be expressed as ONE parts\n * record when both rotate and scale are present (S would have to precede R).\n *\n * Split into separate per-part wrappers, layered from innermost (translate)\n * outwards (rotate, then scale), so the overall composition matches the\n * matrix-level inverse:\n *\n * <g scale^-1> <g rotate^-1> <g translate^-1> {use} </g></g></g>\n *\n * Each wrapper carries an animated parts record over the input kf times.\n * The `origin` for rotate / scale wrappers comes from each kf (the wire emits\n * it alongside whenever rotate or scale is present), so an animated origin\n * sandwich pivots correctly per frame.\n */\nfunction wrapInverseAnimatedBodyTransform(inner: PxNode, node: PxNode, _ctx: ApplyContext): PxNode {\n const animate = node.animate && typeof node.animate === 'object' && !Array.isArray(node.animate)\n ? (node.animate as Record<string, any>) : undefined;\n const animTr = animate?.transform;\n const kfs = animTr && typeof animTr === 'object' && Array.isArray((animTr as Record<string, any>).keyframes)\n ? ((animTr as Record<string, any>).keyframes as Array<Record<string, any>>)\n : undefined;\n if (!kfs || !kfs.length) return inner;\n\n const translateKfs: Array<Record<string, any>> = [];\n const rotateKfs: Array<Record<string, any>> = [];\n const scaleKfs: Array<Record<string, any>> = [];\n\n for (const kf of kfs) {\n const v = (kf.value ?? kf.v) || {};\n const baseKf = keyframeWith(kf as any, undefined); // copies time / easing / tangents\n if (Array.isArray(v.translate)) {\n translateKfs.push({ ...baseKf, ...negatedSpatialTangents(kf), value: { translate: [-v.translate[0], -v.translate[1]] } });\n }\n if (typeof v.rotate === 'number') {\n const rec: Record<string, any> = { rotate: -v.rotate };\n if (Array.isArray(v.origin)) rec.origin = [v.origin[0], v.origin[1]];\n rotateKfs.push({ ...baseKf, value: rec });\n }\n if (Array.isArray(v.scale)) {\n const rec: Record<string, any> = { scale: [1 / v.scale[0], 1 / v.scale[1]] };\n if (Array.isArray(v.origin)) rec.origin = [v.origin[0], v.origin[1]];\n scaleKfs.push({ ...baseKf, value: rec });\n }\n }\n\n // Forward the source animate.transform's loop config (alternate/cycle/etc.)\n // onto each per-part inverse wrapper so a loop on the masked element's body\n // transform survives the inversion split.\n const srcLoop = (animTr as Record<string, any> | undefined)?.loop;\n const withLoop = (kfs: Array<Record<string, any>>): Record<string, any> => {\n const block: Record<string, any> = { keyframes: kfs };\n if (srcLoop !== undefined) block.loop = srcLoop;\n return block;\n };\n\n let n = inner;\n // Innermost = translate (matches `wrapInverseTransform`'s order).\n if (translateKfs.length) n = { type: 'g', animate: { transform: withLoop(translateKfs) }, children: [n] };\n if (rotateKfs.length) n = { type: 'g', animate: { transform: withLoop(rotateKfs) }, children: [n] };\n if (scaleKfs.length) n = { type: 'g', animate: { transform: withLoop(scaleKfs) }, children: [n] };\n return n;\n}\n\n\n/** True when the node carries any body-side transform (the static `transform`\n * string OR an `animate.transform` block). */\nfunction nodeHasBodyTransform(node: PxNode): boolean {\n if (typeof node.transform === 'string') return true;\n if (node.transform && typeof node.transform === 'object') return true;\n return hasAnimateTransform(node);\n}\n\n/** True when the node carries an `animate.transform` block (per-frame\n * override of `node.transform`). */\nfunction hasAnimateTransform(node: PxNode): boolean {\n const animate = node.animate && typeof node.animate === 'object' && !Array.isArray(node.animate)\n ? (node.animate as Record<string, any>) : undefined;\n return !!(animate && animate.transform);\n}\n\n/** Parses the masked element's body transform (`node.transform` string) into a\n * `PxTransformationEffect`-like static parts record so the existing\n * `wrapInverseTransform` machinery can produce its inverse `<g>` wrappers.\n *\n * ANIMATED body transforms (`node.animate.transform.keyframes`) aren't\n * supported yet — they'd require splitting a parts-record keyframe stream\n * into per-part animations to feed into `wrapInversePart`. Falls back with a\n * warning. (In practice the writer emits `effects.transformation` whenever the\n * masked element is animated, so this caller path is reached only for static\n * cases anyway.) */\nfunction readTransformationFromBody(node: PxNode): PxTransformationEffect | undefined {\n if (typeof node.transform === 'string') {\n const parts = parseTransformStringToParts(node.transform);\n if (!parts) return undefined;\n const out: PxTransformationEffect = {};\n if (parts.translate) out.translate = parts.translate;\n if (parts.rotate !== undefined) out.rotate = parts.rotate;\n // Scale parsed from the string is in 1.0-units (e.g. `scale(1.5)`).\n // Pass it through the `{value}` form so `wrapInversePart`'s\n // bare-array → percent normalisation doesn't re-divide by 100.\n if (parts.scale) out.scale = { value: parts.scale };\n if (parts.origin) out.origin = parts.origin;\n return Object.keys(out).length ? out : undefined;\n }\n return undefined;\n}\n\n/** Parses the canonical body-transform string of the form\n * `translate(t)? translate(o)? rotate? scale? translate(-o)?`\n * — back into a `PxTransformParts`-style record. The origin sandwich\n * (`translate(o) … translate(-o)`) is recovered as `origin: o`; the leading\n * translate (if any) becomes `translate: t`. Returns `undefined` when no\n * recognised ops are found. */\nfunction parseTransformStringToParts(s: string): { translate?: Vec2; rotate?: number; scale?: Vec2; origin?: Vec2 } | undefined {\n interface Op { name: string; args: Array<number>; }\n const re = /([a-zA-Z]+)\\s*\\(([^)]*)\\)/g;\n let m: RegExpExecArray | null;\n const ops: Array<Op> = [];\n while ((m = re.exec(s)) !== null) {\n const args = m[2].split(/[\\s,]+/).filter(a => a.length > 0).map(Number);\n ops.push({ name: m[1], args });\n }\n if (!ops.length) return undefined;\n\n // Detect origin sandwich: a trailing `translate(-ox,-oy)` matching an\n // earlier `translate(+ox,+oy)`. Recover origin / inner rotate / scale.\n const last = ops[ops.length - 1];\n if (last.name === 'translate') {\n for (let j = ops.length - 2; j >= 0; j--) {\n const cand = ops[j];\n if (cand.name !== 'translate') continue;\n const ox = cand.args[0] ?? 0;\n const oy = cand.args[1] ?? 0;\n const lx = last.args[0] ?? 0;\n const ly = last.args[1] ?? 0;\n if (lx !== -ox || ly !== -oy) continue;\n // `cand` = +origin, `last` = −origin. Anything BEFORE `cand` may\n // be a body translate; anything BETWEEN them is rotate / scale.\n const out: { translate?: Vec2; rotate?: number; scale?: Vec2; origin?: Vec2 } = {};\n out.origin = [ox, oy];\n for (let k = 0; k < j; k++) {\n if (ops[k].name === 'translate') {\n const tx = ops[k].args[0] ?? 0;\n const ty = ops[k].args[1] ?? 0;\n out.translate = out.translate ? [out.translate[0] + tx, out.translate[1] + ty] : [tx, ty];\n }\n }\n for (let k = j + 1; k < ops.length - 1; k++) {\n const op = ops[k];\n if (op.name === 'rotate') out.rotate = (out.rotate ?? 0) + (op.args[0] ?? 0);\n else if (op.name === 'scale') {\n const sx = op.args[0] ?? 1;\n const sy = op.args.length > 1 ? op.args[1] : sx;\n out.scale = out.scale ? [out.scale[0] * sx, out.scale[1] * sy] : [sx, sy];\n }\n }\n return out;\n }\n }\n\n // No sandwich — flat sequence. `translate`s sum, `rotate`s sum, `scale`s\n // multiply. Order isn't preserved but it works for the cases emitted without\n // origin (translates commute; only one rotate or scale).\n let translate: Vec2 | undefined;\n let rotate: number | undefined;\n let scale: Vec2 | undefined;\n for (const op of ops) {\n if (op.name === 'translate') {\n const dx = op.args[0] ?? 0;\n const dy = op.args[1] ?? 0;\n translate = translate ? [translate[0] + dx, translate[1] + dy] : [dx, dy];\n } else if (op.name === 'rotate') {\n rotate = (rotate ?? 0) + (op.args[0] ?? 0);\n } else if (op.name === 'scale') {\n const sx = op.args[0] ?? 1;\n const sy = op.args.length > 1 ? op.args[1] : sx;\n scale = scale ? [scale[0] * sx, scale[1] * sy] : [sx, sy];\n }\n }\n const out: { translate?: Vec2; rotate?: number; scale?: Vec2 } = {};\n if (translate) out.translate = translate;\n if (rotate !== undefined) out.rotate = rotate;\n if (scale) out.scale = scale;\n return Object.keys(out).length ? out : undefined;\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Ancestor-chain compensation\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Wraps `inner` in a single `<g>` that carries\n * translate = sum(maskSource.ancestors) − sum(maskedElement.ancestors)\n * (separately for the static baseline + every keyframe time observed on any\n * animated ancestor in either chain).\n *\n * Translations commute, so a single wrapper suffices for the translate-only\n * case. When any chain entry has a non-translate part, this function emits a\n * warning and falls back to translate-only — visually wrong but a graceful\n * degradation until the rotate/scale composition is implemented.\n */\nfunction wrapAncestorChainCompensation(inner: PxNode, maskedNode: PxNode, sourceId: string, ctx: ApplyContext, includeTargetOwn: boolean): PxNode {\n const sourceNode = ctx.idMap.get(sourceId);\n\n // M_target = (ancestors) · (target's own). When `effects.transformation`\n // is present, `wrapInverseTransform` already covers target's own; pass\n // `includeTargetOwn=false` to skip the duplicate. With no `effects.\n // transformation`, the baseline `node.transform` string is the element's\n // only transform — include it.\n const targetAncestors = ctx.maskAncestorChains.get(maskedNode) || [];\n const targetOwn = includeTargetOwn ? extractTranslateOnly(maskedNode, ctx) : undefined;\n const targetChain = targetOwn ? [...targetAncestors, targetOwn] : targetAncestors;\n const sourceChain = (sourceNode && ctx.maskAncestorChains.get(sourceNode)) || [];\n\n if (!targetChain.length && !sourceChain.length) return inner;\n\n // Union of all keyframe times across both chains. Static-only chains end\n // up with `times = []`, which short-circuits below to a static wrapper.\n const times = new Set<number>();\n for (const a of targetChain) if (a.translateKeyframes) for (const kf of a.translateKeyframes) times.add(kf.time);\n for (const a of sourceChain) if (a.translateKeyframes) for (const kf of a.translateKeyframes) times.add(kf.time);\n const animated = times.size > 0;\n\n if (!animated) {\n const tgt = sumStaticTranslate(targetChain);\n const src = sumStaticTranslate(sourceChain);\n const dx = src[0] - tgt[0];\n const dy = src[1] - tgt[1];\n if (dx === 0 && dy === 0) return inner;\n return { type: 'g', transform: 'translate(' + dx + ',' + dy + ')', children: [inner] };\n }\n\n const sortedTimes = Array.from(times).sort((a, b) => a - b);\n const keyframes = sortedTimes.map(t => {\n const tgt = sumTranslateAt(targetChain, t);\n const src = sumTranslateAt(sourceChain, t);\n return { time: t, value: { translate: [src[0] - tgt[0], src[1] - tgt[1]] as [number, number] } };\n });\n return { type: 'g', animate: { transform: { keyframes } }, children: [inner] };\n}\n\n/** Sums every translate (baseline) entry in the chain. Ignores animated kfs. */\nfunction sumStaticTranslate(chain: Array<MaskAncestorTransform>): [number, number] {\n let x = 0, y = 0;\n for (const a of chain) {\n if (a.translate) { x += a.translate[0]; y += a.translate[1]; }\n }\n return [x, y];\n}\n\n/** Sums every translate at time `t` in the chain. Animated entries are sampled\n * via linear interpolation between their kfs; static entries contribute their\n * baseline. */\nfunction sumTranslateAt(chain: Array<MaskAncestorTransform>, t: number): [number, number] {\n let x = 0, y = 0;\n for (const a of chain) {\n if (a.translateKeyframes && a.translateKeyframes.length) {\n const v = interpKfs(a.translateKeyframes, t);\n x += v[0]; y += v[1];\n } else if (a.translate) {\n x += a.translate[0]; y += a.translate[1];\n }\n }\n return [x, y];\n}\n\nfunction interpKfs(kfs: Array<{ time: number; value: [number, number] }>, t: number): [number, number] {\n if (t <= kfs[0].time) return kfs[0].value;\n if (t >= kfs[kfs.length - 1].time) return kfs[kfs.length - 1].value;\n for (let i = 1; i < kfs.length; i++) {\n if (t <= kfs[i].time) {\n const prev = kfs[i - 1];\n const cur = kfs[i];\n const a = (t - prev.time) / (cur.time - prev.time);\n return [prev.value[0] + (cur.value[0] - prev.value[0]) * a, prev.value[1] + (cur.value[1] - prev.value[1]) * a];\n }\n }\n return kfs[kfs.length - 1].value;\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Pre-pass: walk tree, record ancestor chains for every (target, source) pair\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Walks `root` top-down and records — for every element involved in an\n * `effects.maskedBy` pair (the masked element AND the mask source it\n * references) — the chain of translate transforms on its `<g>` ancestors.\n * Results land in `ctx.maskAncestorChains`.\n *\n * The walk runs BEFORE pass 1 so it sees the untouched lightweight tree:\n * ancestor `<g transform=\"...\">` strings + `animate.transform` kfs are still\n * intact and easy to parse.\n */\nexport function collectMaskAncestorChains(root: PxNode, ctx: ApplyContext): void {\n // Two-pass: first find the actual NODE references that are masked elements\n // or mask source elements (the source via idMap, the masked element by\n // walking the tree). Then on a second walk, store ancestor chains for\n // those nodes.\n const interestingNodes = new Set<PxNode>();\n const collectInterestingNodes = (n: PxNode): void => {\n const href = n.effects?.maskedBy?.href;\n if (typeof href === 'string') {\n interestingNodes.add(n); // masked element\n const sourceNode = ctx.idMap.get(href);\n if (sourceNode) interestingNodes.add(sourceNode); // mask source\n }\n if (Array.isArray(n.children)) for (const ch of n.children) collectInterestingNodes(ch);\n };\n collectInterestingNodes(root);\n if (interestingNodes.size === 0) return;\n\n const walk = (node: PxNode, chain: Array<MaskAncestorTransform>): void => {\n if (interestingNodes.has(node)) ctx.maskAncestorChains.set(node, chain);\n if (Array.isArray(node.children)) {\n const own = extractTranslateOnly(node, ctx);\n const next = own ? [...chain, own] : chain;\n for (const ch of node.children) walk(ch, next);\n }\n };\n walk(root, []);\n}\n\n/** Extracts only the TRANSLATE part from a node's `transform` + `animate.transform`.\n * Returns `undefined` when the node has no transform OR carries only\n * non-translate parts. Pushes a warning when a non-translate part is dropped. */\nfunction extractTranslateOnly(node: PxNode, ctx: ApplyContext): MaskAncestorTransform | undefined {\n const tr = node.transform;\n const animateBlock = node.animate && typeof node.animate === 'object' && !Array.isArray(node.animate)\n ? (node.animate as Record<string, any>).transform : undefined;\n if (tr === undefined && !animateBlock) return undefined;\n\n const out: MaskAncestorTransform = {};\n\n if (typeof tr === 'string') {\n const parts = parseTranslateOnlyFromString(tr, ctx);\n if (parts) out.translate = parts;\n } else if (tr && typeof tr === 'object') {\n const value = (tr as Record<string, any>).value;\n if (value && typeof value === 'object' && Array.isArray(value.translate)) {\n out.translate = [value.translate[0] || 0, value.translate[1] || 0];\n }\n if (value && (value.rotate !== undefined || value.scale !== undefined || value.skew !== undefined)) {\n ctx.warnings.push('maskedBy ancestor: non-translate transform parts ignored (rotate/scale not yet supported)');\n }\n }\n\n if (animateBlock && Array.isArray((animateBlock as Record<string, any>).keyframes)) {\n const kfs = (animateBlock as Record<string, any>).keyframes as Array<Record<string, any>>;\n const translateKfs: Array<{ time: number; value: [number, number] }> = [];\n for (const kf of kfs) {\n const v = kf.value ?? kf.v;\n const t = (kf.time ?? kf.t ?? 0) as number;\n if (v && typeof v === 'object' && Array.isArray(v.translate)) {\n translateKfs.push({ time: t, value: [v.translate[0] || 0, v.translate[1] || 0] });\n if (v.rotate !== undefined || v.scale !== undefined || v.skew !== undefined) {\n ctx.warnings.push('maskedBy ancestor: animated non-translate parts ignored');\n }\n }\n }\n if (translateKfs.length) out.translateKeyframes = translateKfs;\n }\n\n return (out.translate || out.translateKeyframes) ? out : undefined;\n}\n\n/** Parses ONLY `translate(x[, y])` ops out of an SVG transform string, summing\n * multiple translates and ignoring anything else (with a one-shot warning).\n * The lightweight writer emits the masked / source ancestors' transforms as\n * these simple strings, so this stays a tiny single-purpose parser. */\nfunction parseTranslateOnlyFromString(s: string, ctx: ApplyContext): [number, number] | undefined {\n const re = /([a-zA-Z]+)\\s*\\(([^)]*)\\)/g;\n let m: RegExpExecArray | null;\n let x = 0, y = 0;\n let seen = false;\n let droppedNonTranslate = false;\n while ((m = re.exec(s)) !== null) {\n const name = m[1];\n const args = m[2].split(/[\\s,]+/).filter(a => a.length > 0).map(Number);\n if (name === 'translate') {\n x += args[0] || 0;\n y += args[1] || 0;\n seen = true;\n } else {\n droppedNonTranslate = true;\n }\n }\n if (droppedNonTranslate) ctx.warnings.push('maskedBy ancestor: non-translate transform in string ignored: ' + s);\n return seen ? [x, y] : undefined;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\n/**\n * REF + TRANSFORMATION (combined). The use's `href` is set BEFORE\n * `applyTransformationEffect` wraps the node so it lands on the actual `<use>`\n * rather than on an outer `<g>` wrapper.\n *\n * For `ref:{type:'content'}` the source is materialised as multi-layer by\n * `splitForContentRef` (see `contentRefSplit.ts`), and the use's `href` is\n * rewritten to point at the inner (no-translate) layer's id. No translate\n * cancellation is needed on the use side any more.\n */\n\nimport { applyTransformationEffect } from './transformationEffect';\nimport type { PxCloneEffect, PxNode, PxTransformationEffect } from '../PxAnimatorTypes';\nimport type { ApplyContext } from './types';\n\nconst CONTENT_SUBREF = 'content';\n\n/**\n * Rewrites `node.href` from the clone's reference part (`type`/`baseId`) —\n * content-ref → the inner-layer id minted by `splitForContentRef`, whole-element\n * ref → `baseId`. Pure href mutation (no wrapping), so it can run even when `node`\n * is ALSO a content-ref SOURCE that gets split: a `<use>` that both references\n * content (consumer) and is itself referenced (source) must get its own href\n * rewritten BEFORE the split moves its body inward — otherwise its body keeps the\n * editor-side content id, which doesn't exist in the lightweight tree (dangling\n * href → retime can't follow the chain → the retimed instance renders nothing).\n *\n * A direct-link clone (no `baseId`, e.g. `clone:{retime}`) keeps its existing\n * `href` — there's nothing to redirect; only content-ref REQUIRES a `baseId`.\n */\nexport function applyRefHref(\n node: PxNode,\n clone: PxCloneEffect | undefined,\n ctx: ApplyContext,\n): void {\n if (!clone) return;\n const baseId = clone.baseId;\n if (!baseId) {\n if (clone.type === CONTENT_SUBREF) ctx.errors.push('clone: content ref missing baseId');\n return; // direct link → href already correct, nothing to rewrite\n }\n // For content-ref, redirect href to the inner-layer id produced by\n // `splitForContentRef`. For whole-element ref (or when no split has\n // happened, e.g. target not in the tree), fall back to baseId.\n const targetId = clone.type === CONTENT_SUBREF\n ? (ctx.contentRefInnerIds.get(baseId) || baseId)\n : baseId;\n node.href = '#' + targetId;\n}\n\nexport function applyRefAndTransformationEffect(\n node: PxNode,\n clone: PxCloneEffect | undefined,\n transformation: PxTransformationEffect | undefined,\n ctx: ApplyContext,\n): PxNode {\n applyRefHref(node, clone, ctx);\n return applyTransformationEffect(node, transformation, ctx);\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\nimport { applyTransformationEffect } from './transformationEffect';\nimport type { PxAnimatable, PxAnimationDefinition, PxNode, PxRepeaterEffect, PxTransformationEffect, Vec2 } from '../PxAnimatorTypes';\nimport type { ApplyContext } from './types';\nimport { clone } from './util';\n\n\n/**\n * REPEATER → N clones inside a `<g>` wrapper. Copy 0 is the unmodified base;\n * copies 1..N-1 are wrapped with a per-copy `PxTransformationEffect` synthesised\n * from the repeater parts:\n *\n * - translate × i\n * - rotate × i\n * - scale ^ i (per-axis geometric compound)\n * - origin CONSTANT — rotation/scale center stays put across copies\n *\n * The origin is the rotation/scale CENTER for the sandwich\n * `T(+o) · T(t·i) · R(r·i) · S(s^i) · T(-o)`. Scaling `o` by `i` would shift the\n * center per copy and produce a spiral instead of a repeated rotation.\n *\n * Each part is independently animatable:\n * - Static parts → emitted as structured `transform: {value:…}` on the per-copy wrapper.\n * - Animated parts → emitted as `animate.transform.keyframes` with each kf value\n * scaled by the rule above (time/easing preserved).\n *\n * Uses the same per-copy matrix formula as the heavy SVG render.\n */\nexport function applyRepeaterEffect(node: PxNode, fx: PxRepeaterEffect | undefined, ctx: ApplyContext): PxNode {\n if (!fx) return node;\n\n const copies = fx.copies ?? 1;\n if (copies < 1) { ctx.errors.push('repeater.copies invalid: ' + fx.copies); return node; }\n\n // The base element's SHARED transform (static baseline + any animation) is\n // lifted onto the wrapper so the per-copy increments compose in the wrapper's\n // coordinate space. Non-transform animations (opacity, fill) stay per copy.\n const sharedTransform = node.transform;\n // In-place animations on a node body are always the record form here —\n // narrow the `PxElementAnimation` union accordingly.\n const sharedAnimTransform = (node.animate as PxAnimationDefinition | undefined)?.transform;\n\n const base = clone(node);\n delete base.transform;\n if (base.animate) {\n delete (base.animate as PxAnimationDefinition).transform;\n if (Object.keys(base.animate).length === 0) delete base.animate;\n }\n // The WRAPPER owns the source id (assigned below): a whole-element `<use>` must\n // resolve to the FULL repeated result including the shared transform. Leaving the\n // id on the base would duplicate it across every copy-clone, and href resolution\n // would land on a bare, transform-stripped copy (rendered at the use's position\n // with no body translate — visibly mis-placed).\n delete base.id;\n\n const children: Array<PxNode> = [base];\n for (let i = 1; i < copies; i++) {\n const baseClone = clone(base);\n const synthFx = synthesisePerCopyFx(fx, i);\n // Run through the standard transformation-effect machinery — gets\n // origin sandwich, animated kfs, etc. for free.\n const wrapped = synthFx ? applyTransformationEffect(baseClone, synthFx, ctx) : baseClone;\n children.push(wrapped);\n }\n\n const wrapper: PxNode = { type: 'g', children };\n if (node.id) wrapper.id = node.id;\n if (sharedTransform !== undefined) wrapper.transform = sharedTransform;\n if (sharedAnimTransform !== undefined) wrapper.animate = { transform: sharedAnimTransform };\n return wrapper;\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// PER-COPY SYNTHESIS\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Builds a per-copy `PxTransformationEffect` for copy index `i`. */\nfunction synthesisePerCopyFx(fx: PxRepeaterEffect, i: number): PxTransformationEffect | undefined {\n const out: PxTransformationEffect = {};\n\n if (fx.translate !== undefined) {\n out.translate = mapAnimatableVec2(fx.translate, v => [v[0] * i, v[1] * i]);\n }\n if (fx.rotate !== undefined) {\n out.rotate = mapAnimatableNumber(fx.rotate, v => v * i);\n }\n if (fx.scale !== undefined) {\n out.scale = synthesiseScale(fx.scale, i);\n }\n if (fx.origin !== undefined) {\n // CONSTANT — rotation/scale center stays put across copies. Scaling by `i`\n // would drift the center per copy (spiral instead of repeated rotation).\n out.origin = fx.origin;\n }\n\n return Object.keys(out).length ? out : undefined;\n}\n\n/** Applies `fn` to every value in an animatable Vec2 (static / `{value}` / `{keyframes}`). */\nfunction mapAnimatableVec2(raw: PxAnimatable<Vec2>, fn: (v: Vec2) => Vec2): PxAnimatable<Vec2> {\n if (Array.isArray(raw)) return fn(raw as Vec2);\n if (raw && typeof raw === 'object') {\n const obj = raw as { value?: Vec2; keyframes?: Array<any>; autoOrient?: boolean };\n if (Array.isArray(obj.keyframes)) {\n return {\n ...obj,\n keyframes: obj.keyframes.map(kf => kf && kf.value !== undefined ? { ...kf, value: fn(kf.value) } : kf),\n } as PxAnimatable<Vec2>;\n }\n if (obj.value !== undefined) {\n return { ...obj, value: fn(obj.value) } as PxAnimatable<Vec2>;\n }\n }\n return raw;\n}\n\n/** Applies `fn` to every value in an animatable number (static / `{value}` / `{keyframes}`). */\nfunction mapAnimatableNumber(raw: PxAnimatable<number>, fn: (v: number) => number): PxAnimatable<number> {\n if (typeof raw === 'number') return fn(raw);\n if (raw && typeof raw === 'object') {\n const obj = raw as { value?: number; keyframes?: Array<any>; autoOrient?: boolean };\n if (Array.isArray(obj.keyframes)) {\n return {\n ...obj,\n keyframes: obj.keyframes.map(kf => kf && kf.value !== undefined ? { ...kf, value: fn(kf.value) } : kf),\n } as PxAnimatable<number>;\n }\n if (obj.value !== undefined) {\n return { ...obj, value: fn(obj.value) } as PxAnimatable<number>;\n }\n }\n return raw;\n}\n\n/**\n * Per-copy scale: per-axis geometric compounding `s^i`. Always emitted in\n * **1.0-units** so it bypasses `applyTransformationEffect.normalizeScale`\n * (which only divides BARE-array static scale by 100 — `{value:…}` and\n * `{keyframes:…}` are expected to be already-1.0-units).\n *\n * Wire convention for repeater.scale is irregular:\n * - **Bare-array static** is PERCENT (e.g. `[85, 85]` = 0.85×); needs `/100`\n * before compounding.\n * - **`{keyframes:…}` animated** values are already 1.0-units (the writer\n * converts) — no `/100`.\n * - `{value:…}` static (rare; uses same convention as bare-array → PERCENT).\n */\nfunction synthesiseScale(raw: PxAnimatable<Vec2>, i: number): PxAnimatable<Vec2> {\n const scalePowerFromPercent = (v: Vec2): Vec2 => [Math.pow(v[0] / 100, i), Math.pow(v[1] / 100, i)];\n const scalePowerFromUnits = (v: Vec2): Vec2 => [Math.pow(v[0], i), Math.pow(v[1], i)];\n\n if (Array.isArray(raw)) {\n // Bare-array static (PERCENT) → emit as `{value:[…]}` in 1.0-units to\n // bypass normalizeScale.\n return { value: scalePowerFromPercent(raw as Vec2) };\n }\n if (raw && typeof raw === 'object') {\n const obj = raw as { value?: Vec2; keyframes?: Array<any>; autoOrient?: boolean };\n if (Array.isArray(obj.keyframes)) {\n // Animated values are already 1.0-units on the wire.\n return {\n ...obj,\n keyframes: obj.keyframes.map(kf => kf && kf.value !== undefined ? { ...kf, value: scalePowerFromUnits(kf.value) } : kf),\n } as PxAnimatable<Vec2>;\n }\n if (obj.value !== undefined) {\n // `{value:…}` static — treated as PERCENT like the bare-array case.\n return { ...obj, value: scalePowerFromPercent(obj.value) } as PxAnimatable<Vec2>;\n }\n }\n return raw;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\n/**\n * RETIME (`<use>` timeline remap) — runs AFTER every other pass-1 effect has\n * materialised, so the `<use>`'s `href` already points at the right post-pass-1\n * target (e.g. the inner-content layer that `contentRefSplit` produced).\n *\n * Retime lives nested under the merged `clone` effect (`effects.clone.retime`).\n * For every `<use>` carrying it we:\n * 1. follow `useNode.href` (no `baseId` lookup — the editor-side id wouldn't\n * resolve in the lightweight tree);\n * 2. recursively materialise the chain target-side, preserving each\n * intermediate `<use>`'s offset/transform and accumulating retime at every\n * nested-retime hop (`concatRetime(child, parent)`);\n * 3. wire the chain root into the `<use>` site — see RETIME_MATERIALISATION_MODE.\n *\n * Each chain link becomes its own defs entry with the right accumulated retime\n * applied to ITS OWN kfs, and the link's `href` rewritten to point at the\n * next-level materialisation.\n *\n * NB: `clone.baseId` is intentionally IGNORED by retime — it carries an\n * upstream core id that does not exist in the lightweight tree; retime\n * follows `href`.\n */\n\nimport type { PxNode, PxRetimeEffect } from '../PxAnimatorTypes';\nimport type { ApplyContext } from './types';\nimport { applyUseOffsetToG } from '../PxNodeCloneUtil';\nimport { clone, genId, indexById, regenerateIdsInClone, stripHash } from './util';\n\n\n/** Mode A (true): replace `<use>` with `<g>` whose child IS the chain-root clone.\n * Mode B (false): push the chain-root clone into `<defs>`, rewrite `<use>.href`.\n *\n * Mode B is the default — it preserves the `<use>`'s native semantics (x/y\n * positioning, width/height — none of which `<g>` interprets). Mode A would\n * need to bake those into the new `<g>`'s transform to stay equivalent. */\nconst RETIME_MATERIALISATION_MODE_INLINE_G = false;\n\n\ninterface Retime { start: number; stretch: number; }\n\nfunction asRetime(r: PxRetimeEffect): Retime {\n // `timeCrop` is declared on the wire schema but not implemented yet —\n // warn instead of silently dropping it so producers notice.\n if (r.timeCrop) {\n console.warn('retime: `timeCrop` is not supported yet and will be ignored');\n }\n return { start: r.start ?? 0, stretch: r.stretch ?? 1 };\n}\n\n/** parent applied OUTSIDE, child INSIDE → `t = parent.start + parent.stretch * (child.start + child.stretch * t_local)`. */\nfunction concatRetime(child: Retime, parent: Retime): Retime {\n return {\n start: parent.start + parent.stretch * child.start,\n stretch: parent.stretch * child.stretch,\n };\n}\n\n/** Retime lives nested under the `clone` effect (`effects.clone.retime`). */\nfunction readCloneRetime(n: PxNode): PxRetimeEffect | undefined {\n return n.effects?.clone?.retime;\n}\n\n/** Removes the retime slice and prunes now-empty `clone` / `effects` buckets. */\nfunction clearCloneRetime(n: PxNode): void {\n const clone = n.effects?.clone;\n if (!clone) return;\n delete clone.retime;\n if (Object.keys(clone).length === 0) delete n.effects!.clone;\n if (n.effects && Object.keys(n.effects).length === 0) delete n.effects;\n}\n\n\n/** Pass-2 driver. Re-indexes ids (pass-1 mints new ones like `_lw_inner_0`),\n * then materialises retime at every site. Order-independent: each site\n * recursively expands its own chain via the original retime layout. */\nexport function applyAllRetimeEffects(root: PxNode, ctx: ApplyContext): void {\n ctx.idMap.clear();\n indexById(root, ctx.idMap);\n\n const sites: Array<PxNode> = [];\n const collect = (n: PxNode): void => {\n if (readCloneRetime(n)) sites.push(n);\n n.children?.forEach(collect);\n };\n collect(root);\n\n // OUTER-most sites first. Materialising a site CONSUMES its retime in place (see the\n // load-bearing note below) — so when an outer use's chain later clones a subtree whose\n // inner retimed use was already processed, the inner retime is gone and never composes\n // with the outer one: a doubly-retimed chain started at +inner instead of\n // +inner∘outer. Document order only happens to work when the outer use serialises\n // first; a symbol-heavy document (e.g. one imported from Lottie precomps) puts the\n // template's inner use ahead of the outer site. Order by reachability instead: a site\n // whose chain can reach other sites materialises before them.\n const reachCount = new Map<PxNode, number>();\n for (const site of sites) {\n let count = 0;\n const visited = new Set<string>();\n const walk = (n: PxNode | undefined): void => {\n if (!n) return;\n if (n !== site && readCloneRetime(n)) count++;\n if (n.type === 'use' && n.href) {\n const id = stripHash(n.href);\n if (id && !visited.has(id)) { visited.add(id); walk(ctx.idMap.get(id)); }\n }\n n.children?.forEach(walk);\n };\n const rootId = stripHash(site.href);\n if (rootId) { visited.add(rootId); walk(ctx.idMap.get(rootId)); }\n reachCount.set(site, count);\n }\n // Stable sort: deeper reach first; equal reach keeps document order.\n sites.sort((a, b) => (reachCount.get(b) ?? 0) - (reachCount.get(a) ?? 0));\n\n for (const useNode of sites) {\n const retime = readCloneRetime(useNode);\n if (!retime) continue;\n // Per-site delete is LOAD-BEARING, not just cleanup: once this use is\n // materialised its `href` is rewritten to an already-time-shifted clone, so\n // a downstream use that references THIS one must NOT re-compose this retime\n // (buildChainClone reads `target`'s clone.retime). Deleting it here makes\n // that read return undefined → no double-count. Moving cleanup to a single\n // end-of-pipeline strip regresses nested retime to +750 instead of +500.\n clearCloneRetime(useNode);\n materialiseRetime(useNode, asRetime(retime), ctx);\n }\n}\n\n\n/** Materialises `retime` on `useNode` by cloning the chain rooted at\n * `useNode.href` and wiring the clone into the `<use>` site. */\nfunction materialiseRetime(useNode: PxNode, retime: Retime, ctx: ApplyContext): void {\n const targetId = stripHash(useNode.href);\n if (!targetId) { ctx.errors.push('retime: <use> has no href to follow'); return; }\n\n const chainRootId = buildChainClone(targetId, retime, ctx, new Set());\n if (!chainRootId) return;\n\n if (RETIME_MATERIALISATION_MODE_INLINE_G) {\n const cloneNode = ctx.idMap.get(chainRootId)!;\n useNode.type = 'g';\n delete useNode.href;\n useNode.children = [cloneNode];\n // `<g>` ignores `x`/`y`; preserve the use's position offset as a\n // `translate(x,y)` applied AFTER any transform (nested inner `<g>`).\n applyUseOffsetToG(useNode);\n ctx.defs = ctx.defs.filter(d => d !== cloneNode); // un-defs it since it's inline now\n } else {\n useNode.href = '#' + chainRootId;\n }\n}\n\n\n/** Clones `targetId`'s node, remaps its OWN kfs by `accum`, then — if the target\n * is a `<use>` — recursively materialises ITS target (folding any nested retime\n * into accum via `concatRetime`). Returns the clone's new id, or undefined on\n * dangling refs / loops. The clone is pushed to `ctx.defs` and indexed in\n * `ctx.idMap` so siblings can resolve it. */\nfunction buildChainClone(targetId: string, accum: Retime, ctx: ApplyContext, chain: Set<string>): string | undefined {\n if (chain.has(targetId)) { ctx.errors.push('retime: loop via \"' + targetId + '\"'); return undefined; }\n const target = ctx.idMap.get(targetId);\n if (!target) { ctx.warnings.push('retime: target \"' + targetId + '\" not found'); return undefined; }\n\n const cloneNode = clone(target);\n regenerateIdsInClone(cloneNode, ctx);\n\n // Clone's OWN body kfs (intermediate-use's animated transform, ball's animation, …).\n // For a use, this is usually a no-op (no kfs on the use itself); for a leaf it\n // remaps the entire reachable subtree.\n if (target.type === 'use') {\n remapKeyframeTimesOnly(cloneNode, accum.start, accum.stretch);\n } else {\n remapKeyframeTimes(cloneNode, accum.start, accum.stretch);\n }\n\n // Strip any retime carried into the clone (already consumed via the chain).\n clearCloneRetime(cloneNode);\n\n // If the target is a `<use>`, recurse on ITS href. Nested retime on the\n // intermediate use folds in via concat.\n if (target.type === 'use' && target.href) {\n const subId = stripHash(target.href);\n if (subId) {\n const innerRetime = readCloneRetime(target);\n const subAccum = innerRetime ? concatRetime(asRetime(innerRetime), accum) : accum;\n const subChain = new Set(chain); subChain.add(targetId);\n const subId2 = buildChainClone(subId, subAccum, ctx, subChain);\n if (subId2) cloneNode.href = '#' + subId2;\n }\n } else {\n // Container target (e.g. a content-ref split wrapper) may HOLD nested\n // `<use>` children that themselves carry retime — the nested content-ref\n // case `use → <g> → use(retime) → …`. Those uses aren't in the pass-2\n // site list (they only exist inside this fresh clone), so materialise\n // them here, composing their retime with `accum` (recurse into children).\n // Without this the inner use's retime stays dangling and the subtree\n // renders un-shifted.\n materialiseNestedRetimeUses(cloneNode, accum, ctx, chain, targetId);\n }\n\n ctx.defs.push(cloneNode);\n if (typeof cloneNode.id === 'string') ctx.idMap.set(cloneNode.id, cloneNode);\n return typeof cloneNode.id === 'string' ? cloneNode.id : undefined;\n}\n\n\n/** Walks a freshly-cloned container subtree and materialises every nested\n * `<use>` that carries retime: composes its retime with `accum` and rewires its\n * href to a fresh chain clone (then drops the now-consumed retime). The\n * container analogue of `buildChainClone`'s use-target recursion — needed for\n * nested content-ref retime where the inner `<use retime>` lives INSIDE the\n * cloned wrapper rather than at its href root. */\nfunction materialiseNestedRetimeUses(node: PxNode, accum: Retime, ctx: ApplyContext, chain: Set<string>, parentTargetId: string): void {\n const visit = (n: PxNode): void => {\n const retime = readCloneRetime(n);\n if (n.type === 'use' && retime && n.href) {\n const subId = stripHash(n.href);\n if (subId) {\n const subAccum = concatRetime(asRetime(retime), accum);\n const subChain = new Set(chain); subChain.add(parentTargetId);\n const subId2 = buildChainClone(subId, subAccum, ctx, subChain);\n if (subId2) n.href = '#' + subId2;\n }\n clearCloneRetime(n);\n }\n n.children?.forEach(visit);\n };\n visit(node);\n}\n\n\n/** Remaps every keyframe `time` in `node` and its subtree: `t' = start + t·stretch`. */\nfunction remapKeyframeTimes(node: PxNode, start: number, stretch: number): void {\n remapKeyframeTimesOnly(node, start, stretch);\n node.children?.forEach(c => remapKeyframeTimes(c, start, stretch));\n}\n\nfunction remapKeyframeTimesOnly(node: PxNode, start: number, stretch: number): void {\n const remap = (kfs: Array<any>): void => {\n for (const kf of kfs) if (typeof kf.time === 'number') kf.time = start + kf.time * stretch;\n };\n if (node.transform && typeof node.transform === 'object' && Array.isArray((node.transform as any).keyframes)) {\n remap((node.transform as any).keyframes);\n }\n if (node.animate && typeof node.animate === 'object') {\n for (const prop of Object.keys(node.animate)) {\n const anim = (node.animate as any)[prop];\n if (anim && Array.isArray(anim.keyframes)) remap(anim.keyframes);\n }\n }\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\n/**\n * Arc-length sampler for an SVG path `d` — the geometry backing along-path glyph\n * placement. Parses the path into cubic Bézier segments (lines and quadratics\n * up-converted), builds a per-segment arc-length LUT, and answers\n * `sampleAtDistance(dist) → { x, y, angle }` (angle = path tangent, radians).\n *\n * Supported commands: M/L/H/V/C/S/Q/T/Z (absolute + relative). Arcs (A/a) are\n * approximated as a straight line to the endpoint (editor paths never emit them;\n * this only guards odd imports). Multiple subpaths are concatenated by arc\n * length (gaps between them are ignored — text flows continuously).\n */\n\nimport { bezier2D_arcLengthLUT, bezier2D_derivativeAt, bezier2D_pointAt, bezier2D_tForDistance, type ArcLengthLUT } from '../PxAnimatorUtil';\n\ntype Pt = [number, number];\n\ninterface Cubic { P0: Pt; P1: Pt; P2: Pt; P3: Pt; lut: ArcLengthLUT; len: number; }\n\nexport interface PathPoint { x: number; y: number; angle: number; }\n\nexport interface PathSampler {\n totalLength: number;\n /** True when the path loops back on itself (explicit `Z` or coincident ends) —\n * no open tip to run off, so overflow clamps/wraps rather than clipping. */\n closed: boolean;\n sampleAtDistance(dist: number): PathPoint;\n}\n\nconst LUT_STEPS = 48;\nconst CMD_RE = /[MmLlHhVvCcSsQqTtAaZz]/;\n\n/** Tokenises `d` into command letters and numbers, preserving order. */\nfunction tokenize(d: string): Array<string> {\n const tokens: Array<string> = [];\n const re = /([MmLlHhVvCcSsQqTtAaZz])|(-?\\d*\\.?\\d+(?:[eE][-+]?\\d+)?)/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(d)) !== null) tokens.push(m[0]);\n return tokens;\n}\n\nfunction quadToCubic(P0: Pt, Qc: Pt, P3: Pt): { P1: Pt; P2: Pt } {\n return {\n P1: [P0[0] + 2 / 3 * (Qc[0] - P0[0]), P0[1] + 2 / 3 * (Qc[1] - P0[1])],\n P2: [P3[0] + 2 / 3 * (Qc[0] - P3[0]), P3[1] + 2 / 3 * (Qc[1] - P3[1])],\n };\n}\n\n/** Parses `d` into cubic segments. Returns null when nothing usable was found. */\nfunction parseCubics(d: string): Array<Cubic> | null {\n const tokens = tokenize(d);\n const segs: Array<Cubic> = [];\n\n let i = 0;\n let cx = 0, cy = 0; // current point\n let sx = 0, sy = 0; // subpath start\n let pcx = 0, pcy = 0; // previous cubic control point (for S)\n let pqx = 0, pqy = 0; // previous quad control point (for T)\n let prevCmd = '';\n\n const num = (): number => parseFloat(tokens[i++]);\n const push = (P1: Pt, P2: Pt, P3: Pt): void => {\n const P0: Pt = [cx, cy];\n const lut = bezier2D_arcLengthLUT(P0, P1, P2, P3, LUT_STEPS);\n segs.push({ P0, P1, P2, P3, lut, len: lut.ds[lut.ds.length - 1] });\n cx = P3[0]; cy = P3[1];\n };\n // Straight line as a cubic with controls at 1/3 and 2/3 — this makes\n // `B(t) = P0 + t·(P3−P0)` EXACTLY, so arc length is linear in t and sampling\n // is precise (degenerate `P1=P0,P2=P3` controls would reparametrise it).\n const pushLine = (x: number, y: number): void => {\n push(\n [cx + (x - cx) / 3, cy + (y - cy) / 3],\n [cx + 2 * (x - cx) / 3, cy + 2 * (y - cy) / 3],\n [x, y],\n );\n };\n\n while (i < tokens.length) {\n let cmd = tokens[i];\n if (CMD_RE.test(cmd)) i++;\n else cmd = prevCmd === 'M' ? 'L' : prevCmd === 'm' ? 'l' : prevCmd; // implicit repeat\n const rel = cmd >= 'a';\n const U = cmd.toUpperCase();\n\n if (U === 'Z') { pushLine(sx, sy); cx = sx; cy = sy; prevCmd = cmd; continue; }\n if (U === 'M') {\n const x = num() + (rel ? cx : 0), y = num() + (rel ? cy : 0);\n cx = x; cy = y; sx = x; sy = y; prevCmd = cmd; continue;\n }\n if (U === 'L') {\n pushLine(num() + (rel ? cx : 0), num() + (rel ? cy : 0));\n } else if (U === 'H') {\n pushLine(num() + (rel ? cx : 0), cy);\n } else if (U === 'V') {\n pushLine(cx, num() + (rel ? cy : 0));\n } else if (U === 'C') {\n const p1: Pt = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];\n const p2: Pt = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];\n const p3: Pt = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];\n pcx = p2[0]; pcy = p2[1];\n push(p1, p2, p3);\n } else if (U === 'S') {\n const smooth = (prevCmd.toUpperCase() === 'C' || prevCmd.toUpperCase() === 'S');\n const p1: Pt = smooth ? [2 * cx - pcx, 2 * cy - pcy] : [cx, cy];\n const p2: Pt = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];\n const p3: Pt = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];\n pcx = p2[0]; pcy = p2[1];\n push(p1, p2, p3);\n } else if (U === 'Q') {\n const qc: Pt = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];\n const p3: Pt = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];\n pqx = qc[0]; pqy = qc[1];\n const { P1, P2 } = quadToCubic([cx, cy], qc, p3);\n push(P1, P2, p3);\n } else if (U === 'T') {\n const smooth = (prevCmd.toUpperCase() === 'Q' || prevCmd.toUpperCase() === 'T');\n const qc: Pt = smooth ? [2 * cx - pqx, 2 * cy - pqy] : [cx, cy];\n const p3: Pt = [num() + (rel ? cx : 0), num() + (rel ? cy : 0)];\n pqx = qc[0]; pqy = qc[1];\n const { P1, P2 } = quadToCubic([cx, cy], qc, p3);\n push(P1, P2, p3);\n } else if (U === 'A') {\n // Arc — skip rx ry rot large sweep, use endpoint as a straight line.\n i += 5;\n pushLine(num() + (rel ? cx : 0), num() + (rel ? cy : 0));\n } else { i++; continue; } // unknown — skip a token defensively\n\n prevCmd = cmd;\n }\n\n return segs.length ? segs : null;\n}\n\nfunction clamp(v: number, lo: number, hi: number): number {\n return v < lo ? lo : v > hi ? hi : v;\n}\n\nexport function createPathSampler(d: string): PathSampler | null {\n const segs = parseCubics(d);\n if (!segs) return null;\n\n // Cumulative start distance per segment; cum[segs.length] === total length.\n const cum = new Float64Array(segs.length + 1);\n for (let k = 0; k < segs.length; k++) cum[k + 1] = cum[k] + segs[k].len;\n const totalLength = cum[segs.length];\n\n // A path is CLOSED when it returns to its start (an explicit `Z`, or coincident\n // first/last points). Open paths get straight-line extrapolation past either end\n // (below); closed paths loop back on themselves, so there's no tip to run off.\n const start = segs[0].P0, end = segs[segs.length - 1].P3;\n const closed = Math.hypot(end[0] - start[0], end[1] - start[1]) < 1e-3;\n\n // Sample strictly within [0, totalLength].\n const sampleOn = (dist: number): PathPoint => {\n let k = 0;\n while (k < segs.length - 1 && dist > cum[k + 1]) k++;\n const seg = segs[k];\n const local = dist - cum[k];\n const t = seg.len > 0 ? bezier2D_tForDistance(seg.lut, local) : 0;\n const [x, y] = bezier2D_pointAt(seg.P0, seg.P1, seg.P2, seg.P3, t);\n const [dx, dy] = bezier2D_derivativeAt(seg.P0, seg.P1, seg.P2, seg.P3, t);\n return { x, y, angle: Math.atan2(dy, dx) };\n };\n\n return {\n totalLength,\n closed,\n sampleAtDistance(dist: number): PathPoint {\n // A CLOSED path loops: a distance outside [0, totalLength] wraps around\n // (modulo the length) rather than piling up at the seam. Without this a\n // negative startOffset collapses every pre-start glyph onto the path start\n // (e.g. text on a circle with startOffset < 0 stacking its first word).\n if (closed && totalLength > 0 && (dist < 0 || dist > totalLength)) {\n return sampleOn(((dist % totalLength) + totalLength) % totalLength);\n }\n // Past an end of an OPEN path: continue in a straight line along that\n // end's tangent, so along-path motion keeps going instead of piling up\n // at the tip. (The caller only asks for distances a glyph actually\n // reaches — startOffset + text length — so this never runs off forever.)\n if (!closed && (dist < 0 || dist > totalLength)) {\n const edge = dist < 0 ? 0 : totalLength;\n const p = sampleOn(edge);\n const over = dist - edge;\n return { x: p.x + Math.cos(p.angle) * over, y: p.y + Math.sin(p.angle) * over, angle: p.angle };\n }\n return sampleOn(clamp(dist, 0, totalLength));\n },\n };\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\nimport type { PxAnimatable, PxNode, PxTextPathEffect } from '../PxAnimatorTypes';\nimport type { ApplyContext } from './types';\nimport { createPathSampler } from './pathSampler';\nimport { genId } from './util';\n\n\nconst EXTEND_MARGIN_FRAC = 0.15; // slack (× path length) to absorb sampling/measure error\n\n\n/** {min,max} over a `PxAnimatable<number>`'s keyframe values (or its single static\n * value; {0,0} when absent). The tangent extension must cover the FULL animation\n * range: the MOST-NEGATIVE startOffset drives the START extension, and the LARGEST\n * startOffset(+textLength) drives the END — using only one value (e.g. the max)\n * misses the other end when startOffset is animated. */\nfunction numRange(v: PxAnimatable<number> | undefined): { min: number; max: number } {\n if (typeof v === 'number') return { min: v, max: v };\n if (v && typeof v === 'object') {\n const o = v as { value?: number; keyframes?: Array<{ value?: number }> };\n if (typeof o.value === 'number') return { min: o.value, max: o.value };\n if (Array.isArray(o.keyframes) && o.keyframes.length) {\n const vals = o.keyframes.map(k => Number(k.value) || 0);\n return { min: Math.min(...vals), max: Math.max(...vals) };\n }\n }\n return { min: 0, max: 0 };\n}\n\n/** Generous upper bound on the text's advance width: char-count × largest font\n * (~1em/char). Over-estimating is safe — the extension is an invisible tail of the\n * reference `<path>`, so extra length just goes unused. */\nfunction estimateTextAdvance(node: PxNode): number {\n let chars = 0, maxFont = 16;\n const walk = (el: PxNode): void => {\n const fs = parseFloat(String((el as any).fontSize ?? '')) || 0;\n if (fs) maxFont = Math.max(maxFont, fs);\n const t = (el as any).text ?? (el as any).textContent;\n if (typeof t === 'string') chars += t.length;\n if (el.children) for (const c of el.children) walk(c);\n };\n walk(node);\n return chars * maxFont;\n}\n\nconst r3 = (n: number): number => Math.round(n * 1000) / 1000;\n\n/** Inputs for {@link extendedPathForBrowser}. `advance` = the text run-width used to\n * size the end extension (caller-measured; the player estimates it from the node,\n * the editor from its text model — browser fonts have no glyph metrics available). */\nexport interface ExtendPathOpts {\n pathOverflow?: string;\n startOffset?: PxAnimatable<number>;\n textLength?: PxAnimatable<number>;\n advance?: number;\n}\n\n/** Result of {@link extendedPathForBrowser}: the (possibly) extended `d`, plus\n * `startShift` — the length of the prepended START lead-in. Because that lead-in\n * moves the `<textPath>` origin back by `startShift`, EVERY `startOffset` (all\n * keyframes) MUST be shifted by `+startShift` so the text lands where it would on\n * the un-extended path (`extend` only adds a tail, it must never move the text). */\nexport interface ExtendedPath {\n d: string;\n startShift: number;\n}\n\n/** Shift a `PxAnimatable<number>` by a constant (all keyframes). No-op for `0`. */\nexport function shiftAnimatable(v: PxAnimatable<number> | undefined, by: number): PxAnimatable<number> | undefined {\n if (!by || v === undefined || v === null) return v;\n if (typeof v === 'number') return v + by;\n const o = v as { value?: number; keyframes?: Array<{ value?: number }> };\n if (typeof o.value === 'number') return { ...o, value: o.value + by };\n if (Array.isArray(o.keyframes)) return { ...o, keyframes: o.keyframes.map(k => ({ ...k, value: (Number(k.value) || 0) + by })) };\n return v;\n}\n\n/** For `pathOverflow:'extend'` (browser-font): extend an OPEN path along its endpoint\n * tangents so the browser lays overflow glyphs onto the straight extension (matching\n * glyph-mode's tangent behavior) instead of dropping them. `'clip'`/closed paths are\n * returned unchanged (browser clips natively). Shared by the player's browser-font\n * applier and the editor's live/heavy `<textPath>` def mint (single source of truth).\n * Returns the extended `d` AND `startShift` — see {@link ExtendedPath}. */\nexport function extendedPathForBrowser(pathD: string, opts: ExtendPathOpts): ExtendedPath {\n if (opts.pathOverflow === 'clip') return { d: pathD, startShift: 0 };\n const sampler = createPathSampler(pathD);\n if (!sampler || sampler.closed || sampler.totalLength <= 0) return { d: pathD, startShift: 0 };\n\n const L = sampler.totalLength;\n const margin = EXTEND_MARGIN_FRAC * L;\n const so = numRange(opts.startOffset);\n const runWidth = numRange(opts.textLength).max || (opts.advance ?? 0);\n // START: how far the EARLIEST (most-negative) startOffset reaches before the path\n // start. END: how far the LATEST run (max startOffset + run width) reaches past the\n // path end. Only add the slack `margin` when actually extending, so a non-negative\n // startOffset that fits leaves the corresponding end alone (no phantom shift).\n const startOverflow = Math.max(0, -so.min);\n const endOverflow = Math.max(0, so.max + runWidth - L);\n const startExt = startOverflow > 0 ? startOverflow + margin : 0;\n const endExt = endOverflow > 0 ? endOverflow + margin : 0;\n if (endExt <= 0 && startExt <= 0) return { d: pathD, startShift: 0 };\n\n const s = sampler.sampleAtDistance(0);\n const e = sampler.sampleAtDistance(L);\n let d = pathD;\n if (startExt > 0) {\n const sx = s.x - Math.cos(s.angle) * startExt, sy = s.y - Math.sin(s.angle) * startExt;\n // Prepend a lead-in: M(extended start) L(original start) + the original path\n // minus its own leading `M x y` (we've re-stated the start via the `L`).\n const rest = pathD.replace(/^\\s*[Mm]\\s*-?[\\d.]+[\\s,]+-?[\\d.]+/, '');\n d = 'M' + r3(sx) + ',' + r3(sy) + 'L' + r3(s.x) + ',' + r3(s.y) + rest;\n }\n if (endExt > 0) {\n const ex = e.x + Math.cos(e.angle) * endExt, ey = e.y + Math.sin(e.angle) * endExt;\n d += 'L' + r3(ex) + ',' + r3(ey);\n }\n // The `<textPath>` distance origin moved back by exactly the start lead-in length.\n return { d, startShift: startExt };\n}\n\n\n/**\n * `effects.textPath` materialiser (browser-font / non-glyph path).\n *\n * The path geometry is carried INLINE on the effect as `path` (an SVG `d`). SVG's\n * native rendering requires a `<textPath href=\"#…\">` wrapper referencing a `<path>`\n * def, so this applier mints that `<path>` def from the inline geometry, wraps the\n * text node's children in the `<textPath>`, and forwards the textPath SVG attrs\n * (`lengthAdjust`, `method`, `spacing`, `startOffset`, `textLength`).\n *\n * `startOffset` / `textLength` accept the full `PxAnimatable<number>` shape: a static\n * number is set as an attribute; the `{keyframes}` form is forwarded to\n * `<textPath>.animate.<attr>`; `{value}` is unwrapped to the static shape.\n *\n * `pathOverflow:'extend'` tangent-extends the minted `<path>` (see\n * {@link extendedPathForBrowser}) so the browser lays overflow glyphs onto the straight\n * extension; `'clip'` mints the geometry as-is and native `<textPath>` drops overflow.\n */\nexport function applyTextPathEffect(\n node: PxNode,\n fx: PxTextPathEffect | undefined,\n ctx: ApplyContext,\n): PxNode {\n if (!fx || typeof fx.path !== 'string' || !fx.path) return node;\n\n const pathId = genId(ctx, 'tpath');\n const { d, startShift } = extendedPathForBrowser(fx.path, {\n pathOverflow: fx.pathOverflow, startOffset: fx.startOffset,\n textLength: fx.textLength, advance: estimateTextAdvance(node),\n });\n ctx.defs.push({ type: 'path', id: pathId, d });\n\n const textPath: PxNode = {\n type: 'textPath',\n href: '#' + pathId,\n children: node.children ?? [],\n };\n if (fx.lengthAdjust !== undefined) textPath.lengthAdjust = fx.lengthAdjust;\n if (fx.method !== undefined) textPath.method = fx.method;\n if (fx.spacing !== undefined) textPath.spacing = fx.spacing;\n // Compensate the start lead-in: shift startOffset (all keyframes) by `startShift`\n // so `extend` doesn't move the text vs the un-extended path.\n applyAnimatableNumber(textPath, 'startOffset', shiftAnimatable(fx.startOffset, startShift));\n applyAnimatableNumber(textPath, 'textLength', fx.textLength);\n\n node.children = [textPath];\n return node;\n}\n\n\n/** Routes a `PxAnimatable<number>` onto a node:\n * - bare `number` / `{value:number}` → `node[attrName] = String(value)`\n * - `{keyframes:[…]}` → `node.animate[attrName] = { keyframes }`\n * Mirrors the pattern in `trimPathEffect.applyAttr`. */\nfunction applyAnimatableNumber(node: PxNode, attrName: string, raw: PxAnimatable<number> | undefined): void {\n if (raw === undefined || raw === null) return;\n\n if (typeof raw === 'number') {\n node[attrName] = String(raw);\n return;\n }\n if (typeof raw === 'object' && raw !== null) {\n const obj = raw as { value?: number; keyframes?: Array<unknown>; loop?: unknown };\n if (Array.isArray(obj.keyframes)) {\n const prevAnimate = node.animate && typeof node.animate === 'object' && !Array.isArray(node.animate) ? node.animate : undefined;\n const animate: Record<string, any> = { ...(prevAnimate || {}) };\n const block: { keyframes: Array<unknown>, loop?: unknown } = { keyframes: obj.keyframes };\n if (obj.loop !== undefined) block.loop = obj.loop;\n animate[attrName] = block;\n node.animate = animate;\n return;\n }\n if (typeof obj.value === 'number') {\n node[attrName] = String(obj.value);\n return;\n }\n }\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\n/**\n * Element-creation factory — abstracts WHAT an \"element\" is so the same\n * geometry/layout code (e.g. the glyph text materialiser) can emit plain wire\n * nodes here, or the editor's React / px elements when called from the editor.\n *\n * The signature intentionally mirrors the editor's `createPxElement(type,\n * props, children, fixReactKeysIfNeeded?)` so the editor's own factory drops in\n * unchanged.\n */\nexport type PxCreateElement<E = any> = (\n type: string,\n props: { [k: string]: any },\n children?: Array<E> | E | null,\n fixReactKeysIfNeeded?: boolean,\n) => E;\n\n\n/**\n * Default factory → a plain wire node `{ type, ...props, children? }`.\n * Drops `undefined` props and empty `children` so output matches the shape the\n * effects pipeline (and `JSON.stringify`) expects.\n */\nexport const jsonElementFactory: PxCreateElement<any> = (type, props, children) => {\n const node: { [k: string]: any } = { type };\n for (const k in props) if (props[k] !== undefined) node[k] = props[k];\n const arr = Array.isArray(children) ? children.filter(c => c != null) : (children != null ? [children] : []);\n if (arr.length) node.children = arr;\n return node;\n};\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\n/**\n * Bakes an affine transform into an SVG path-`d` string so per-glyph outlines\n * (in em units) can be placed at their pen position and merged into a single\n * `<path>`. Parses the absolute `M`/`L`/`C`/`Q`/`Z` commands opentype's\n * `toPathData` emits — glyph outlines never use relative or arc commands.\n *\n * Matrix order matches SVG: `x' = a·x + c·y + e`, `y' = b·x + d·y + f`.\n * For horizontal text it's just scale+translate `[s,0,0,s,tx,ty]`; the full\n * 6-tuple leaves room for rotation (along-path, later).\n */\nexport type Affine = [a: number, b: number, c: number, d: number, e: number, f: number];\n\n\nfunction fmt(v: number, decimals: number): string {\n // Match opentype's `floatToString`: integers stay bare, else fixed decimals.\n return Math.round(v) === v ? '' + Math.round(v) : v.toFixed(decimals);\n}\n\n/** Packs numbers the way opentype does: a space separates a value from the\n * previous one only when it doesn't already start with a `-`. */\nfunction pack(nums: Array<number>, decimals: number): string {\n let s = '';\n for (let i = 0; i < nums.length; i++) {\n const str = fmt(nums[i], decimals);\n if (i > 0 && str.charCodeAt(0) !== 45 /* '-' */) s += ' ';\n s += str;\n }\n return s;\n}\n\nfunction apply(m: Affine, x: number, y: number): [number, number] {\n return [m[0] * x + m[2] * y + m[4], m[1] * x + m[3] * y + m[5]];\n}\n\nconst TOKEN_RE = /([MLCQZ])|(-?\\d*\\.?\\d+(?:e[-+]?\\d+)?)/gi;\n\n/**\n * Applies `m` to every coordinate in `d` (absolute M/L/C/Q/Z) and re-emits.\n * Unknown tokens are skipped defensively; the input is always opentype output.\n */\nexport function transformPathData(d: string, m: Affine, decimals: number = 2): string {\n const tokens: Array<string> = [];\n let match: RegExpExecArray | null;\n TOKEN_RE.lastIndex = 0;\n while ((match = TOKEN_RE.exec(d)) !== null) tokens.push(match[0]);\n\n let out = '';\n let i = 0;\n const num = (): number => parseFloat(tokens[i++]);\n\n while (i < tokens.length) {\n const cmd = tokens[i++];\n if (cmd === 'M' || cmd === 'L') {\n const [x, y] = apply(m, num(), num());\n out += cmd + pack([x, y], decimals);\n } else if (cmd === 'C') {\n const [x1, y1] = apply(m, num(), num());\n const [x2, y2] = apply(m, num(), num());\n const [x, y] = apply(m, num(), num());\n out += 'C' + pack([x1, y1, x2, y2, x, y], decimals);\n } else if (cmd === 'Q') {\n const [x1, y1] = apply(m, num(), num());\n const [x, y] = apply(m, num(), num());\n out += 'Q' + pack([x1, y1, x, y], decimals);\n } else if (cmd === 'Z' || cmd === 'z') {\n out += 'Z';\n }\n // else: stray number without a command — skip (never happens for glyph data).\n }\n return out;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\n/**\n * Glyph text materialiser — turns a `<text>`/`<tspan>` subtree into `<path>`\n * outlines from `definitions.glyphs`, so the text renders with no external font.\n *\n * - HORIZONTAL ({@link materialiseGlyphTextHorizontal}) — left-to-right by\n * advance width; honours font-size, text-anchor, letter/word-spacing,\n * per-tspan x/y/dx/dy, fill/stroke, nested tspans.\n * - ALONG-PATH ({@link materialiseGlyphTextAlongPath}) — each glyph placed and\n * rotated to the referenced path's tangent. Static `startOffset` → glyphs\n * bake+merge; animated `startOffset` → per-glyph `<path>` with sampled\n * `animate.transform`. Text-level `x`/`dx` add distance ALONG the path (≈\n * startOffset) and `dy` shifts PERPENDICULAR — matching native `<textPath>`\n * (see {@link alongPathNodeOffsets}); `y` and per-tspan positioning are ignored\n * (a single run).\n *\n * Element creation goes through an injected {@link PxCreateElement} factory, so\n * the SAME layout produces plain wire nodes here (the effects pipeline) or the\n * editor's React/px elements when the editor calls it — see\n * {@link materialiseGlyphText}.\n *\n * v1 scope (see svga.text.design.md): keyframe-interval easing is linear;\n * kerning/ligatures, per-tspan opacity, text-level animated fill are out of scope.\n */\n\nimport { TEXT_ATTR, TEXT_CONTENT_ATTR, type PxAnimatable, type PxGlyphFont, type PxNode, type PxTextEffect } from '../PxAnimatorTypes';\nimport { jsonElementFactory, type PxCreateElement } from './elementFactory';\nimport { transformPathData, type Affine } from './glyphPathBake';\nimport { createPathSampler, type PathSampler } from './pathSampler';\nimport { unwrapAutoOrientRotations } from '../PxMotionPath';\nimport { ReadKind, readAnimatable, TransformPart } from './transformParts';\nimport type { ApplyContext } from './types';\n\n\nconst DEFAULT_FONT_SIZE = 16;\n\n/** Text/tspan attribute keys that don't belong on the materialised `<g>`. */\nconst TEXT_ATTR_KEYS: ReadonlyArray<string> = [\n 'fontFamily', 'fontSize', 'fontWeight', 'fontStyle', 'textAnchor',\n 'letterSpacing', 'wordSpacing', 'textDecoration', 'textTransform',\n 'whiteSpace', 'x', 'y', 'dx', 'dy', 'lengthAdjust',\n 'fill', 'stroke', 'strokeWidth', 'effects',\n TEXT_ATTR, TEXT_CONTENT_ATTR, 'xml:space',\n];\n\n/** Inputs for a glyph materialisation, decoupled from the effects `ApplyContext`\n * so the editor can call the materialiser directly. */\nexport interface GlyphMaterialiseOpts<E = any> {\n /** Embedded glyph fonts, keyed by `font-family`. */\n glyphs: Record<string, PxGlyphFont>;\n /** Element factory — defaults to plain wire nodes ({@link jsonElementFactory}). */\n create?: PxCreateElement<E>;\n /** Optional diagnostics sink. */\n warnings?: Array<string>;\n}\n\n// fill/stroke/strokeWidth are OPAQUE pass-throughs — copied verbatim onto the\n// emitted element. The wire uses strings (hex); the editor threads its own\n// colour VALUES through unchanged (the factory maps them back to shape paint).\ninterface Paint { fill?: any; stroke?: any; strokeWidth?: any; }\ninterface Style extends Paint { fontFamily?: string; fontSize: number; letterSpacing: number; wordSpacing: number; }\n/** A glyph ready to emit: its em outline + the affine placing it in the doc. */\ninterface Placement { glyphD: string; m: Affine; paint: Paint; }\n/** Minimal keyframe shape (avoids `PxKeyframe`'s non-generic type). Input\n * `startOffset` kfs carry a number `value`; emitted kfs carry transform parts. */\ninterface TransformKeyframe<V = any> { time?: number; value: V; }\n\n\nfunction parseLen(v: unknown): number | undefined {\n if (typeof v === 'number') return v;\n if (typeof v === 'string') { const n = parseFloat(v); return isNaN(n) ? undefined : n; }\n return undefined;\n}\n\nfunction str(v: unknown): string | undefined {\n return typeof v === 'string' ? v : undefined;\n}\n\nfunction resolveStyle(node: PxNode, parent: Style): Style {\n return {\n fontFamily: str(node.fontFamily) ?? parent.fontFamily,\n fontSize: parseLen(node.fontSize) ?? parent.fontSize,\n fill: node.fill ?? parent.fill,\n stroke: node.stroke ?? parent.stroke,\n strokeWidth: node.strokeWidth ?? parent.strokeWidth,\n letterSpacing: parseLen(node.letterSpacing) ?? parent.letterSpacing,\n wordSpacing: parseLen(node.wordSpacing) ?? parent.wordSpacing,\n };\n}\n\nfunction rootStyleOf(node: PxNode): Style {\n return {\n fontFamily: str(node.fontFamily),\n fontSize: parseLen(node.fontSize) ?? DEFAULT_FONT_SIZE,\n fill: node.fill,\n stroke: node.stroke,\n strokeWidth: node.strokeWidth,\n letterSpacing: parseLen(node.letterSpacing) ?? 0,\n wordSpacing: parseLen(node.wordSpacing) ?? 0,\n };\n}\n\nfunction paintOf(s: Style): Paint {\n const p: Paint = {};\n if (s.fill !== undefined) p.fill = s.fill;\n if (s.stroke !== undefined) p.stroke = s.stroke;\n if (s.strokeWidth !== undefined) p.strokeWidth = s.strokeWidth;\n return p;\n}\n\nfunction glyphFontFor(s: Style, glyphs: Record<string, PxGlyphFont>, soleFont: PxGlyphFont | undefined, warnings?: Array<string>): PxGlyphFont | undefined {\n const gf = s.fontFamily ? glyphs[s.fontFamily] : soleFont;\n if (!gf) warnings?.push('textGlyphs: no glyphs for font \"' + (s.fontFamily ?? '') + '\"');\n return gf;\n}\n\nfunction soleFontOf(glyphs: Record<string, PxGlyphFont>): PxGlyphFont | undefined {\n const names = Object.keys(glyphs);\n return names.length === 1 ? glyphs[names[0]] : undefined;\n}\n\n\n/** Default advance (in em units) for a MISSING glyph with no known width, so its\n * placeholder box gets a plausible letter-cell instead of collapsing to nothing. */\nconst MISSING_GLYPH_ADVANCE_EM = 0.6;\n\n/**\n * A HOLLOW FRAME outline (em/glyph units, baseline at y=0 rising to y=-ascent) for a\n * MISSING glyph — so a font that can't supply a char renders a visible □ instead of\n * silently disappearing. Outer rect + a reversed inner rect → a plain nonzero `fill`\n * (the SAME paint a real glyph uses) leaves the middle empty, i.e. a thin outline (a\n * solid block reads as too brutal). Empty string for degenerate sizes.\n */\nfunction missingGlyphBoxEm(advanceEm: number, ascentEm: number): string {\n if (advanceEm <= 0 || ascentEm <= 0) return '';\n const inset = 0.08;\n const x0 = advanceEm * inset, x1 = advanceEm * (1 - inset);\n const y1 = -ascentEm * (1 - inset); // box top (baseline at 0)\n const bw = x1 - x0, bh = -y1;\n const t = Math.max(1, Math.min(bw, bh) * 0.12); // frame border thickness\n const outer = 'M' + x0 + ' 0L' + x1 + ' 0L' + x1 + ' ' + y1 + 'L' + x0 + ' ' + y1 + 'Z';\n if (bw <= 2 * t || bh <= 2 * t) return outer; // too small for a hole → solid\n const ix0 = x0 + t, ix1 = x1 - t, iyb = -t, iyt = y1 + t;\n // Inner rect wound OPPOSITE the outer → nonzero fill carves a hole (the outline).\n return outer + 'M' + ix0 + ' ' + iyb + 'L' + ix0 + ' ' + iyt + 'L' + ix1 + ' ' + iyt + 'L' + ix1 + ' ' + iyb + 'Z';\n}\n\n\n// ── HORIZONTAL ──────────────────────────────────────────────────────────────\n\nexport function materialiseGlyphTextHorizontal<E = any>(node: PxNode, opts: GlyphMaterialiseOpts<E>): E {\n const { glyphs, create = jsonElementFactory as PxCreateElement<E>, warnings } = opts;\n const soleFont = soleFontOf(glyphs);\n\n const pen = { x: parseLen(node.x) ?? 0, y: parseLen(node.y) ?? 0 };\n const placements: Array<Placement & { line: number; x: number; y: number; scale: number }> = [];\n const lines: Array<{ start: number; end: number }> = [{ start: pen.x, end: pen.x }];\n let line = 0;\n\n const renderChars = (content: string, s: Style): void => {\n const gf = glyphFontFor(s, glyphs, soleFont, warnings);\n const upm = gf?.unitsPerEm || 1000;\n const scale = s.fontSize / upm;\n const ascentEm = gf?.ascent ?? 0.9 * upm;\n const paint = paintOf(s);\n for (let i = 0; i < content.length; i++) {\n const ch = content.charAt(i);\n const g = gf?.glyphs[ch];\n if (g && g.d) {\n placements.push({ glyphD: g.d, m: [scale, 0, 0, scale, pen.x, pen.y], paint, line, x: pen.x, y: pen.y, scale });\n pen.x += g.width * scale;\n } else if (/\\S/.test(ch)) {\n // Missing glyph (font absent, or the char has no outline) → a visible □\n // placeholder box so the text doesn't just silently vanish.\n const advEm = (g && g.width > 0) ? g.width : MISSING_GLYPH_ADVANCE_EM * upm;\n placements.push({ glyphD: missingGlyphBoxEm(advEm, ascentEm), m: [scale, 0, 0, scale, pen.x, pen.y], paint, line, x: pen.x, y: pen.y, scale });\n pen.x += advEm * scale;\n } else {\n pen.x += (g ? g.width : 0) * scale; // whitespace: advance only\n }\n pen.x += s.letterSpacing + (ch === ' ' ? s.wordSpacing : 0);\n lines[line].end = pen.x;\n }\n };\n\n const walk = (el: PxNode, parentStyle: Style): void => {\n const s = resolveStyle(el, parentStyle);\n const x = parseLen(el.x);\n const y = parseLen(el.y);\n if (x !== undefined) { pen.x = x; line = lines.length; lines.push({ start: pen.x, end: pen.x }); }\n if (y !== undefined) pen.y = y;\n pen.x += parseLen(el.dx) ?? 0;\n pen.y += parseLen(el.dy) ?? 0;\n const content = str(el[TEXT_ATTR]) ?? str(el[TEXT_CONTENT_ATTR]);\n // Render a node's OWN text only when it has no element children. In the glyph\n // text model text lives on leaf spans; a container that ALSO carries folded\n // text — a single-span line collapsed onto its line-`<tspan>` — would\n // otherwise render its run twice (the fold AND the child span).\n if (content && !el.children?.length) renderChars(content, s);\n if (el.children) for (const ch of el.children) walk(ch, s);\n };\n\n const rootStyle = rootStyleOf(node);\n if (node.children) for (const ch of node.children) walk(ch, rootStyle);\n const rootContent = str(node[TEXT_ATTR]) ?? str(node[TEXT_CONTENT_ATTR]);\n if (rootContent && !node.children?.length) renderChars(rootContent, rootStyle);\n\n // text-anchor: shift each line by its own advance width, then rebuild `m`.\n const anchor = str(node.textAnchor);\n if (anchor === 'middle' || anchor === 'end') {\n for (const p of placements) {\n const w = lines[p.line].end - lines[p.line].start;\n const shift = anchor === 'middle' ? -w / 2 : -w;\n p.m = [p.scale, 0, 0, p.scale, p.x + shift, p.y];\n }\n }\n\n return toGroup(node, buildPaths(placements, create, warnings), create);\n}\n\n\n/** Per-CHARACTER advance box (local, pre-transform coords). `x,y` = the char's baseline start,\n * `width` = its advance, `ascent`/`fontSize` size its bbox. */\nexport interface GlyphCharBox {\n x: number; y: number; width: number; ascent: number; fontSize: number;\n /** Along-path only: baseline END point (leading edge of the next char). Absent for\n * horizontal, where the end is `x + width` on the same baseline. */\n endX?: number; endY?: number;\n /** Along-path only: char rotation in DEGREES (path tangent; 0 = horizontal). */\n rotation?: number;\n}\n\n/** Optional along-path geometry for {@link layoutGlyphTextChars}: when given, chars are\n * placed + rotated along `pathD` (mirrors {@link materialiseGlyphTextAlongPath}) at the\n * STATIC / frame-0 startOffset, so the editor caret follows the path. */\nexport interface GlyphCharBoxAlongPath { pathD?: string; startOffset?: PxAnimatable<number>; textLength?: PxAnimatable<number>; pathOverflow?: string; }\n\n/** Per-character layout boxes for a glyph text, in reading/DOM order INCLUDING spaces\n * (a space has no glyph but advances the pen) AND one zero-width filler box per EMPTY\n * line — the editor's edit canvas renders a zero-width filler char for an empty line\n * (so the caret has something to measure), and DOM char indices must stay aligned.\n * HORIZONTAL by default — mirrors `materialiseGlyphTextHorizontal`'s pen-walk exactly\n * (same x/y/dx/dy, spacing and text-anchor). When `opts.alongPath` is given, mirrors\n * `materialiseGlyphTextAlongPath` (each char placed + rotated to the path tangent). So\n * an editor caret built from these lands on the rendered glyphs. Empty for a text with\n * no glyph font / unparsable path. */\nexport function layoutGlyphTextChars(node: PxNode, opts: Pick<GlyphMaterialiseOpts, 'glyphs' | 'warnings'> & { alongPath?: GlyphCharBoxAlongPath }): Array<GlyphCharBox> {\n if (opts.alongPath?.pathD) return layoutGlyphTextCharsAlongPath(node, opts.alongPath.pathD, opts);\n const { glyphs, warnings } = opts;\n const soleFont = soleFontOf(glyphs);\n\n const pen = { x: parseLen(node.x) ?? 0, y: parseLen(node.y) ?? 0 };\n const boxes: Array<GlyphCharBox & { line: number }> = [];\n const lines: Array<{ start: number; end: number }> = [{ start: pen.x, end: pen.x }];\n let line = 0;\n\n const renderChars = (content: string, s: Style): void => {\n const gf = glyphFontFor(s, glyphs, soleFont, warnings);\n const upm = gf?.unitsPerEm || 1000;\n const scale = s.fontSize / upm;\n const ascent = (gf?.ascent ?? 0.9 * upm) * scale;\n for (let i = 0; i < content.length; i++) {\n const ch = content.charAt(i);\n const g = gf?.glyphs[ch];\n const advance = (g ? g.width : 0) * scale + s.letterSpacing + (ch === ' ' ? s.wordSpacing : 0);\n boxes.push({ x: pen.x, y: pen.y, width: advance, ascent, fontSize: s.fontSize, line });\n pen.x += advance;\n lines[line].end = pen.x;\n }\n };\n\n const walk = (el: PxNode, parentStyle: Style): void => {\n const s = resolveStyle(el, parentStyle);\n const x = parseLen(el.x);\n const y = parseLen(el.y);\n if (x !== undefined) { pen.x = x; line = lines.length; lines.push({ start: pen.x, end: pen.x }); }\n if (y !== undefined) pen.y = y;\n pen.x += parseLen(el.dx) ?? 0;\n pen.y += parseLen(el.dy) ?? 0;\n const content = str(el[TEXT_ATTR]) ?? str(el[TEXT_CONTENT_ATTR]);\n if (content && !el.children?.length) renderChars(content, s);\n if (el.children) for (const ch of el.children) walk(ch, s);\n };\n\n const rootStyle = rootStyleOf(node);\n if (node.children) for (const ch of node.children) {\n const before = boxes.length;\n walk(ch, rootStyle);\n // An EMPTY line (a line-tspan whose subtree yields no chars) still occupies ONE\n // DOM slot on the edit canvas — the zero-width filler the editor renders so the\n // caret has something to measure. Mirror it: one zero-width box at the line's\n // pen position, sized by the line's own resolved font (ascent for caret height,\n // and its hit quad extends the element bbox to include the empty line).\n if (boxes.length === before) {\n const s = resolveStyle(ch, rootStyle);\n const gf = glyphFontFor(s, glyphs, soleFont); // no warning — an empty line has nothing to render\n const upm = gf?.unitsPerEm || 1000;\n boxes.push({ x: pen.x, y: pen.y, width: 0, ascent: (gf?.ascent ?? 0.9 * upm) * (s.fontSize / upm), fontSize: s.fontSize, line });\n }\n }\n const rootContent = str(node[TEXT_ATTR]) ?? str(node[TEXT_CONTENT_ATTR]);\n if (rootContent && !node.children?.length) renderChars(rootContent, rootStyle);\n\n // text-anchor: shift each line's chars by its own advance width (matches the placement shift).\n const anchor = str(node.textAnchor);\n if (anchor === 'middle' || anchor === 'end') {\n for (const b of boxes) {\n const w = lines[b.line].end - lines[b.line].start;\n b.x += anchor === 'middle' ? -w / 2 : -w;\n }\n }\n return boxes.map(({ line: _l, ...b }) => b);\n}\n\n/** Along-path variant of {@link layoutGlyphTextChars}: one box per DOM char (spaces\n * included), placed + rotated along `pathD` at the static / frame-0 startOffset.\n * Mirrors `collectAlongPathCells` + `materialiseGlyphTextAlongPath`, but records EVERY\n * char (the materialiser's cells skip glyph-less chars). `pStart`=char leading edge on\n * the path, `end`=trailing edge, `rotation`=tangent at the char midpoint. */\nfunction layoutGlyphTextCharsAlongPath(node: PxNode, pathD: string, opts: Pick<GlyphMaterialiseOpts, 'glyphs' | 'warnings'> & { alongPath?: GlyphCharBoxAlongPath }): Array<GlyphCharBox> {\n const { glyphs, warnings, alongPath } = opts;\n const sampler = createPathSampler(pathD);\n if (!sampler) { warnings?.push('textGlyphs: unparsable along-path geometry (caret)'); return []; }\n const soleFont = soleFontOf(glyphs);\n\n // Reading-order pass over leaf text (positioning attrs ignored — along-path is a\n // single run), recording each char's [advStart, advEnd], its glyph advance (WITHOUT\n // spacing) for the rotation midpoint, and bbox metrics.\n const chars: Array<{ advStart: number; advEnd: number; glyphW: number; ascent: number; fontSize: number }> = [];\n let adv = 0;\n const walk = (el: PxNode, parentStyle: Style): void => {\n const s = resolveStyle(el, parentStyle);\n const content = str(el[TEXT_ATTR]) ?? str(el[TEXT_CONTENT_ATTR]);\n if (content && !el.children?.length) {\n const gf = glyphFontFor(s, glyphs, soleFont, warnings);\n const upm = gf?.unitsPerEm || 1000;\n const scale = s.fontSize / upm;\n const ascent = (gf?.ascent ?? 0.9 * upm) * scale;\n for (let i = 0; i < content.length; i++) {\n const ch = content.charAt(i);\n const g = gf?.glyphs[ch];\n const glyphW = (g ? g.width : 0) * scale;\n const advance = glyphW + s.letterSpacing + (ch === ' ' ? s.wordSpacing : 0);\n chars.push({ advStart: adv, advEnd: adv + advance, glyphW, ascent, fontSize: s.fontSize });\n adv += advance;\n }\n }\n if (el.children) for (const ch of el.children) walk(ch, s);\n };\n walk(node, rootStyleOf(node));\n\n const width = adv;\n // textLength (lengthAdjust=spacing): scale positions so the run spans textLength.\n // Static / frame-0 read — the caret is a static-frame layout (like startOffset below).\n const tlr = readAnimatable<number>(alongPath?.textLength);\n const tlv = tlr.kind === ReadKind.Animated ? (Number(tlr.keyframes[0]?.value) || 0)\n : tlr.kind === ReadKind.Static ? (Number(tlr.value) || 0) : 0;\n const k = (tlv > 0 && width > 0) ? tlv / width : 1;\n // startOffset base — static or frame-0 keyframe (matches the materialiser's static place).\n // x/dx add along-path distance; dy shifts perpendicular (both mirror the materialiser).\n const so = readAnimatable<number>(alongPath?.startOffset);\n const { along: alongOffset, perp } = alongPathNodeOffsets(node);\n const base = alongOffset + (so.kind === ReadKind.Animated ? (Number(so.keyframes[0]?.value) || 0)\n : so.kind === ReadKind.Static ? (Number(so.value) || 0) : 0);\n\n // Shift a sampled point perpendicular to the path (left normal) by `perp`.\n const withPerp = (p: { x: number; y: number; angle: number }) => ({\n x: p.x - perp * Math.sin(p.angle), y: p.y + perp * Math.cos(p.angle), angle: p.angle,\n });\n\n return chars.map(c => {\n const dStart = base + c.advStart * k;\n const dEnd = base + c.advEnd * k;\n const p0 = withPerp(sampler.sampleAtDistance(dStart));\n const p1 = withPerp(sampler.sampleAtDistance(dEnd));\n // Caret rotation = tangent at the GLYPH's own midpoint (advStart + glyphW/2), which\n // DISREGARDS the char's letter/word spacing. This keeps the synthetic caret aligned\n // with the baked glyph outline (which is placed at its glyph centre), so letter\n // spacing doesn't add extra tilt to the caret.\n const glyphMid = sampler.sampleAtDistance(base + (c.advStart + c.glyphW / 2) * k);\n return {\n x: p0.x, y: p0.y,\n width: c.advEnd - c.advStart,\n ascent: c.ascent, fontSize: c.fontSize,\n endX: p1.x, endY: p1.y,\n rotation: glyphMid.angle * 180 / Math.PI,\n };\n });\n}\n\n\n// ── ALONG-PATH ──────────────────────────────────────────────────────────────\n\n/** One glyph in path order: its outline + geometry, and `midBase` = the arc-\n * distance from the text start (startOffset 0) to the glyph's advance midpoint. */\ninterface AlongCell { glyphD: string; widthEm: number; scale: number; paint: Paint; midBase: number; }\n\n/** Walks the tspans in reading order, accumulating advance (whitespace included)\n * so each rendered glyph gets its `midBase`. Positioning attrs are ignored —\n * along-path text is a single run. */\nfunction collectAlongPathCells(node: PxNode, glyphs: Record<string, PxGlyphFont>, soleFont: PxGlyphFont | undefined, warnings?: Array<string>): { cells: Array<AlongCell>; width: number } {\n const cells: Array<AlongCell> = [];\n let adv = 0;\n const walk = (el: PxNode, parentStyle: Style): void => {\n const s = resolveStyle(el, parentStyle);\n const content = str(el[TEXT_ATTR]) ?? str(el[TEXT_CONTENT_ATTR]);\n // Only leaf text (no children) — a single-span line folds its text onto the\n // line-`<tspan>` AND keeps the child span; rendering both would duplicate it.\n if (content && !el.children?.length) {\n const gf = glyphFontFor(s, glyphs, soleFont, warnings);\n if (gf) {\n const scale = s.fontSize / gf.unitsPerEm;\n const ascentEm = gf.ascent ?? 0.9 * gf.unitsPerEm;\n const paint = paintOf(s);\n for (let i = 0; i < content.length; i++) {\n const ch = content.charAt(i);\n const g = gf.glyphs[ch];\n if (g && g.d) {\n const glyphAdv = g.width * scale;\n cells.push({ glyphD: g.d, widthEm: g.width, scale, paint, midBase: adv + glyphAdv / 2 });\n adv += glyphAdv;\n } else if (/\\S/.test(ch)) {\n // Missing glyph → a visible □ placeholder box (see missingGlyphBoxEm).\n const wEm = (g && g.width > 0) ? g.width : MISSING_GLYPH_ADVANCE_EM * gf.unitsPerEm;\n const boxAdv = wEm * scale;\n cells.push({ glyphD: missingGlyphBoxEm(wEm, ascentEm), widthEm: wEm, scale, paint, midBase: adv + boxAdv / 2 });\n adv += boxAdv;\n } else {\n adv += (g ? g.width : 0) * scale; // whitespace: advance only\n }\n adv += s.letterSpacing + (ch === ' ' ? s.wordSpacing : 0);\n }\n }\n }\n if (el.children) for (const ch of el.children) walk(ch, s);\n };\n walk(node, rootStyleOf(node));\n return { cells, width: adv };\n}\n\n/** Affine placing a glyph so its mid-advance baseline sits at path-distance\n * `dist`, rotated to the tangent (scale baked in). `perp` shifts the glyph\n * PERPENDICULAR to the path (SVG `dy` on text-on-a-path), along the left normal\n * (−sinθ, cosθ) — in path/user units, NOT scaled by the glyph size. */\nfunction alongAffine(sampler: PathSampler, dist: number, scale: number, widthEm: number, perp = 0): Affine {\n const { x, y, angle } = sampler.sampleAtDistance(dist);\n const cos = Math.cos(angle), sin = Math.sin(angle), hw = widthEm / 2;\n return [scale * cos, scale * sin, -scale * sin, scale * cos, x - scale * cos * hw - perp * sin, y - scale * sin * hw + perp * cos];\n}\n\n/** Text-on-a-path offsets from the `<text>`/`<tspan>` x/dx/dy attributes (horizontal\n * writing mode; see the SVG \"text on a path\" layout rules):\n * • `x` and `dx` shift ALONG the path (both add to the startpoint distance),\n * • `dy` shifts PERPENDICULAR to the path,\n * • `y` is IGNORED (the path, not `y`, sets the cross-axis position).\n * Matches the browser's native `<textPath>` so our baked glyphs line up with it. */\nfunction alongPathNodeOffsets(node: PxNode): { along: number; perp: number } {\n return {\n along: (parseLen(node.x) ?? 0) + (parseLen(node.dx) ?? 0),\n perp: parseLen(node.dy) ?? 0,\n };\n}\n\nexport function materialiseGlyphTextAlongPath<E = any>(\n node: PxNode,\n pathD: string | undefined,\n startOffset: PxAnimatable<number> | undefined,\n opts: GlyphMaterialiseOpts<E>,\n textLength?: PxAnimatable<number>,\n pathOverflow?: string,\n): E | null {\n const { glyphs, create = jsonElementFactory as PxCreateElement<E>, warnings } = opts;\n const sampler = pathD ? createPathSampler(pathD) : null;\n if (!sampler) { warnings?.push('textGlyphs: unparsable along-path geometry'); return null; }\n\n const soleFont = soleFontOf(glyphs);\n const { cells, width } = collectAlongPathCells(node, glyphs, soleFont, warnings);\n if (!cells.length) return toGroup(node, [], create);\n\n // x/dx → extra distance ALONG the path (added to startOffset); dy → perpendicular.\n const { along: alongOffset, perp } = alongPathNodeOffsets(node);\n\n // Both drivers as piecewise-linear tracks. textLength (lengthAdjust=spacing) scales\n // each glyph's position along the path so the run spans `textLength(t)` (glyph\n // outlines keep their natural size): distance(t) = startOffset(t) + k(t)·midBase.\n const soTrack = numTrackOf(startOffset);\n const tlTrack = numTrackOf(textLength);\n const kOf = (tl: number): number => (tl > 0 && width > 0) ? tl / width : 1;\n\n // pathOverflow 'clip' (open path): a glyph whose mid-advance point falls past an\n // end disappears (native <textPath> semantics), vs 'extend' (default) where the\n // sampler continues along the tangent. See svga.text.path-overflow.plan.md.\n const isClip = pathOverflow === 'clip' && !sampler.closed;\n\n if (soTrack.animated || tlTrack.animated) {\n // startOffset and/or textLength animate → each glyph slides along the path: its\n // own <path> with sampled translate+rotate keyframes (no merge). Per merged-\n // timeline interval both tracks are linear, so the glyph distance is linear too.\n const times = mergeTrackTimes(soTrack.times, tlTrack.times);\n const distOf = (c: AlongCell, t: number): number => alongOffset + soTrack.at(t) + kOf(tlTrack.at(t)) * c.midBase;\n const loop = soTrack.animated ? soTrack.loop : tlTrack.loop;\n return toGroup(node, buildAnimatedAlongPath(cells, sampler, distOf, times, loop, create, isClip, perp), create);\n }\n\n // Static (or single-keyframe): place + bake; glyphs sharing paint still merge.\n const k = kOf(tlTrack.at(0));\n const base = alongOffset + soTrack.at(0);\n const placeCells = isClip\n ? cells.filter(c => { const d = base + c.midBase * k; return d >= 0 && d <= sampler.totalLength; })\n : cells;\n const placements: Array<Placement> = placeCells.map(c => ({\n glyphD: c.glyphD, paint: c.paint,\n m: alongAffine(sampler, base + c.midBase * k, c.scale, c.widthEm, perp),\n }));\n return toGroup(node, buildPaths(placements, create, warnings), create);\n}\n\n/** A `PxAnimatable<number>` as a clamped piecewise-LINEAR sampler: constant for\n * static / absent / single-keyframe, keyframe-interpolated when animated — the same\n * linear-per-interval interpretation the along-path baking has always used. */\ninterface NumTrack { animated: boolean; times: Array<number>; loop?: unknown; at(t: number): number; }\n\nfunction numTrackOf(raw: PxAnimatable<number> | undefined): NumTrack {\n const r = readAnimatable<number>(raw);\n if (r.kind === ReadKind.Animated && r.keyframes.length >= 2) {\n const kfs = [...r.keyframes].sort((k1, k2) => (Number(k1.time) || 0) - (Number(k2.time) || 0));\n const times = kfs.map(kf => Number(kf.time) || 0);\n const vals = kfs.map(kf => Number(kf.value) || 0);\n return {\n animated: true, times, loop: r.loop,\n at(t: number): number {\n if (t <= times[0]) return vals[0];\n for (let i = 1; i < times.length; i++) {\n if (t <= times[i]) {\n const span = times[i] - times[i - 1];\n const f = span > 0 ? (t - times[i - 1]) / span : 1;\n return vals[i - 1] + f * (vals[i] - vals[i - 1]);\n }\n }\n return vals[vals.length - 1];\n },\n };\n }\n const v = r.kind === ReadKind.Animated ? (Number(r.keyframes[0]?.value) || 0)\n : r.kind === ReadKind.Static ? (Number(r.value) || 0) : 0;\n return { animated: false, times: [], at: () => v };\n}\n\n/** Sorted union of two keyframe-time lists (deduped) — the merged animation timeline. */\nfunction mergeTrackTimes(a: Array<number>, b: Array<number>): Array<number> {\n const all = [...a, ...b].sort((t1, t2) => t1 - t2);\n const out: Array<number> = [];\n for (const t of all) if (!out.length || t !== out[out.length - 1]) out.push(t);\n return out;\n}\n\n\n// Sampling density for a glyph's motion-path keyframes: aim for ~≤ this many\n// steps across the whole path so linear interpolation follows the curve.\nconst ALONG_PATH_MAX_STEPS = 48;\nconst ALONG_PATH_MAX_STEPS_PER_SEGMENT = 64;\n\nfunction roundN(v: number, n: number): number {\n const f = 10 ** n;\n return Math.round(v * f) / f;\n}\n\n/** Builds a separate glyph element per glyph, its outline baked centred at the\n * origin (mid-advance baseline) so `animate.transform` translate+rotate places\n * it along the path over time. `distOf` gives the glyph's along-path distance at a\n * time (startOffset(t) + textLength-scale(t)·midBase + x/dx — both drivers merged\n * into `times`); each interval is sub-sampled so the glyph tracks a curved path.\n * Interval interp is linear (per-keyframe easing shaping isn't reproduced — a v1\n * limitation). */\nfunction buildAnimatedAlongPath<E>(\n cells: Array<AlongCell>,\n sampler: PathSampler,\n distOf: (c: AlongCell, t: number) => number,\n times: Array<number>,\n loop: unknown,\n create: PxCreateElement<E>,\n isClip: boolean,\n perp = 0,\n): Array<E> {\n const step = Math.max(sampler.totalLength / ALONG_PATH_MAX_STEPS, 0.5);\n const onPath = (dist: number): boolean => dist >= 0 && dist <= sampler.totalLength;\n\n const out: Array<E> = [];\n for (const c of cells) {\n const centred: Affine = [c.scale, 0, 0, c.scale, -c.scale * (c.widthEm / 2), 0];\n const d = transformPathData(c.glyphD, centred);\n\n const sampleKf = (dist: number, time: number): TransformKeyframe => {\n const { x, y, angle } = sampler.sampleAtDistance(dist);\n const cos = Math.cos(angle), sin = Math.sin(angle);\n // dy shifts perpendicular to the path (left normal), in path units.\n return {\n time,\n value: {\n [TransformPart.Translate]: [roundN(x - perp * sin, 3), roundN(y + perp * cos, 3)],\n [TransformPart.Rotate]: roundN(angle * 180 / Math.PI, 3),\n },\n };\n };\n\n const kfs: Array<TransformKeyframe> = [];\n // Clip: opacity 1 while the glyph's centre is on the path, 0 off — the\n // sampling is dense (`step`), so the linear fade across one step reads as a\n // near-sharp pop (a robust stand-in for the hard native-<textPath> drop).\n const opKfs: Array<TransformKeyframe<number>> = [];\n const pushKf = (dist: number, time: number): void => {\n kfs.push(sampleKf(dist, time));\n if (isClip) opKfs.push({ time, value: onPath(dist) ? 1 : 0 });\n };\n\n pushKf(distOf(c, times[0]), times[0]);\n for (let k = 1; k < times.length; k++) {\n const t0 = times[k - 1], t1 = times[k];\n const d0 = distOf(c, t0), d1 = distOf(c, t1);\n const n = Math.min(ALONG_PATH_MAX_STEPS_PER_SEGMENT, Math.max(1, Math.ceil(Math.abs(d1 - d0) / step)));\n for (let s = 1; s <= n; s++) {\n const f = s / n;\n const t = t0 + f * (t1 - t0);\n pushKf(distOf(c, t), t);\n }\n }\n\n // Tangent angles come from atan2 and wrap at ±180° — crossing that seam (e.g.\n // the bottom of a circle) would otherwise lerp the ~358° long way between two\n // samples and visibly flip the glyph. Same fix as motion-path auto-orient.\n unwrapAutoOrientRotations(kfs);\n\n const transform: { keyframes: Array<TransformKeyframe>; loop?: unknown } = { keyframes: kfs };\n if (loop !== undefined) transform.loop = loop;\n const animate: { [k: string]: any } = { transform };\n // Only add an opacity track when it actually toggles (a glyph fully on-path\n // the whole time needs none).\n if (isClip && opKfs.some(k => k.value === 0)) {\n const op: { keyframes: Array<TransformKeyframe<number>>; loop?: unknown } = { keyframes: opKfs };\n if (loop !== undefined) op.loop = loop;\n animate.opacity = op;\n }\n\n out.push(create('path', { d, ...paintProps(c.paint), animate }, []));\n }\n return out;\n}\n\n\n// ── shared emit ───────────────────────────────────────────────────────────────\n\nfunction paintProps(paint: Paint): { [k: string]: any } {\n const p: { [k: string]: any } = {};\n if (paint.fill !== undefined) p.fill = paint.fill;\n if (paint.stroke !== undefined) p.stroke = paint.stroke;\n if (paint.strokeWidth !== undefined) p.strokeWidth = paint.strokeWidth;\n return p;\n}\n\n/** Merges placements sharing paint into baked `<path>` elements. */\nfunction buildPaths<E>(placements: Array<Placement>, create: PxCreateElement<E>, warnings?: Array<string>): Array<E> {\n if (!placements.length) { warnings?.push('textGlyphs: nothing to render'); return []; }\n\n const byPaint = new Map<string, { paint: Paint; d: string }>();\n for (const p of placements) {\n // Stable key across any paint value type (hex string, [r,g,b], gradient object).\n const key = JSON.stringify([p.paint.fill ?? null, p.paint.stroke ?? null, p.paint.strokeWidth ?? null]);\n const baked = transformPathData(p.glyphD, p.m);\n const entry = byPaint.get(key);\n if (entry) entry.d += baked;\n else byPaint.set(key, { paint: p.paint, d: baked });\n }\n\n const out: Array<E> = [];\n for (const { paint, d } of byPaint.values()) out.push(create('path', { d, ...paintProps(paint) }, []));\n return out;\n}\n\n/** Builds the `<g>` that replaces the `<text>`: keeps its transform / id /\n * animate / opacity, drops text-specific attributes, holds the glyph elements. */\nfunction toGroup<E>(node: PxNode, children: Array<E>, create: PxCreateElement<E>): E {\n const gProps: { [k: string]: any } = {};\n for (const k of Object.keys(node)) {\n if (k === 'type' || k === 'children' || TEXT_ATTR_KEYS.indexOf(k) !== -1) continue;\n gProps[k] = (node as { [k: string]: any })[k];\n }\n if (gProps.style && typeof gProps.style === 'object') {\n const style = { ...(gProps.style as Record<string, unknown>) };\n delete style['white-space'];\n if (Object.keys(style).length) gProps.style = style; else delete gProps.style;\n }\n return create('g', gProps, children);\n}\n\n\n// ── editor-facing convenience + pipeline adapters ──────────────────────────────\n\n/** Single entry the EDITOR calls: materialises a glyph `<text>` node into the\n * factory's element type, choosing along-path when `alongPath` is given. */\nexport function materialiseGlyphText<E = any>(\n node: PxNode,\n opts: GlyphMaterialiseOpts<E> & { alongPath?: { pathD?: string; startOffset?: PxAnimatable<number>; textLength?: PxAnimatable<number>; pathOverflow?: string } },\n): E | null {\n if (opts.alongPath) return materialiseGlyphTextAlongPath(node, opts.alongPath.pathD, opts.alongPath.startOffset, opts, opts.alongPath.textLength, opts.alongPath.pathOverflow);\n return materialiseGlyphTextHorizontal(node, opts);\n}\n\n/** Pipeline adapter (plain wire nodes) — `effects.text.useGlyphs`, horizontal. */\nexport function applyTextGlyphsEffect(node: PxNode, fx: PxTextEffect | undefined, ctx: ApplyContext): PxNode {\n if (!fx?.useGlyphs) return node;\n if (!ctx.glyphs) { ctx.warnings.push('textGlyphs: no definitions.glyphs — left as native <text>'); return node; }\n return materialiseGlyphTextHorizontal<PxNode>(node, { glyphs: ctx.glyphs, warnings: ctx.warnings });\n}\n\n/** Pipeline adapter (plain wire nodes) — glyph text along a referenced path. */\nexport function applyTextGlyphsAlongPath(node: PxNode, ctx: ApplyContext, pathD: string | undefined, startOffset: PxAnimatable<number> | undefined, textLength?: PxAnimatable<number>, pathOverflow?: string): PxNode | null {\n if (!ctx.glyphs) { ctx.warnings.push('textGlyphs: no definitions.glyphs'); return null; }\n return materialiseGlyphTextAlongPath<PxNode>(node, pathD, startOffset, { glyphs: ctx.glyphs, warnings: ctx.warnings }, textLength, pathOverflow);\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\nimport type { PxAnimatable, PxBezierPath, PxKeyframe, PxLoop, PxNode, Vec2, _PxTrimPathEffect } from '../PxAnimatorTypes';\nimport { bezier2D_arcLengthLUT, bezierToSvgPath, clamp } from '../PxAnimatorUtil';\nimport { parseSvgPathToBezier } from '../PxDefinitions';\nimport { ReadKind, readAnimatable, type ReadPart } from './transformParts';\nimport type { ApplyContext } from './types';\n\n\n/**\n * Applies a `trimPath` effect: collects every descendant shape leaf, slices each\n * leaf's `d` into sub-paths, measures each in px, and converts the parametric\n * `offset` + `range` to per-sub-path `stroke-dasharray` / `stroke-dashoffset` (and\n * `opacity` for empty-range hide).\n *\n * - `trimAllAsOne` chains every sub-path's length end-to-end so the\n * window slides across siblings (a flag of TRUE keeps a single trim window,\n * chaining the sub-paths' `totalLength`).\n * - Animated `offset` becomes `animate.strokeDashoffset.keyframes`;\n * animated `range` becomes `animate.strokeDasharray.keyframes`.\n * - The dasharray emits a repeated pattern so any dashoffset shift lands on a\n * valid dash segment.\n * - Empty-range moments are hidden with `stroke-opacity` 0 (STROKE only — the\n * fill stays visible).\n *\n * COLLAPSE: when the trim host is itself a single shape leaf with exactly ONE\n * sub-path, the trim materialises directly onto that leaf's own `<path>` (no\n * `<g>` split). Multi-subpath (or group/descendant) trims still expand to\n * `<g>` + one bare `<path>` per sub-path.\n */\nexport function applyTrimPathEffect(\n node: PxNode,\n trimPath: _PxTrimPathEffect | undefined,\n isCombinedShape: boolean | undefined,\n ctx: ApplyContext,\n): PxNode {\n if (!trimPath) return node;\n\n const trimAllAsOne = !!trimPath.trimAllAsOne;\n\n // Pass 1a — collect leaves with subpath lengths (no chain offset yet).\n const leafEntries: Array<LeafEntry> = [];\n const measure = (n: PxNode): void => {\n if (Array.isArray(n.children) && n.children.length > 0) {\n for (const ch of n.children) measure(ch);\n return;\n }\n const d = typeof n.d === 'string' ? n.d : shapeToPathD(n);\n if (d === undefined) return;\n const subpaths = parseSvgPathToBezier(d);\n if (!subpaths.length) return;\n const entry: LeafEntry = { leaf: n, subpaths: [] };\n for (const sp of subpaths) {\n const lengthPx = pxBezierPathLength(sp);\n entry.subpaths.push({ subpath: sp, lengthPx, startOffsetPx: 0 });\n }\n leafEntries.push(entry);\n };\n measure(node);\n\n if (!leafEntries.length) return node;\n\n // Pass 1b — assign chain offsets.\n // `trimAllAsOne=true`: walk leaves in REVERSE doc order so the chain\n // starts at the visually-topmost leaf. Within each leaf, subpaths keep their\n // `d`-attribute order — without the reverse, a multi-leaf group emits the\n // leaves' dashoffsets SWAPPED, which renders the visible trim window on the\n // wrong subpath.\n // `trimAllAsOne=false`: each subpath gets its own independent chain\n // (offset 0), so the leaf iteration order doesn't matter.\n let acc = 0;\n const iterOrder = trimAllAsOne ? [...leafEntries].reverse() : leafEntries;\n for (const entry of iterOrder) {\n for (const sp of entry.subpaths) {\n if (!trimAllAsOne) acc = 0;\n sp.startOffsetPx = acc;\n acc += sp.lengthPx;\n }\n }\n\n const chainLengthPx = acc;\n if (trimAllAsOne && chainLengthPx < 0.001) return node;\n\n // Offset / range readers. Range is post-processed for cross-overs so the\n // dasharray emitter never sees `range[0] > range[1]`.\n //\n // Defaults: `offset = 0` and `range = [0, 1]`. Treating absent\n // inputs as those statics (rather than skipping the emit) keeps the\n // `+ SMALL_PADDING_PX` shift active — that 1-px buffer is what stops\n // `stroke-linecap=\"round\"` from painting a round dot at the zero-length\n // first dash. Missing-emit means no `stroke-dashoffset`, no shift, and\n // the dot reappears.\n const offsetReadRaw = readAnimatable<number>(trimPath.offset);\n const offsetRead: ReadPart<number> = offsetReadRaw.kind === ReadKind.Absent\n ? { kind: ReadKind.Static, value: 0 }\n : offsetReadRaw;\n const rangeReadRaw = readRangeWithCrossings(trimPath.range);\n const rangeRead: ReadPart<Vec2> = rangeReadRaw.kind === ReadKind.Absent\n ? { kind: ReadKind.Static, value: [0, 1] }\n : rangeReadRaw;\n\n const offsetValues = readScalarValues(offsetRead);\n const minOffset = offsetValues.length ? Math.min(...offsetValues) : 0;\n const maxOffset = offsetValues.length ? Math.max(...offsetValues) : 0;\n const minMaxOffset: [number, number] = [minOffset, maxOffset];\n\n // COLLAPSE: the trim host is a single shape leaf with exactly one sub-path\n // → no `<g>` split. The trim stroke attrs go directly on the leaf's own\n // `<path>` (its `fill` / `stroke` / `transform` / `id` stay put).\n if (leafEntries.length === 1 && leafEntries[0].leaf === node && leafEntries[0].subpaths.length === 1) {\n const entry = leafEntries[0];\n const sp = entry.subpaths[0];\n const pathLengthPx = trimAllAsOne ? chainLengthPx : sp.lengthPx;\n if (pathLengthPx < 0.001) return node;\n const startOffsetPct = trimAllAsOne ? sp.startOffsetPx / pathLengthPx : 0;\n return collapseLeafWithTrim(entry.leaf, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead);\n }\n\n // Pass 2 — walk the tree and replace each measured leaf with a <g>\n // containing one bare <path> per sub-path.\n const replacements = new Map<PxNode, PxNode>();\n for (const entry of leafEntries) {\n const newChildren: Array<PxNode> = [];\n for (const sp of entry.subpaths) {\n const pathLengthPx = trimAllAsOne ? chainLengthPx : sp.lengthPx;\n if (pathLengthPx < 0.001) continue;\n const startOffsetPct = trimAllAsOne ? sp.startOffsetPx / pathLengthPx : 0;\n newChildren.push(...buildSubpathNodes(entry.leaf, sp.subpath, pathLengthPx, startOffsetPct, minMaxOffset, offsetRead, rangeRead, ctx));\n }\n replacements.set(entry.leaf, wrapLeafAsGroup(entry.leaf, newChildren));\n }\n\n const swap = (n: PxNode): PxNode => {\n const r = replacements.get(n);\n if (r) return r;\n if (Array.isArray(n.children) && n.children.length > 0) {\n return { ...n, children: n.children.map(swap) };\n }\n return n;\n };\n return swap(node);\n}\n\n\n// ============================================================================\n// Leaf -> sub-path table\n// ============================================================================\n\ninterface LeafEntry {\n leaf: PxNode;\n subpaths: Array<{ subpath: PxBezierPath; lengthPx: number; startOffsetPx: number }>;\n}\n\n/** Wraps a leaf as a `<g>` with new sub-path children. Outer attrs of the leaf\n * move onto the wrapper (so its `id` / style anchors are preserved); `d`,\n * `strokeDasharray`, `strokeDashoffset`, and `effects` are stripped. */\nfunction wrapLeafAsGroup(leaf: PxNode, children: Array<PxNode>): PxNode {\n const wrapper: PxNode = { ...leaf, type: 'g', children };\n delete wrapper.d;\n delete wrapper.strokeDasharray;\n delete wrapper.strokeDashoffset;\n delete wrapper.effects;\n return wrapper;\n}\n\n\n// ============================================================================\n// Sub-path node builder\n// ============================================================================\n\nfunction buildSubpathNodes(\n leaf: PxNode,\n subpath: PxBezierPath,\n pathLengthPx: number,\n startOffsetPct: number,\n minMaxOffset: [number, number],\n offsetRead: ReadPart<number>,\n rangeRead: ReadPart<Vec2>,\n ctx: ApplyContext,\n): Array<PxNode> {\n const offsetToDashOffset = makeOffsetToDashOffset(startOffsetPct, pathLengthPx, minMaxOffset);\n const rangeToDasharray = makeRangeToDasharray(pathLengthPx, minMaxOffset);\n\n const dashOffsetAttr = computeAnimAttr(offsetRead, offsetToDashOffset);\n const dashArrayAttr = computeAnimAttr(rangeRead, rangeToDasharray);\n const strokeOpacityAttr = computeOpacityFromRange(rangeRead);\n\n const dStr = bezierToSvgPath(subpath);\n\n // Bare sub-path under the trim wrapper — fill / stroke / stroke-width are\n // inherited from the wrapper <g>. The empty-range hide uses `stroke-opacity`\n // (STROKE only), so the fill stays visible without a fill-only twin.\n const base = makeBareSubpath(dStr);\n applyAttr(base, 'strokeDasharray', dashArrayAttr);\n applyAttr(base, 'strokeDashoffset', dashOffsetAttr);\n applyAttr(base, 'strokeOpacity', strokeOpacityAttr);\n\n return [base];\n}\n\n/** Collapsed single-subpath form: the trim host stays a single `<path>` (its own\n * `fill` / `stroke` / `transform` / `id` preserved); the trim stroke attrs are\n * applied directly. */\nfunction collapseLeafWithTrim(\n leaf: PxNode,\n pathLengthPx: number,\n startOffsetPct: number,\n minMaxOffset: [number, number],\n offsetRead: ReadPart<number>,\n rangeRead: ReadPart<Vec2>,\n): PxNode {\n const offsetToDashOffset = makeOffsetToDashOffset(startOffsetPct, pathLengthPx, minMaxOffset);\n const rangeToDasharray = makeRangeToDasharray(pathLengthPx, minMaxOffset);\n\n const node: PxNode = { ...leaf };\n delete node.effects;\n applyAttr(node, 'strokeDasharray', computeAnimAttr(rangeRead, rangeToDasharray));\n applyAttr(node, 'strokeDashoffset', computeAnimAttr(offsetRead, offsetToDashOffset));\n applyAttr(node, 'strokeOpacity', computeOpacityFromRange(rangeRead));\n return node;\n}\n\n/** Fresh `<path>` carrying only the sub-path geometry. Presentation attrs\n * (`fill`, `stroke`, `stroke-width`, `transform`, `id`, …) stay on the wrapper\n * `<g>` and are inherited — bare `<path>`s under a single attrs-bearing `<g>`. */\nfunction makeBareSubpath(dStr: string): PxNode {\n return { type: 'path', d: dStr };\n}\n\n\n// ============================================================================\n// Math\n// ============================================================================\n\nconst SMALL_PADDING_PX = 1;\n\n/** Produces a px dashoffset from a parametric offset. */\nfunction makeOffsetToDashOffset(\n startOffsetPct: number,\n pathLengthPx: number,\n minMaxOffset: [number, number],\n): (offsetVal: number) => number {\n const [minIdx] = getOffsetIndexRange(minMaxOffset);\n return offsetVal => pathLengthPx * (-offsetVal - minIdx + startOffsetPct) + SMALL_PADDING_PX;\n}\n\n/** Produces a px dash pattern of the form `[0, gap, dash, gap, dash, ..., gap]`\n * repeated so the offset can wrap. */\nfunction makeRangeToDasharray(\n pathLengthPx: number,\n minMaxOffset: [number, number],\n): (rangeVal: Vec2) => Array<number> {\n const [minIdx, maxIdx] = getOffsetIndexRange(minMaxOffset);\n const repeats = maxIdx - minIdx + 1;\n return (rangeVal: Vec2) => {\n const a = clamp(rangeVal[0], 0, 1);\n const b = clamp(rangeVal[1], 0, 1);\n const minR = Math.min(a, b);\n const maxR = Math.max(a, b);\n const out: Array<number> = [0];\n let gap = SMALL_PADDING_PX;\n for (let i = 0; i < repeats; i++) {\n out.push(gap + minR * pathLengthPx); // GAP\n out.push((maxR - minR) * pathLengthPx); // DASH\n gap = (1 - maxR) * pathLengthPx;\n }\n out.push(gap + SMALL_PADDING_PX); // closing GAP\n return out;\n };\n}\n\n/** Floor/ceil of the negated min/max offset → integer dash-repeat index range. */\nfunction getOffsetIndexRange(minMaxOffset: [number, number]): [number, number] {\n return [\n Math.floor(Math.min(-minMaxOffset[0], -minMaxOffset[1])),\n Math.ceil(Math.max(-minMaxOffset[0], -minMaxOffset[1])),\n ];\n}\n\n\n// ============================================================================\n// Animatable plumbing\n// ============================================================================\n\ntype AnimAttrResult<TOut> =\n | { kind: ReadKind.Static; value: TOut }\n | { kind: ReadKind.Animated; keyframes: Array<PxKeyframe>; loop?: PxLoop | boolean }\n | undefined;\n\nfunction readScalarValues(r: ReadPart<number>): Array<number> {\n if (r.kind === ReadKind.Absent) return [];\n if (r.kind === ReadKind.Static) return [r.value];\n const out: Array<number> = [];\n for (const kf of r.keyframes) {\n const v = kf.value ?? kf.v;\n if (typeof v === 'number') out.push(v);\n }\n return out;\n}\n\nfunction computeAnimAttr<TIn, TOut>(read: ReadPart<TIn>, map: (v: TIn) => TOut): AnimAttrResult<TOut> {\n if (read.kind === ReadKind.Absent) return undefined;\n if (read.kind === ReadKind.Static) return { kind: ReadKind.Static, value: map(read.value) };\n return {\n kind: ReadKind.Animated,\n keyframes: read.keyframes.map(kf => ({\n time: kf.time ?? kf.t ?? 0,\n value: map((kf.value ?? kf.v) as TIn),\n easing: kf.easing ?? kf.e,\n })),\n loop: read.loop,\n };\n}\n\nfunction applyAttr<T>(node: PxNode, attrName: string, attr: AnimAttrResult<T>): void {\n if (!attr) return;\n if (attr.kind === ReadKind.Static) {\n node[attrName] = attr.value;\n return;\n }\n const prevAnimate = node.animate && typeof node.animate === 'object' && !Array.isArray(node.animate) ? node.animate : undefined;\n const animate: Record<string, any> = { ...(prevAnimate || {}) };\n const block: { keyframes: Array<PxKeyframe>, loop?: PxLoop | boolean } = { keyframes: attr.keyframes };\n if (attr.loop !== undefined) block.loop = attr.loop;\n animate[attrName] = block;\n node.animate = animate;\n // ALSO write the first kf's value as a STATIC attribute. The animator only\n // pushes the animated value to the DOM on its first rAF tick — if a caller\n // snapshots the DOM in the window between `play()` and that first tick\n // (e.g. visual-tests live-mode sample at t=0), the element renders with\n // DEFAULT stroke styling (no dash, full opacity), which would expose the\n // entire stroked path even when the t=0 kf says it should be hidden /\n // mostly-dashed. Mirroring the SVG convention of \"static baseline +\n // animation\" makes the pre-tick DOM render match the kf-at-time-0 value.\n const firstKf = attr.keyframes[0];\n if (firstKf && (firstKf.value ?? (firstKf as any).v) !== undefined) {\n node[attrName] = firstKf.value ?? (firstKf as any).v;\n }\n}\n\n/** Width (ms) of the opacity transition emitted at each hide↔show boundary\n * (one SVGA frame = 10 ms at the 100 fps SVGA grid). */\nconst OPACITY_STEP_MS = 10;\n\n/** Empty-range opacity (hide when `startEnd[0] === startEnd[1]`).\n * Static: single 0 if hide always; undefined otherwise.\n * Animated: step-jump kfs at each hide↔show transition (~one SVGA frame\n * wide so the renderer doesn't briefly show the stroke between an empty\n * range and the first non-empty kf at wall-clock t≈0). */\nfunction computeOpacityFromRange(rangeRead: ReadPart<Vec2>): AnimAttrResult<number> {\n const hide = (v: Vec2): boolean => v[0] === v[1];\n\n if (rangeRead.kind === ReadKind.Absent) return undefined;\n if (rangeRead.kind === ReadKind.Static) return hide(rangeRead.value) ? { kind: ReadKind.Static, value: 0 } : undefined;\n\n const kfs = rangeRead.keyframes;\n let anyHide = false;\n let allHide = true;\n for (const kf of kfs) {\n if (hide((kf.value ?? kf.v) as Vec2)) anyHide = true;\n else allHide = false;\n }\n if (!anyHide) return undefined;\n if (allHide) return { kind: ReadKind.Static, value: 0 };\n\n // Prev/next-aware emitter — only inserts kfs at the transitions to keep the\n // wire compact.\n const out: Array<PxKeyframe> = [];\n for (let i = 0; i < kfs.length; i++) {\n const kf = kfs[i];\n const prevKf = i > 0 ? kfs[i - 1] : undefined;\n const nextKf = i < kfs.length - 1 ? kfs[i + 1] : undefined;\n const t = kf.time ?? kf.t ?? 0;\n const thisHide = hide((kf.value ?? kf.v) as Vec2);\n const prevHide = prevKf ? thisHide && hide((prevKf.value ?? prevKf.v) as Vec2) : thisHide;\n const nextHide = nextKf ? thisHide && hide((nextKf.value ?? nextKf.v) as Vec2) : thisHide;\n\n if (prevHide && !nextHide) {\n out.push({ time: t, value: 0 });\n out.push({ time: t + OPACITY_STEP_MS, value: 1 });\n } else if (!prevHide && nextHide) {\n out.push({ time: t - OPACITY_STEP_MS, value: 1 });\n out.push({ time: t, value: 0 });\n }\n }\n if (out.length <= 1) return undefined;\n return { kind: ReadKind.Animated, keyframes: out };\n}\n\n\n// ============================================================================\n// Range cross-over\n// ============================================================================\n\ninterface SimpleKf { time: number; value: Vec2; easing?: any; }\n\n/** Reads `range` and, when the kf sequence has `value[0] > value[1]` anywhere,\n * inserts crossing-point keyframes (bisection-located) and swaps any\n * remaining reversed kfs so every emitted range satisfies `range[0] ≤ range[1]`. */\nfunction readRangeWithCrossings(raw: PxAnimatable<Vec2> | undefined): ReadPart<Vec2> {\n const r = readAnimatable<Vec2>(raw);\n if (r.kind !== ReadKind.Animated) return r;\n\n const kfs: Array<SimpleKf> = r.keyframes.map(kf => ({\n time: kf.time ?? kf.t ?? 0,\n value: (kf.value ?? kf.v) as Vec2,\n easing: kf.easing ?? kf.e,\n }));\n\n const hasReverse = kfs.some(kf => kf.value[0] > kf.value[1]);\n if (!hasReverse) {\n return {\n kind: ReadKind.Animated,\n keyframes: kfs.map(kf => ({ time: kf.time, value: kf.value, easing: kf.easing })),\n };\n }\n\n const crossingTimes: Array<number> = [];\n for (let i = 1; i < kfs.length; i++) {\n const prev = kfs[i - 1];\n const cur = kfs[i];\n const dPrev = prev.value[1] - prev.value[0];\n const dCur = cur.value[1] - cur.value[0];\n if (dPrev * dCur < 0) {\n const t = bisectionForRangeCrossing(prev, cur);\n if (t !== null && t > prev.time && t < cur.time) {\n crossingTimes.push(Math.round(t));\n }\n }\n }\n const uniqueTs = Array.from(new Set(crossingTimes)).sort((a, b) => a - b);\n\n const out: Array<SimpleKf> = [];\n let j = 0;\n for (const kf of kfs) {\n while (j < uniqueTs.length && uniqueTs[j] < kf.time) {\n const t = uniqueTs[j++];\n const v = interpolateRangeAt(kfs, t);\n const m = (v[0] + v[1]) / 2;\n out.push({ time: t, value: [m, m] });\n }\n const v: Vec2 = kf.value[0] > kf.value[1] ? [kf.value[1], kf.value[0]] : kf.value;\n out.push({ time: kf.time, value: v, easing: kf.easing });\n }\n while (j < uniqueTs.length) {\n const t = uniqueTs[j++];\n const v = interpolateRangeAt(kfs, t);\n const m = (v[0] + v[1]) / 2;\n out.push({ time: t, value: [m, m] });\n }\n\n return { kind: ReadKind.Animated, keyframes: out };\n}\n\nfunction bisectionForRangeCrossing(prev: SimpleKf, cur: SimpleKf): number | null {\n const f = (t: number): number => {\n const a = (t - prev.time) / (cur.time - prev.time);\n const v0 = prev.value[0] + (cur.value[0] - prev.value[0]) * a;\n const v1 = prev.value[1] + (cur.value[1] - prev.value[1]) * a;\n return v1 - v0;\n };\n let lo = prev.time, hi = cur.time;\n let fLo = f(lo);\n if (fLo === 0) return lo;\n const fHi = f(hi);\n if (fHi === 0) return hi;\n if (fLo * fHi > 0) return null;\n for (let i = 0; i < 100; i++) {\n const mid = (lo + hi) / 2;\n const fMid = f(mid);\n if (fMid === 0 || Math.abs(hi - lo) < 0.0001) return mid;\n if (fLo * fMid < 0) { hi = mid; }\n else { lo = mid; fLo = fMid; }\n }\n return (lo + hi) / 2;\n}\n\nfunction interpolateRangeAt(kfs: Array<SimpleKf>, t: number): Vec2 {\n if (t <= kfs[0].time) return kfs[0].value;\n if (t >= kfs[kfs.length - 1].time) return kfs[kfs.length - 1].value;\n for (let i = 1; i < kfs.length; i++) {\n if (t <= kfs[i].time) {\n const prev = kfs[i - 1];\n const cur = kfs[i];\n const a = (t - prev.time) / (cur.time - prev.time);\n return [\n prev.value[0] + (cur.value[0] - prev.value[0]) * a,\n prev.value[1] + (cur.value[1] - prev.value[1]) * a,\n ];\n }\n }\n return kfs[kfs.length - 1].value;\n}\n\n\n// ============================================================================\n// Geometry helpers\n// ============================================================================\n\n/** Total arc length of a `PxBezierPath` (sum of per-segment LUT lengths). */\nfunction pxBezierPathLength(path: PxBezierPath): number {\n const v = path.v;\n if (!v || v.length < 2) return 0;\n let total = 0;\n for (let i = 0; i < v.length - 1; i++) {\n total += segmentLength(path, i, i + 1);\n }\n if (path.c && v.length > 1) {\n total += segmentLength(path, v.length - 1, 0);\n }\n return total;\n}\n\nfunction segmentLength(path: PxBezierPath, from: number, to: number): number {\n const v = path.v;\n const p0 = v[from] as [number, number];\n const p3 = v[to] as [number, number];\n const p1 = (path.o?.[from] ?? p0) as [number, number];\n const p2 = (path.i?.[to] ?? p3) as [number, number];\n const lut = bezier2D_arcLengthLUT(p0, p1, p2, p3);\n return lut.ds[lut.ds.length - 1];\n}\n\n/**\n * Cubic-bezier control-point ratio for a quarter arc — the standard circle\n * approximation (max radial error ≈ 0.02%, far below stroke-dash precision).\n */\nconst ARC_KAPPA = 0.5522847498307936;\n\n/**\n * A primitive shape -> outline path `d`, for shapes that carry no `d` of their own.\n * Returns undefined for unsupported types.\n *\n * Start point and winding MATCH the shape's own SVG parameterisation, because the\n * measured length feeds a `stroke-dasharray` that the browser then walks along that\n * very parameterisation — a mismatched start would put the visible trim window in\n * the wrong place.\n *\n * - `<rect>` from `(x+w, y)`, clockwise. Emits the explicit closing-line\n * vertex (`L x0,y0`) before `z`.\n * - `<ellipse>`/`<circle>` from `(cx+rx, cy)` clockwise as four cubic quarters — the\n * SVG-spec equivalent path, which the UA also uses for dashing.\n */\nfunction shapeToPathD(node: PxNode): string | undefined {\n if (node.type === 'rect') {\n const x = Number(node.x ?? 0), y = Number(node.y ?? 0);\n const w = Number(node.width ?? 0), h = Number(node.height ?? 0);\n return 'M' + (x + w) + ',' + y +\n 'L' + (x + w) + ',' + (y + h) +\n 'L' + x + ',' + (y + h) +\n 'L' + x + ',' + y +\n 'L' + (x + w) + ',' + y + 'z';\n }\n\n if (node.type === 'ellipse' || node.type === 'circle') {\n const cx = Number(node.cx ?? 0), cy = Number(node.cy ?? 0);\n const rx = node.type === 'circle' ? Number(node.r ?? 0) : Number(node.rx ?? 0);\n const ry = node.type === 'circle' ? Number(node.r ?? 0) : Number(node.ry ?? 0);\n if (!(rx > 0) || !(ry > 0)) return undefined;\n const kx = rx * ARC_KAPPA, ky = ry * ARC_KAPPA;\n const c = (x1: number, y1: number, x2: number, y2: number, x: number, y: number) =>\n 'C' + x1 + ',' + y1 + ' ' + x2 + ',' + y2 + ' ' + x + ',' + y;\n return 'M' + (cx + rx) + ',' + cy +\n c(cx + rx, cy + ky, cx + kx, cy + ry, cx, cy + ry) +\n c(cx - kx, cy + ry, cx - rx, cy + ky, cx - rx, cy) +\n c(cx - rx, cy - ky, cx - kx, cy - ry, cx, cy - ry) +\n c(cx + kx, cy - ry, cx + rx, cy - ky, cx + rx, cy) + 'z';\n }\n\n return undefined;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\n/**\n * Lightweight, dependency-free applier for \"player-effects\" SVGA JSON.\n *\n * Input: the JSON produced by `SvgaJsonWithPlayerEffectsSerialisationUtil`, where\n * structure-creating effects are left UN-applied on `node.effects`. This module\n * reads those effects and MATERIALISES them into a plain node tree (extra `<g>`\n * wrappers, copies, mask defs) that renders identically to the heavy editor path.\n *\n * Design goals (intentional): minimal, transparent, no merging/optimisation. It\n * is fine to emit more nodes than strictly necessary — the only contract is \"same\n * result on screen\". Each effect lives in its own file; this module only wires\n * them into the recursion. Nothing here imports outside `effects/`, so the whole\n * folder can move into the Player codebase verbatim.\n */\n\nimport { identifyContentRefTargets, splitForContentRef } from './contentRefSplit';\nimport { applyFillGradientEffect, applyStrokeGradientEffect } from './gradientEffect';\nimport { applyClipPathEffect } from './clipPathEffect';\nimport { applyMaskedByEffect, collectMaskAncestorChains } from './maskedByEffect';\nimport { applyRefAndTransformationEffect, applyRefHref } from './refEffect';\nimport { applyRepeaterEffect } from './repeaterEffect';\nimport { applyAllRetimeEffects } from './retimeEffect';\nimport { applyTextPathEffect } from './textPathEffect';\nimport { applyTextGlyphsAlongPath, applyTextGlyphsEffect } from './textGlyphsEffect';\nimport { applyTrimPathEffect } from './trimPathEffect';\nimport { getAnimatorConfig, getDefs, PxAnimatorEngine, PxAnimatorMode } from '../PxAnimatorTypes';\nimport type { PxNode } from '../PxAnimatorTypes';\nimport type { ApplyContext, ApplyResult } from './types';\nimport { clone, genId, indexById, spliceDefs } from './util';\n\nexport type { PxNode } from '../PxAnimatorTypes';\nexport type { ApplyResult } from './types';\n\n\n/**\n * Applies all player-effects in `root` and returns a materialised copy plus any\n * generated <defs> nodes, warnings and errors. `root` is not mutated.\n *\n * Two passes:\n * 1. `applyPlayerEffects_exceptRetime` — materialises every effect except retime.\n * 2. `applyPlayerEffects_retime` — applies retime, cloning the NOW-materialised\n * subtrees so retimed `<use>`s see the same wrappers/animations the heavy\n * editor path would produce.\n *\n * Pre-pass identifies every element that is the target of a `<use>` with\n * `ref:{type:'content'}` and allocates a fresh \"inner\" id for it; pass 1 then\n * splits those sources into outer-translate + inner-content layers so the use\n * can target the inner layer.\n */\nexport function applyPlayerEffects(root: PxNode): ApplyResult {\n const ctx: ApplyContext = {\n defs: [], warnings: [], errors: [],\n idMap: new Map(), nextId: 0,\n contentRefInnerIds: new Map(),\n maskAncestorChains: new Map(),\n // Resolved engine: `frames` ONLY when explicitly set; auto/webapi/unset →\n // webapi (we're not 100% sure it's frames, and CSS/WAAPI need the inline form).\n engine: getAnimatorConfig(root)?.mode === PxAnimatorMode.frames\n ? PxAnimatorEngine.frames\n : PxAnimatorEngine.webapi,\n glyphs: getDefs(root)?.glyphs,\n };\n\n const working = clone(root);\n indexById(working, ctx.idMap);\n identifyContentRefTargets(working, ctx, () => genId(ctx, 'inner'));\n collectMaskAncestorChains(working, ctx);\n\n const afterPass1 = applyPlayerEffects_exceptRetime(working, ctx);\n const out = applyPlayerEffects_retime(afterPass1, ctx);\n spliceDefs(out, ctx.defs);\n\n return { root: out, defs: ctx.defs, warnings: ctx.warnings, errors: ctx.errors };\n}\n\n/**\n * Pass 1 — materialise every effect except retime. Retime is preserved on the\n * original (now wrapped-inner) node so pass 2 can find and apply it.\n *\n * After wrapping, the outer-most wrapper for a node with `originalId` is written\n * back into `ctx.idMap` so retime's clone target picks up the FULL materialised\n * subtree, not the bare un-wrapped original.\n *\n * If the node is a content-ref target, `splitForContentRef` re-shapes the\n * materialised result into outer-translate + inner-rest layers — the outer keeps\n * the original id, the inner gets the pre-allocated inner id so the `<use>` can\n * target it.\n */\nfunction applyPlayerEffects_exceptRetime(node: PxNode, ctx: ApplyContext): PxNode {\n if (node.children) node.children = node.children.map(child => applyPlayerEffects_exceptRetime(child, ctx));\n\n const fx = node.effects;\n const originalId = typeof node.id === 'string' ? node.id : undefined;\n const innerIdForContentRef = originalId ? ctx.contentRefInnerIds.get(originalId) : undefined;\n\n if (!fx && !innerIdForContentRef) return node;\n\n const { transformation, repeater, maskedBy, clipPath, trimPath, clone: cloneFx, fillGradient, strokeGradient, textPath, text } = fx ?? {};\n const isCombinedShape = fx?.isCombinedShape;\n if (fx) delete node.effects;\n\n let n = node;\n // Glyph text: replace the <text>/<tspan> subtree with baked <path> outlines\n // BEFORE any wrapper. Along-path glyphs place+rotate each glyph to the\n // referenced path's tangent; plain glyphs lay out horizontally.\n let consumedByGlyphs = false;\n if (text?.useGlyphs) {\n if (textPath) {\n // Path geometry is INLINE (`textPath.path`) — no `<path>` def lookup.\n const pathD = typeof textPath.path === 'string' ? textPath.path : undefined;\n // textLength passes through as a full PxAnimatable — static stretches the\n // run; animated re-spaces the glyphs over time (same per-glyph sampled\n // keyframe machinery as animated startOffset).\n const glyphed = applyTextGlyphsAlongPath(n, ctx, pathD, textPath.startOffset, textPath.textLength, textPath.pathOverflow);\n if (glyphed) { n = glyphed; consumedByGlyphs = true; } // native textPath NOT applied\n } else {\n n = applyTextGlyphsEffect(n, text, ctx);\n consumedByGlyphs = true;\n }\n }\n // textPath wraps the host's own children in a `<textPath>` — must run BEFORE any\n // structural wrapper (trim/repeater/mask) so the wrapping happens on the un-cloned\n // content first. Skipped when glyphs consumed it.\n if (!consumedByGlyphs) n = applyTextPathEffect(n, textPath, ctx);\n // Paint-gradient defs are minted FIRST, before any structural wrapper —\n // the gradient effect sits on the innermost element (alongside its `fill`\n // / `stroke` body attrs), so it must materialise before trim/repeater/\n // mask wrap around it. `<linearGradient>` defs themselves don't get\n // wrapped — they live in `ctx.defs` independent of the structure walk.\n n = applyFillGradientEffect(n, fillGradient, ctx);\n n = applyStrokeGradientEffect(n, strokeGradient, ctx);\n n = applyTrimPathEffect(n, trimPath, isCombinedShape, ctx); // innermost shape\n n = applyRepeaterEffect(n, repeater, ctx);\n n = applyMaskedByEffect(n, maskedBy, transformation, ctx); // mask sits on inner element\n n = applyClipPathEffect(n, clipPath, ctx); // clip-path ref on the element\n\n if (innerIdForContentRef) {\n // This node is the SOURCE of a content-ref `<use>` → split into\n // outer-translate + inner-rest + bare element so the use can target the\n // inner layer. But it may ALSO be a content-ref CONSUMER itself (a\n // `<use>` that both references content and is referenced — the nested\n // case): rewrite its OWN ref href first so the split moves a resolved\n // body inward, not the dangling editor-side content id.\n applyRefHref(n, cloneFx, ctx);\n n = splitForContentRef(n, transformation, originalId!, innerIdForContentRef, ctx);\n } else {\n n = applyRefAndTransformationEffect(n, cloneFx, transformation, ctx);\n }\n\n // Hand off the retime slice to pass 2 (keeps it nested under `clone`). The\n // ref part (type/baseId) was consumed above.\n if (cloneFx?.retime) node.effects = { clone: { retime: cloneFx.retime } };\n if (originalId) ctx.idMap.set(originalId, n); // outer wrapper is the clone target\n return n;\n}\n\n/** Pass 2 — apply retime to every `<use>` that carries it. Follows the\n * materialised `<use>.href` (not the editor-side `retime.baseId`). */\nfunction applyPlayerEffects_retime(node: PxNode, ctx: ApplyContext): PxNode {\n applyAllRetimeEffects(node, ctx);\n return node;\n}\n\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n/**\n * Single-call materialisation pipeline.\n *\n * Runs the full sequence of document-level transformations that turn the\n * wire-format `PxAnimatedSvgDocument` into a flat tree any renderer can\n * consume. The player itself calls this from `createAnimatorImpl`; the same\n * function is exported for the Editor (or any external caller) so the\n * Editor's flat-export path is GUARANTEED to be byte-identical to what the\n * player sees internally — no parallel pipeline to drift.\n *\n * 1. `applyPlayerEffects` — `node.effects` (ref / transformation / repeater /\n * maskedBy / trimPath / retime) materialised into wrappers, defs, clones.\n * 2. `materialiseInternalLoopsInTree` — every `propAnim.loop` expanded into\n * repeated keyframes filling the duration.\n * 3. `materialiseMotionPathsInTree` — `transform` kfs with tangents +\n * `autoOrient` flattened into sampled `{translate, rotate}` kfs. Only\n * for `engine === webapi` — frames-mode keeps the parametric form and\n * evaluates per frame for max spatial fidelity.\n * 4. `materialiseAnimatedUseInstances` — `<use>` referencing an animated\n * subtree replaced with a `<g>` carrying a deep clone (fresh ids).\n * Only for `engine === webapi` — frames-mode updates source attrs\n * per frame, which propagate through `<use>` shadow trees natively.\n *\n * Immutable: input doc is never mutated. Steps that didn't apply (the engine\n * gating or \"nothing to do\" early-outs) return the input by reference.\n */\n\nimport { applyPlayerEffects } from './effects/PlayerEffectsUtil';\nimport { DEFAULT_DURATION_MS } from './PxAnimatorUtil';\nimport { materialiseInternalLoopsInTree } from './PxDefinitions';\nimport { materialiseMotionPathsInTree } from './PxMotionPath';\nimport type { MotionPathMaterialisationOptions } from './PxMotionPath';\nimport { getAnimatorConfig, PxAnimatorEngine } from './PxAnimatorTypes';\nimport type { PxAnimatedSvgDocument, PxNode } from './PxAnimatorTypes';\nimport { materialiseAnimatedUseInstances } from './PxAnimatorUseMaterialiser';\n\n\n/** Options accepted by {@link materialiseAllInTree}. Mostly forwarded to the\n * per-stage materialisers; ordering is fixed (see module doc). */\nexport interface MaterialiseAllOptions {\n /** Knobs forwarded to `materialiseMotionPathsInTree`. Only consulted for\n * `engine === webapi` — frames-mode skips that stage entirely. */\n motionPath?: MotionPathMaterialisationOptions;\n}\n\n\nexport function materialiseAllInTree(\n doc: PxAnimatedSvgDocument,\n engine: PxAnimatorEngine,\n opts?: MaterialiseAllOptions,\n): PxAnimatedSvgDocument {\n // 1. Effects → structural materialisation. Always runs; returns a fresh root.\n let root = applyPlayerEffects(doc).root as PxAnimatedSvgDocument;\n\n // 2. Loops → flat repeated keyframes. Always runs (both engines need flat\n // kfs covering the duration; per-binding expansion in\n // `normalizeKeyframes` becomes a no-op once the loop field is consumed).\n const duration = getAnimatorConfig(root)?.duration ?? DEFAULT_DURATION_MS;\n root = materialiseInternalLoopsInTree(root, duration);\n\n if (engine === PxAnimatorEngine.webapi) {\n // 3. Motion-along-path → sampled `{translate, rotate}` kfs. WAAPI can't\n // evaluate parametric tangents; frames-mode does that per frame so\n // we skip this for frames.\n root = materialiseMotionPathsInTree(root, opts?.motionPath);\n\n // 4. <use> referencing animated subtrees → <g> wrapping a fresh clone.\n // WAAPI / CSS animations don't reliably propagate through SVG <use>\n // shadow trees in Chrome / Safari; frames-mode updates source\n // attributes per frame and the shadow tree picks those up natively.\n root = materialiseAnimatedUseInstances(root);\n\n // 5. Prune <defs> `<g>`/`<symbol>` entries that step 4 orphaned — i.e. no\n // `<use>` references them any more (the animated uses that did got\n // inlined into `<g>`+clones). webapi-only: frames keeps `<use href>`,\n // so nothing is orphaned there.\n root = pruneUnreferencedDefs(root);\n }\n\n return root;\n}\n\n\n/**\n * Removes orphaned `<defs>` entries: direct `<defs>` children of type `<g>` /\n * `<symbol>` whose `id` is no longer targeted by ANY `<use href>` in the tree.\n * Runs after step 4 (`materialiseAnimatedUseInstances`), which inlines animated\n * `<use>`s and thereby leaves their former defs targets unreferenced.\n *\n * Loops to a fixpoint so chains collapse fully: pruning an entry can drop the\n * `<use>`s inside it, which in turn orphans the entries THOSE referenced. The\n * loop also drops a `<defs>` node once pruning has emptied it.\n *\n * Scope is intentionally limited to `<g>`/`<symbol>` (the `<use>`-target element\n * types) so `url(#…)`-referenced defs (gradients / masks / clipPaths / filters)\n * are never touched. Mutates `root` in place — safe, as it's a freshly\n * materialised tree owned by {@link materialiseAllInTree}.\n */\nfunction pruneUnreferencedDefs(root: PxAnimatedSvgDocument): PxAnimatedSvgDocument {\n const stripHash = (h: string): string => (h.startsWith('#') ? h.slice(1) : h);\n const walk = (n: PxNode, fn: (n: PxNode) => void): void => { fn(n); n.children?.forEach(c => walk(c, fn)); };\n\n let changed = true;\n while (changed) {\n changed = false;\n const referenced = new Set<string>();\n walk(root, n => {\n if (n.type === 'use' && typeof n.href === 'string') referenced.add(stripHash(n.href));\n });\n walk(root, n => {\n if (!n.children) return;\n let kept = n.children;\n // (a) inside <defs>: drop <g>/<symbol> entries no <use> targets any more\n if (n.type === 'defs') {\n kept = kept.filter(c =>\n !((c.type === 'g' || c.type === 'symbol') && typeof c.id === 'string' && !referenced.has(c.id)));\n }\n // (b) anywhere: drop a now-empty <defs> child\n kept = kept.filter(c => !(c.type === 'defs' && (!c.children || c.children.length === 0)));\n if (kept.length !== n.children.length) { n.children = kept; changed = true; }\n });\n }\n return root;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { getAnimatorConfig, PxAnimatorEngine, type PxAnimatedSvgDocument, type PxAnimatorAPI, type PxAnimatorCallbacksConfig } from './PxAnimatorTypes';\nimport { camelCaseToKebabWordIfNeeded, clamp, DEFAULT_DURATION_MS, STYLE_ATTR_NAMES } from './PxAnimatorUtil';\nimport { calcAnimationValues, getNormalisedBindings } from './PxDefinitions';\n\n\n// Frame scheduling — resolved LAZILY from globalThis on every call so test\n// harnesses that install fake timers (and hosts that polyfill rAF late) are\n// honoured. Falls back to a ~60fps setTimeout when rAF is unavailable.\nfunction requestFrame(cb: () => void): number {\n const g: any = globalThis as any;\n if (typeof g.requestAnimationFrame === 'function') return g.requestAnimationFrame(cb);\n return g.setTimeout(cb, 16) as unknown as number;\n}\n\nfunction cancelFrame(handle: number): void {\n const g: any = globalThis as any;\n if (typeof g.cancelAnimationFrame === 'function') { g.cancelAnimationFrame(handle); return; }\n g.clearTimeout(handle);\n}\n\n/**\n * Platform adapter interface for abstracting platform-specific operations.\n */\nexport interface PxPlatformAdapter {\n\n /** Check if the root element is still connected/mounted */\n isConnected(): boolean;\n\n /** Set an attribute on an element by id */\n setAttribute(id: string, attrName: string, value: string): void;\n}\n\n/**\n * Creates an animator instance that uses a frame loop for animations.\n * This is the abstract/platform-agnostic version.\n *\n * @param adapter Platform adapter for DOM/environment operations.\n * @param callbacks Optional lifecycle callbacks.\n * @returns A PxAnimatorAPI instance.\n */\nexport function createBasicFrameLoopAnimator(\n doc: PxAnimatedSvgDocument,\n adapter: PxPlatformAdapter,\n callbacks?: PxAnimatorCallbacksConfig\n): PxAnimatorAPI {\n\n const config = getAnimatorConfig(doc) || {};\n\n const bindings = getNormalisedBindings(doc, PxAnimatorEngine.frames);\n\n // iterations: either number or Infinity\n const _iterations = config.iterations;\n let iterations: number = 1;\n if (typeof _iterations === 'number') iterations = _iterations || 1;\n if (_iterations === 'infinite') iterations = Infinity;\n if (iterations < 1) iterations = 1;\n\n const duration = +(config.duration || DEFAULT_DURATION_MS); // per-iteration duration (ms), cannot be 0!\n const totalDuration = duration && iterations ?\n duration * (iterations === Infinity ? Infinity : iterations) :\n (duration ? (iterations ?? 1) * duration : 0);\n\n // direction handling\n const direction = config.direction || 'normal'; // 'normal' | 'reverse' | 'alternate' | 'alternate-reverse'\n\n // fill handling — mirrors the Web Animations API `fill` semantics as closely\n // as a frame-writer can. Default 'forwards' (hold final state) matches the\n // webapi engine and the config doc.\n const fill = config.fill ?? 'forwards';\n const fillsForwards = fill === 'forwards' || fill === 'both';\n const fillsBackwards = fill === 'backwards' || fill === 'both';\n\n ////////////////////////////////////////////////////////////////\n\n let timerId: number | null = null;\n let playing = false;\n\n // Accumulated logical time before the current run (ms). A positive\n // config.delay means \"wait before starting\" → the animation starts at\n // NEGATIVE logical time and reaches 0 after `delay` ms (same convention as\n // the Web Animations API). A negative config.delay means \"seek into the\n // animation\" → positive start time.\n let timeBeforeLastStartMs = -(config.delay || 0);\n let lastStartedTs = 0; // timestamp when last started/resumed\n let playbackRate = 1;\n\n let finishCalled = false; // ensures onFinish called once\n\n // Frame rate throttling\n const frameRate = config.frameRate;\n const minFrameIntervalMs = frameRate && frameRate > 0 ? 1000 / frameRate : 0;\n let lastRenderTs = 0; // timestamp of last render\n\n // Raw logical time — may be negative during the delay phase; not clamped\n // to the [0, totalDuration] range at the top end either. Internal use only.\n const getRawAnimTime = () => {\n // compute effective elapsed time (ms), taking playbackRate into account\n const runningElapsed = lastStartedTs ? (Date.now() - lastStartedTs) * playbackRate : 0;\n return timeBeforeLastStartMs + runningElapsed;\n };\n\n const getAnimCurrentTime = () => {\n let time = getRawAnimTime();\n\n // clamp to [0, totalDuration]\n if (Number.isFinite(totalDuration) && time > (totalDuration as number)) time = totalDuration as number;\n if (time < 0) time = 0;\n return time;\n };\n\n\n ////////////////////////////////////////////////////////////////\n\n\n // separate render function that uses a given currentTime (ms)\n function renderFrame(currentTimeMs: number) {\n\n function getEffectiveProgress() {\n // If no duration or duration === 0, set iteration/progress accordingly\n const safeDuration = duration > 0 ? duration : 1; // avoid division by zero\n\n let rawProgress = 0;\n let iteration = 0;\n if (duration > 0) {\n\n // rawProgress is normalized progress within the current iteration:\n // - first iteration: [0 .. 1]\n // - following iterations: (0 .. 1]\n //\n // iteration is the zero-based iteration index\n //\n // Examples (safeDuration = 3):\n // currentTimeMs = 0 → rawProgress = 0 , iteration = 0\n // currentTimeMs = 3 → rawProgress = 1 , iteration = 0\n // currentTimeMs = 3.0001 → rawProgress = 0.0001 , iteration = 1\n\n currentTimeMs = clamp(currentTimeMs, 0, iterations * safeDuration);\n\n iteration = Math.max(0, Math.ceil(currentTimeMs / safeDuration) - 1);\n iteration = Math.min(iteration, iterations - 1);\n\n // Time elapsed since the start of the current iteration\n const iterationTime = currentTimeMs - iteration * safeDuration;\n\n // Normalized progress (preserves fractional overflow after boundaries)\n rawProgress = clamp(iterationTime / safeDuration, 0, 1);\n } else {\n rawProgress = currentTimeMs; // We shouldn't be here\n }\n\n\n // compute per-iteration directional progress\n // start with baseProgress = rawProgress in [0,1)\n\n let baseProgress = rawProgress;\n // apply direction rules:\n // - normal: as is\n // - reverse: progress = 1 - baseProgress\n // - alternate: reverse on odd iterations\n // - alternate-reverse: reverse on even iterations\n const dir = direction || 'normal';\n let effectiveProgress = baseProgress;\n if (dir === 'reverse') {\n effectiveProgress = 1 - baseProgress;\n } else if (dir === 'alternate') {\n if (iteration % 2 === 1) effectiveProgress = 1 - baseProgress;\n } else if (dir === 'alternate-reverse') {\n // alternate-reverse: start reversed on iteration 0\n if (iteration % 2 === 0) effectiveProgress = 1 - baseProgress;\n } // else 'normal' -> keep\n return effectiveProgress;\n }\n let effectiveProgress = getEffectiveProgress(); // else 'normal' -> keep\n\n ////////////////////////////////////////////////////////////////\n\n // FIXME - pre-calc defs, then use\n\n for (const binding of bindings || []) {\n const animDef = binding.animate;\n if (!animDef || typeof animDef !== 'object' || Array.isArray(animDef)) {\n console.warn('Empty or unresolved binding', binding);\n continue;\n }\n\n // Calculate interpolated values for this binding's animation\n const computedValues = calcAnimationValues(animDef, effectiveProgress * duration);\n\n // Apply each computed attribute\n for (const [attrName, value] of Object.entries(computedValues)) {\n adapter.setAttribute(binding.id, attrName, value);\n }\n }\n }\n\n\n ////////////////////////////////////////////////////////////////\n\n const tick = () => {\n\n // if root element provided and detached, stop\n if (!adapter.isConnected()) {\n // stop animation loop (we'll let external code call play/resume)\n // do not call onFinish here. It's a detach situation.\n pauseAnim();\n return;\n }\n\n const currentTime = getAnimCurrentTime();\n\n // Delay phase (raw time < 0): the animation hasn't started yet.\n // With fill 'backwards'/'both' hold the first frame; otherwise leave\n // the element's static attributes untouched — mirrors WAAPI fill.\n // Checked BEFORE throttling so boundary states can't be skipped.\n const rawTime = getRawAnimTime();\n if (rawTime < 0 && playbackRate > 0) {\n if (fillsBackwards) renderFrame(0);\n return;\n }\n\n // Detect reverse playback reaching the start (natural end for rate < 0)\n // — mirrors WAAPI, where reverse playback fires `finish` at time 0.\n // pauseAnim runs FIRST (its trailing render must not clobber the\n // boundary frame rendered below).\n if (playbackRate < 0 && rawTime <= 0) {\n pauseAnim();\n renderFrame(0);\n if (!finishCalled) {\n finishCalled = true;\n callbacks?.onFinish?.();\n }\n return;\n }\n\n // Detect finished (natural end, forward playback)\n if (playbackRate > 0 && totalDuration && Number.isFinite(totalDuration) && currentTime >= (totalDuration as number)) {\n pauseAnim();\n // Render the end state — final frame when filling forwards, first\n // frame otherwise (closest frame-writer approximation of WAAPI\n // fill:'none'/'backwards', which reverts to the pre-animation state).\n renderFrame(fillsForwards ? (totalDuration as number) : 0);\n // call onFinish once\n if (!finishCalled) {\n finishCalled = true;\n callbacks?.onFinish?.();\n }\n return;\n }\n\n // Frame rate throttling: skip render if not enough time has passed.\n // Applies only to normal in-flight frames — boundary states above are\n // always rendered, so a throttled tick can never swallow the finish.\n if (minFrameIntervalMs > 0) {\n const now = Date.now();\n if (lastRenderTs && (now - lastRenderTs) < minFrameIntervalMs) {\n // Not enough time elapsed, skip this frame but continue the loop\n return;\n }\n lastRenderTs = now;\n }\n\n // Otherwise render normal frame\n renderFrame(currentTime);\n };\n\n\n ////////////////////////////////////////////////////////////////\n\n\n if (config.delay) {\n if (config.delay < 0) {\n // Negative delay = seek into the animation; render the seeked frame.\n renderFrame(getAnimCurrentTime());\n } else if (fillsBackwards) {\n // Positive delay = wait before start; hold the first frame only\n // when filling backwards (WAAPI convention).\n renderFrame(0);\n }\n }\n\n ////////////////////////////////////////////////////////////////\n\n const _isPlaying = () => {\n if (!playing) return false;\n if (!adapter.isConnected()) { return false; }\n if (playbackRate < 0) {\n // Reverse playback finishes when it reaches the start.\n return getRawAnimTime() > 0;\n }\n if (Number.isFinite(totalDuration) && getAnimCurrentTime() >= (totalDuration as number)) return false;\n return true;\n };\n\n const loopAnim = (isFirst?: boolean) => {\n if (timerId !== null) {\n cancelFrame(timerId);\n timerId = null;\n }\n\n if (!(isFirst || _isPlaying())) {\n // finished or not playing\n return;\n }\n\n timerId = requestFrame(() => {\n timerId = null;\n tick();\n loopAnim();\n });\n };\n\n const startAnim = () => {\n if (playing) return;\n\n // If the animation has already reached its natural end (for the current\n // playback direction), rewind to the opposite end before resuming —\n // mirrors the Web Animations API, where calling play() on a finished\n // animation auto-rewinds. Without this, resuming from the boundary\n // would re-finish on the first tick and leave the animation stuck.\n if (playbackRate >= 0) {\n if (Number.isFinite(totalDuration) && timeBeforeLastStartMs >= (totalDuration as number)) {\n timeBeforeLastStartMs = 0;\n }\n } else {\n // Reverse playback starting at (or before) the start: seek to the end.\n if (timeBeforeLastStartMs <= 0) {\n if (!Number.isFinite(totalDuration)) {\n // Cannot rewind to an infinite end (WAAPI throws here) —\n // warn and stay stopped instead of \"finishing\" instantly.\n console.warn('play: cannot start reverse playback of an infinite animation from time 0');\n return;\n }\n timeBeforeLastStartMs = totalDuration as number;\n }\n }\n\n // starting playback opens a new finish episode (mirrors WAAPI, where\n // play() always re-arms the finished promise / finish event)\n finishCalled = false;\n\n playing = true;\n lastStartedTs = Date.now();\n loopAnim(true);\n };\n\n const pauseAnim = () => {\n if (!playing) return;\n // Capture the RAW logical time — during the delay phase it is negative\n // and must stay negative, otherwise pausing would silently swallow the\n // remaining delay. Clamp only the top end.\n let raw = getRawAnimTime();\n if (Number.isFinite(totalDuration) && raw > (totalDuration as number)) raw = totalDuration as number;\n timeBeforeLastStartMs = raw;\n lastStartedTs = 0;\n playing = false;\n\n if (timerId !== null) {\n cancelFrame(timerId);\n timerId = null;\n }\n // Render a frame at the paused time to keep the DOM consistent —\n // except during the delay phase, where rendering would violate the\n // fill semantics (only 'backwards'/'both' show frame 0 before start).\n if (raw >= 0) {\n renderFrame(raw);\n } else if (fillsBackwards) {\n renderFrame(0);\n }\n };\n\n const cancelAnim = () => {\n pauseAnim();\n\n timeBeforeLastStartMs = 0;\n lastStartedTs = 0;\n playing = false;\n finishCalled = false;\n\n renderFrame(timeBeforeLastStartMs);\n\n callbacks?.onCancel?.();\n };\n\n const finishAnim = (callOnFinish = true) => {\n // jump to the end\n if (Number.isFinite(totalDuration)) {\n timeBeforeLastStartMs = totalDuration as number;\n } else {\n // infinity animations: set to current time (no-op)\n timeBeforeLastStartMs = getAnimCurrentTime();\n }\n lastStartedTs = 0;\n playing = false;\n // cancel any pending frame — pause/destroy early-return when not\n // playing, so a frame left queued here would never be cleaned up\n if (timerId !== null) {\n cancelFrame(timerId);\n timerId = null;\n }\n // Render the end state honouring `fill` (same rule as the natural\n // finish in `tick()`, and same as WAAPI where fill:'none' reverts even\n // after an explicit finish()).\n renderFrame(fillsForwards ? timeBeforeLastStartMs : 0);\n\n if (callOnFinish && !finishCalled) {\n finishCalled = true;\n callbacks?.onFinish?.();\n }\n };\n\n ////////////////////////////////////////////////////////////////\n\n const api: PxAnimatorAPI = {\n\n \"isReady\": () => true,\n\n \"getRootElement\": () => null,\n\n \"isPlaying\": (): boolean => { return _isPlaying(); },\n\n \"play\": () => {\n startAnim();\n callbacks?.onPlay?.();\n },\n \"pause\": () => {\n pauseAnim();\n callbacks?.onPause?.();\n },\n \"cancel\": () => {\n cancelAnim();\n // onCancel already called in cancelAnim\n },\n \"finish\": () => {\n finishAnim(true);\n },\n\n \"setPlaybackRate\": (rate: number) => {\n if (!isFinite(rate) || rate === 0) {\n console.warn('setPlaybackRate: rate must be finite and non-zero');\n return;\n }\n // Preserve the RAW logical time when changing rate — during the\n // delay phase it is negative and clamping it to 0 would skip the\n // remaining delay. Clamp only the top end.\n let current = getRawAnimTime();\n if (Number.isFinite(totalDuration) && current > (totalDuration as number)) current = totalDuration as number;\n // a direction change opens a new finish episode\n if ((rate < 0) !== (playbackRate < 0)) finishCalled = false;\n playbackRate = rate;\n timeBeforeLastStartMs = current;\n if (playing) lastStartedTs = Date.now();\n },\n\n \"getCurrentTime\": (): number | null => { return getAnimCurrentTime(); },\n\n \"setCurrentTime\": (newTime: number) => {\n // clamp newTime\n if (newTime < 0) newTime = 0;\n if (Number.isFinite(totalDuration) && newTime > (totalDuration as number)) newTime = totalDuration as number;\n\n timeBeforeLastStartMs = newTime;\n if (playing) lastStartedTs = Date.now();\n // seeking re-arms the finish notification (mirrors WAAPI)\n if (!Number.isFinite(totalDuration) || newTime < (totalDuration as number)) finishCalled = false;\n // render immediately to reflect the change\n renderFrame(getAnimCurrentTime());\n },\n\n \"destroy\": () => {\n api.cancel();\n callbacks?.onRemove?.();\n }\n };\n\n ////////////////////////////////////////////////////////////////\n\n return api;\n}\n\n\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\n\n/**\n * \"Equal-in-effect\" comparator for SVGA node trees.\n *\n * Two trees can render identically while differing structurally — extra `<g>`\n * wrappers, different ids, `<use>` clones vs inline copies, a transform expressed\n * as a baked string vs a parts record. This module reduces a tree to what is\n * actually painted: every drawable leaf, with its CUMULATIVE transform matrix\n * (resolved at a given time) and key visual attributes. Comparing those leaf\n * sets ignores representation and catches genuine visual differences.\n *\n * It is a deterministic function applied identically to both trees, so equal\n * inputs (in effect) yield equal output regardless of how each was encoded.\n *\n * Dependency-free on purpose (mirrors the applier's isolation). Scope: the node\n * types and transform forms the player-effects / heavy serialisers emit. Colour\n * animation is not interpolated — leaves are compared at keyframe instants where\n * sampled values are exact.\n */\n\ntype Mat = [number, number, number, number, number, number];\n\ninterface VmNode {\n type?: string;\n children?: Array<VmNode>;\n [attr: string]: any;\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// MATRIX MATH (2x3 affine, SVG order: [a b c d e f])\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst IDENTITY: Mat = [1, 0, 0, 1, 0, 0];\n\nfunction mul(m: Mat, n: Mat): Mat {\n return [\n m[0] * n[0] + m[2] * n[1],\n m[1] * n[0] + m[3] * n[1],\n m[0] * n[2] + m[2] * n[3],\n m[1] * n[2] + m[3] * n[3],\n m[0] * n[4] + m[2] * n[5] + m[4],\n m[1] * n[4] + m[3] * n[5] + m[5],\n ];\n}\n\nconst translateM = (x: number, y: number): Mat => [1, 0, 0, 1, x, y];\nconst scaleM = (sx: number, sy: number): Mat => [sx, 0, 0, sy, 0, 0];\nfunction rotateM(deg: number): Mat {\n const r = (deg * Math.PI) / 180;\n return [Math.cos(r), Math.sin(r), -Math.sin(r), Math.cos(r), 0, 0];\n}\nconst skewXM = (deg: number): Mat => [1, 0, Math.tan((deg * Math.PI) / 180), 1, 0, 0];\nconst skewYM = (deg: number): Mat => [1, Math.tan((deg * Math.PI) / 180), 0, 1, 0, 0];\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// TRANSFORM EVALUATION\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Parses an SVG transform string (\"translate(..)rotate(..)…\") into a matrix. */\nfunction parseTransformString(s: string): Mat {\n let m = IDENTITY;\n const re = /(translate|rotate|scale|matrix|skewX|skewY)\\(([^)]*)\\)/g;\n let hit: RegExpExecArray | null;\n while ((hit = re.exec(s))) {\n const fn = hit[1];\n const a = hit[2].split(/[\\s,]+/).filter(Boolean).map(Number);\n if (fn === 'translate') m = mul(m, translateM(a[0] || 0, a[1] || 0));\n else if (fn === 'scale') m = mul(m, scaleM(a[0], a.length > 1 ? a[1] : a[0]));\n else if (fn === 'rotate') m = mul(m, rotateM(a[0]));\n else if (fn === 'skewX') m = mul(m, skewXM(a[0]));\n else if (fn === 'skewY') m = mul(m, skewYM(a[0]));\n else if (fn === 'matrix') m = mul(m, [a[0], a[1], a[2], a[3], a[4], a[5]]);\n }\n return m;\n}\n\ninterface Parts { translate?: [number, number]; rotate?: number; scale?: [number, number]; origin?: [number, number]; }\n\n/** Composes a `PxTransformParts` record (player canonical order, origin-pivoted). */\nfunction partsToMatrix(p: Parts): Mat {\n let m = IDENTITY;\n if (p.translate) m = mul(m, translateM(p.translate[0], p.translate[1]));\n const pivot = p.origin && (p.rotate !== undefined || p.scale);\n if (pivot) m = mul(m, translateM(p.origin![0], p.origin![1]));\n if (p.rotate !== undefined) m = mul(m, rotateM(p.rotate));\n if (p.scale) m = mul(m, scaleM(p.scale[0], p.scale[1]));\n if (pivot) m = mul(m, translateM(-p.origin![0], -p.origin![1]));\n return m;\n}\n\nfunction lerp(a: number, b: number, f: number): number { return a + (b - a) * f; }\n\n/** Linear-interpolates a parts record between keyframes at time `t` (ms). */\nfunction interpParts(kfs: Array<any>, t: number): Parts {\n if (!kfs.length) return {};\n if (t <= (kfs[0].time ?? 0)) return kfs[0].value || {};\n if (t >= (kfs[kfs.length - 1].time ?? 0)) return kfs[kfs.length - 1].value || {};\n\n let i = 0;\n while (i < kfs.length - 1 && (kfs[i + 1].time ?? 0) < t) i++;\n const a = kfs[i], b = kfs[i + 1];\n const f = (t - (a.time ?? 0)) / ((b.time ?? 0) - (a.time ?? 0) || 1);\n const va: Parts = a.value || {}, vb: Parts = b.value || {};\n\n const out: Parts = {};\n if (va.translate && vb.translate) out.translate = [lerp(va.translate[0], vb.translate[0], f), lerp(va.translate[1], vb.translate[1], f)];\n else out.translate = va.translate || vb.translate;\n if (va.rotate !== undefined && vb.rotate !== undefined) out.rotate = lerp(va.rotate, vb.rotate, f);\n else out.rotate = va.rotate ?? vb.rotate;\n if (va.scale && vb.scale) out.scale = [lerp(va.scale[0], vb.scale[0], f), lerp(va.scale[1], vb.scale[1], f)];\n else out.scale = va.scale || vb.scale;\n out.origin = va.origin || vb.origin;\n return out;\n}\n\n/** Resolves any transform-slot form (string | {value} | {keyframes}) to a matrix at `t`. */\nfunction evalTransformValue(v: any, t: number): Mat {\n if (v === undefined || v === null) return IDENTITY;\n if (typeof v === 'string') return parseTransformString(v);\n if (v.keyframes) return partsToMatrix(interpParts(v.keyframes, t));\n if (v.value) return partsToMatrix(v.value);\n return IDENTITY;\n}\n\n/** The node's own transform at `t`: animated slot wins over the static baseline. */\nfunction nodeMatrix(node: VmNode, t: number): Mat {\n if (node.animate && node.animate.transform) return evalTransformValue(node.animate.transform, t);\n if (node.transform !== undefined) return evalTransformValue(node.transform, t);\n return IDENTITY;\n}\n\n/** Linear-interpolates a scalar animation (e.g. opacity); falls back to static / default. */\nfunction evalScalar(animated: any, staticVal: any, fallback: number, t: number): number {\n if (animated && animated.keyframes && animated.keyframes.length) {\n const kfs = animated.keyframes;\n if (t <= (kfs[0].time ?? 0)) return kfs[0].value;\n if (t >= (kfs[kfs.length - 1].time ?? 0)) return kfs[kfs.length - 1].value;\n let i = 0;\n while (i < kfs.length - 1 && (kfs[i + 1].time ?? 0) < t) i++;\n const a = kfs[i], b = kfs[i + 1];\n const f = (t - (a.time ?? 0)) / ((b.time ?? 0) - (a.time ?? 0) || 1);\n return lerp(a.value, b.value, f);\n }\n return staticVal !== undefined ? Number(staticVal) : fallback;\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// FLATTEN → multiset of painted primitives\n// ─────────────────────────────────────────────────────────────────────────────\n\nconst CONTAINER_TYPES = new Set(['svg', 'g', 'symbol']);\nconst SKIP_TYPES = new Set(['defs', 'mask', 'clipPath', 'title']);\n\nfunction buildIdMap(node: VmNode, map: Map<string, VmNode>): void {\n if (typeof node.id === 'string') map.set(node.id, node);\n node.children?.forEach(c => buildIdMap(c, map));\n}\n\nfunction num(v: any): number { return v === undefined || v === null ? 0 : Number(v); }\n\n// 2-decimal rounding (sub-pixel). The heavy path bakes matrices into strings\n// rounded to ~4 decimals; comparing at 2 decimals avoids straddling a rounding\n// boundary against the applier's full-precision values, while staying visually exact.\nfunction round(n: number): number { return Math.round(n * 100) / 100 + 0; }\n\nfunction geomKey(node: VmNode): string {\n switch (node.type) {\n case 'rect': return num(node.width) + ',' + num(node.height) + ',' + num(node.x) + ',' + num(node.y);\n case 'ellipse': return num(node.rx) + ',' + num(node.ry) + ',' + num(node.cx) + ',' + num(node.cy);\n case 'circle': return num(node.r) + ',' + num(node.cx) + ',' + num(node.cy);\n case 'path': return String(node.d ?? '');\n default: return '';\n }\n}\n\nfunction describePrimitive(node: VmNode, m: Mat, t: number): string {\n const fill = node.fill ?? '';\n const stroke = node.stroke ?? '';\n const sw = node['stroke-width'] ?? node.strokeWidth ?? '';\n const opacity = round(evalScalar(node.animate?.opacity, node.opacity, 1, t));\n const masked = node.mask ? 1 : 0;\n const mat = m.map(round).join(',');\n return node.type + '|' + geomKey(node) + '|[' + mat + ']|f:' + fill + '|s:' + stroke + '|sw:' + (num(sw) || '') + '|o:' + opacity + '|m:' + masked;\n}\n\nfunction flatten(node: VmNode, parent: Mat, t: number, idMap: Map<string, VmNode>, out: Array<string>): void {\n const type = node.type || '';\n if (SKIP_TYPES.has(type)) return;\n\n const m = mul(parent, nodeMatrix(node, t));\n\n if (type === 'use') {\n const targetId = typeof node.href === 'string' ? node.href.replace(/^#/, '') : '';\n const target = idMap.get(targetId);\n const useM = mul(m, translateM(num(node.x), num(node.y)));\n if (target) flatten(target, useM, t, idMap, out);\n else out.push('UNRESOLVED_USE:#' + targetId);\n return;\n }\n\n if (CONTAINER_TYPES.has(type)) {\n node.children?.forEach(c => flatten(c, m, t, idMap, out));\n return;\n }\n\n out.push(describePrimitive(node, m, t));\n}\n\n\n// ─────────────────────────────────────────────────────────────────────────────\n// PUBLIC: sample times + visual model + comparison\n// ─────────────────────────────────────────────────────────────────────────────\n\n/** Every keyframe `time` found anywhere in the tree, plus 0. */\nexport function collectSampleTimes(node: VmNode, into: Set<number>): void {\n into.add(0);\n const scanAnim = (anim: any) => {\n if (!anim || typeof anim !== 'object') return;\n for (const key of Object.keys(anim)) {\n const kfs = anim[key]?.keyframes;\n if (Array.isArray(kfs)) kfs.forEach(kf => into.add(kf.time ?? 0));\n }\n };\n scanAnim(node.animate);\n if (node.transform && typeof node.transform === 'object' && (node.transform as any).keyframes) {\n (node.transform as any).keyframes.forEach((kf: any) => into.add(kf.time ?? 0));\n }\n node.children?.forEach(c => collectSampleTimes(c, into));\n}\n\n/** Sorted, painted-primitive multiset for the tree at time `t`. */\nexport function visualModelAt(root: VmNode, t: number): Array<string> {\n const idMap = new Map<string, VmNode>();\n buildIdMap(root, idMap);\n const out: Array<string> = [];\n flatten(root, IDENTITY, t, idMap, out);\n return out.sort();\n}\n\nexport interface EffectDiff {\n time: number;\n onlyInA: Array<string>;\n onlyInB: Array<string>;\n}\n\n/**\n * Compares two trees \"in effect\" across all keyframe instants found in either.\n * Returns one entry per time where the painted-primitive multisets differ.\n */\nexport function diffInEffect(a: VmNode, b: VmNode): Array<EffectDiff> {\n const times = new Set<number>();\n collectSampleTimes(a, times);\n collectSampleTimes(b, times);\n\n const diffs: Array<EffectDiff> = [];\n for (const t of Array.from(times).sort((x, y) => x - y)) {\n const ma = visualModelAt(a, t);\n const mb = visualModelAt(b, t);\n const onlyInA = subtractMultiset(ma, mb);\n const onlyInB = subtractMultiset(mb, ma);\n if (onlyInA.length || onlyInB.length) diffs.push({ time: t, onlyInA, onlyInB });\n }\n return diffs;\n}\n\n/** Items in `a` not matched one-for-one in `b` (multiset difference). */\nfunction subtractMultiset(a: Array<string>, b: Array<string>): Array<string> {\n const counts = new Map<string, number>();\n for (const x of b) counts.set(x, (counts.get(x) || 0) + 1);\n const extra: Array<string> = [];\n for (const x of a) {\n const c = counts.get(x) || 0;\n if (c > 0) counts.set(x, c - 1);\n else extra.push(x);\n }\n return extra;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { getDefs, getNormalizedProps, resolveStyle, sanitiseAttributeValue, camelCaseToKebabWordIfNeeded, CSS_ONLY_STYLE_PROPS, DISALLOWED_SVG_TAGS_LOWER, TEXT_ATTR, TEXT_CONTENT_ATTR, type PxAnimatedSvgDocument, type PxDefs, type PxNode } from '@pixodesk/svg-animator-core';\n\n// Re-export from the historical home so the package surface is unchanged.\nexport { getNormalizedProps };\n\n\nconst SVG_NS = 'http://www.w3.org/2000/svg';\n\nfunction createElement(\n tagName: string,\n normalisedProps: { [k: string]: string },\n style: Record<string, string | number> | undefined,\n children: Array<Element> | undefined,\n textContent?: string\n): SVGElement | null {\n if (DISALLOWED_SVG_TAGS_LOWER.has(tagName.toLowerCase())) {\n console.warn('SVG tag blocked (dangerous): ', tagName);\n return null;\n }\n\n const element = document.createElementNS(SVG_NS, tagName);\n\n for (const propName in normalisedProps) {\n // `sanitiseAttributeValue` returns `undefined` to mean \"do not emit\"\n // (whitelist miss, blocked dangerous value, …). Browsers coerce\n // `undefined` to the literal string `\"undefined\"` at `setAttribute`,\n // which is exactly the bug we keep hitting — skip instead.\n const sanitised = sanitiseAttributeValue(propName, normalisedProps[propName]);\n if (sanitised === undefined) continue;\n // CSS-only properties (mix-blend-mode, isolation) aren't SVG presentation\n // attributes — the browser ignores them via setAttribute, so route them\n // through `element.style` (camelCase key) instead.\n if (CSS_ONLY_STYLE_PROPS.has(propName)) {\n (element as unknown as { style: Record<string, string> }).style[propName] = String(sanitised);\n continue;\n }\n element.setAttribute(camelCaseToKebabWordIfNeeded(propName), sanitised);\n }\n\n // Apply style properties directly (avoids kebab-case issues)\n if (style) {\n for (const styleProp in style) {\n (element as any).style[styleProp] = String(style[styleProp]);\n }\n }\n\n if (children) {\n for (const child of children) {\n element.appendChild(child);\n }\n }\n\n if (textContent) element.textContent = textContent;\n\n return element;\n}\n\n\n/**\n * Renders a PxNode tree to DOM elements.\n */\nexport function renderNode(node: PxNode, defs?: PxDefs): Element | null {\n if (!node) return null;\n\n const { type, children, style, ...props } = node;\n\n // feFunc elements (feFuncR/G/B/A) carry their SVG `type` attribute\n // (identity/table/…) under `funcType`, because the lightweight-JSON `type`\n // key is reserved for the node tag (and `type` is an INTERNAL_ATTR that\n // `getNormalizedProps` drops). Pull it out and re-apply it onto the created\n // element below, so a feComponentTransfer can actually invert.\n const feFuncType = (props as { funcType?: string }).funcType;\n if (feFuncType !== undefined) delete (props as { funcType?: string }).funcType;\n\n // Extract defs from root svg node\n const nodeDefs = getDefs(node as PxAnimatedSvgDocument) || defs;\n\n // Resolve style reference\n const resolvedStyle = resolveStyle(style, nodeDefs);\n\n // Process children\n let childElements: Array<Element> | undefined;\n if (children) {\n for (const ch of children) {\n const child = renderNode(ch, nodeDefs);\n if (child) {\n if (!childElements) childElements = [];\n childElements.push(child);\n }\n }\n }\n\n const element = createElement(\n type || 'g',\n getNormalizedProps(props),\n resolvedStyle,\n childElements,\n props[TEXT_ATTR] || props[TEXT_CONTENT_ATTR]\n );\n\n // `type` is an INTERNAL_ATTR (reserved for the node tag), so the feFunc transfer\n // function relayed via `funcType` must be applied to the real attribute here.\n if (element && feFuncType !== undefined) element.setAttribute('type', feFuncType);\n\n return element;\n}","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport type { PxTrigger } from '@pixodesk/svg-animator-core';\nimport type { PxAnimatorAPI } from './PxAnimatorWebTypes';\n\n\n/**\n * Sets up event-based triggers for an animation.\n *\n * This function attaches event listeners to the animation's root element based on the\n * provided configuration, allowing animations to be started by user interactions\n * or visibility changes.\n *\n * ### Trigger Options (startOn):\n * - 'load': Starts after the page loads.\n * - 'mouseOver': Starts on mouse enter.\n * - 'click': Toggles play/end action on click.\n * - 'scrollIntoView': Starts when the element scrolls into the viewport.\n * - 'programmatic': No automatic start. Must be controlled via the API.\n *\n * ### End Action Options (outAction):\n * Defines behavior when the trigger condition ends (e.g., mouse leave).\n * - 'continue': Animation continues playing.\n * - 'pause': Pauses the animation.\n * - 'reset': Cancels the animation, resetting it to the start.\n * - 'reverse': Reverses the animation playback.\n *\n * @param {!PxAnimatorAPI} api The animator API instance to control.\n * @param {!PxTrigger} config The trigger configuration object.\n * @returns {!PxAnimatorAPI} The same animator API instance, for chaining.\n */\nexport function setupAnimationTriggers(\n api: PxAnimatorAPI,\n config: PxTrigger\n): PxAnimatorAPI {\n // Threshold default 0 — \"any pixel visible starts it\". Keep in sync with the editor\n // model's default (TSvgSvgAnimationAttr.scrollIntoViewThreshold), which OMITS the\n // value on the wire when it equals this default.\n const { startOn, outAction = 'continue', scrollIntoViewThreshold = 0 } = config;\n\n const root = api.getRootElement();\n\n if (!root) {\n console.warn('setupAnimationTriggers: No root element found for animation.');\n return api;\n }\n\n // Tracks whether the LAST out-action put the animation into reverse, so the\n // next trigger start can restore forward playback without clobbering a\n // custom playback rate the user may have set through the API.\n let reversed = false;\n\n /** Ensures forward playback and starts or resumes the animation. */\n const start = () => {\n if (reversed) {\n reversed = false;\n api.setPlaybackRate(1);\n }\n api.play();\n };\n\n /** Handles what to do when the element leaves the active trigger condition. */\n const handleEndAction = () => {\n switch (outAction) {\n case 'pause':\n api.pause();\n break;\n case 'reset':\n api.cancel();\n break;\n case 'reverse':\n // Play the animation backwards from its current position.\n reversed = true;\n api.setPlaybackRate(-1);\n api.play();\n break;\n case 'continue':\n default:\n // Do nothing\n break;\n }\n };\n\n // ---- Setup event-based start logic ----\n switch (startOn) {\n case 'load': {\n const startHandler = () => start();\n if (document.readyState === 'complete') {\n startHandler();\n } else {\n window.addEventListener('load', startHandler, { once: true });\n }\n break;\n }\n\n case 'mouseOver': {\n // An OUT may only follow an IN. A `mouseleave` with no preceding `mouseenter` happens\n // when the pointer is already over the element at load and then moves away — and for\n // `outAction: 'reverse'` the out action PLAYS (`setPlaybackRate(-1); play()`), so an\n // untriggered leave would start the animation running backwards. Same class of bug as\n // the scrollIntoView initial-intersection case handled below.\n let enteredOnce = false;\n const mouseOverHandler = () => { enteredOnce = true; start(); };\n const mouseOutHandler = () => { if (enteredOnce) handleEndAction(); };\n\n root.addEventListener('mouseenter', mouseOverHandler);\n root.addEventListener('mouseleave', mouseOutHandler);\n break;\n }\n\n case 'click': {\n const clickHandler = () => {\n if (api.isPlaying()) {\n handleEndAction();\n } else {\n start();\n }\n };\n root.addEventListener('click', clickHandler);\n break;\n }\n\n case 'scrollIntoView': {\n // `observe()` delivers an INITIAL entry describing the CURRENT state, which is how an\n // element that is already on screen starts without any scrolling. But that same initial\n // entry also reports \"not intersecting\" for an element merely below the fold — and\n // treating that as an out-action ran it before anything had ever played. For `reverse`\n // that meant `setPlaybackRate(-1)` + `play()`, i.e. the animation started running\n // BACKWARDS on page load. An OUT is only meaningful after an IN, so require one.\n // A target TALLER than the viewport can never reach a high ratio (ratio is measured\n // against the TARGET's own size), so a 0.5/0.9 threshold would be unsatisfiable and the\n // animation would never play. Normalise by what could possibly be visible, and register\n // a granular threshold list — registering the raw threshold would mean the callback\n // never fires at all for such a target.\n const effectiveRatio = (entry: IntersectionObserverEntry): number => {\n const target = entry.boundingClientRect;\n const visible = entry.intersectionRect;\n // Simplified entries (tests, older engines) may omit the rects — fall back to the\n // browser's own ratio rather than inventing one.\n if (!target?.height || !visible) return entry.intersectionRatio;\n // Use the SMALLER of `rootBounds` and the live viewport. `rootBounds` can be null\n // (implicit root in some embeddings) and can also report a box LARGER than the\n // actual viewport — trusting it then reinstates the very cap this normalisation\n // exists to remove. `intersectionRect` is already clipped to the real viewport, so\n // the denominator must be too.\n const live = typeof window !== 'undefined' && window.innerHeight ? window.innerHeight : Infinity;\n const declared = entry.rootBounds?.height ?? Infinity;\n const viewport = Math.min(live, declared);\n const denom = Math.min(target.height, Number.isFinite(viewport) ? viewport : target.height);\n return denom > 0 ? visible.height / denom : entry.intersectionRatio;\n };\n const thresholdSteps = Array.from({ length: 21 }, (_, i) => i / 20);\n let wasIntersecting = false;\n const observer = new IntersectionObserver(\n entries => {\n entries.forEach(entry => {\n // If the element is at least partially visible\n if (entry.isIntersecting && effectiveRatio(entry) >= scrollIntoViewThreshold) {\n wasIntersecting = true;\n start();\n } else if (wasIntersecting) {\n // Element scrolled OFF screen after having been on it -> out action\n wasIntersecting = false;\n handleEndAction();\n }\n });\n },\n { threshold: thresholdSteps }\n );\n observer.observe(root);\n break;\n }\n\n case 'programmatic':\n // No auto-start; external code must call play()\n break;\n }\n\n return api;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { camelCaseToKebabWordIfNeeded, createBasicFrameLoopAnimator, getAnimatorConfig, STYLE_ATTR_NAMES, type PxAnimatedSvgDocument, type PxAnimatorCallbacksConfig, type PxPlatformAdapter } from '@pixodesk/svg-animator-core';\nimport { setupAnimationTriggers } from './PxAnimatorTriggers';\nimport type { PxAnimatorAPI } from './PxAnimatorWebTypes';\n\n// Re-export the platform-neutral pieces from their historical home so the\n// package surface is unchanged by the core extraction.\nexport { createBasicFrameLoopAnimator };\nexport type { PxPlatformAdapter };\n\nexport function getSelector(id: string) {\n // return `[data-px-id=\"${id}\"]`; FIXME\n return '#' + id;\n}\n\n\n////////////////////////////////////////////////////////////////\n// Browser DOM implementation\n////////////////////////////////////////////////////////////////\n\n\n\n/**\n * Creates an animator instance that uses a requestAnimationFrame loop for animations.\n * This is the browser DOM-specific version.\n *\n * @param {PxAnimatorCallbacksConfig=} callbacks Optional lifecycle callbacks.\n * @param {Element=} rootElement Optional pre-rendered root element.\n * @returns {PxAnimatorAPI} A PxAnimatorAPI instance.\n */\nexport function createFrameLoopAnimator(\n doc: PxAnimatedSvgDocument,\n adapter?: PxPlatformAdapter,\n callbacks?: PxAnimatorCallbacksConfig,\n rootElement?: Element | null\n): PxAnimatorAPI {\n\n const config = getAnimatorConfig(doc) || {};\n\n // Use provided root element or try to find by selector\n if (!rootElement) {\n if (doc.id) {\n const rootSelector = getSelector(doc.id);\n rootElement = document.querySelector(rootSelector);\n if (!rootElement) console.warn(\"createFrameLoopAnimator: No root element found for selector: \", rootSelector);\n } else {\n console.warn(\"createFrameLoopAnimator: No root element provided\");\n }\n }\n\n const basicApi = createBasicFrameLoopAnimator(\n doc,\n adapter || createDomAdapter(rootElement),\n callbacks\n );\n\n // Specialise the platform-neutral API to the DOM: the root is an Element.\n const api: PxAnimatorAPI = {\n ...basicApi,\n \"getRootElement\": () => rootElement || null\n };\n if (config.trigger) setupAnimationTriggers(api, config.trigger);\n return api;\n}\n\nexport function createDomAdapter(rootElement?: Element | null) {\n // Track warnings to avoid spamming console\n const warnedSelectors = new Set<string>();\n\n const adapter: PxPlatformAdapter = {\n isConnected: () => {\n if (!rootElement) return true; // No root element means we're always \"connected\"\n return rootElement.isConnected;\n },\n setAttribute: (id, attrName, value) => {\n\n attrName = camelCaseToKebabWordIfNeeded(attrName);\n\n const selector = getSelector(id);\n\n // Query elements by selector within root (or document if no root)\n const elements = rootElement?.querySelectorAll(selector) || document.querySelectorAll(selector);\n\n if (elements.length === 0 && !warnedSelectors.has(selector)) {\n warnedSelectors.add(selector);\n console.warn('setAttribute: No elements found for selector \"' + selector + '\"');\n }\n\n for (let i = 0; i < elements.length; i++) {\n const element = elements[i];\n // `<pattern>` ignores the plain `transform` ATTRIBUTE (it transforms via\n // `patternTransform`). The WAAPI engine drives the same animation through\n // CSS `transform`, which browsers do apply to patterns — remap here so the\n // frames engine animates everything WAAPI animates.\n const effectiveAttrName = attrName === 'transform' && element.tagName === 'pattern'\n ? 'patternTransform'\n : attrName;\n element.setAttribute(effectiveAttrName, value);\n if (STYLE_ATTR_NAMES.has(attrName)) {\n (element as HTMLElement).style[attrName as any] = value;\n }\n }\n },\n };\n return adapter;\n}","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { bezierToSvgPath, clamp, COLOUR_ATTR_NAMES, composeTransformParts, cubicBezier, getAnimatorConfig, getNormalisedBindings, interpolateValue, kebabToCamelCaseWord, PxAnimatorEngine, splitEasing, toRGBA, TRANSFORM_FN_NAMES, type PxAnimatedSvgDocument, type PxAnimationDefinition, type PxAnimatorCallbacksConfig, type PxAnimatorConfig, type PxBezierPath, type PxKeyframe } from '@pixodesk/svg-animator-core';\nimport { getSelector } from './PxAnimatorFrameLoop';\nimport { setupAnimationTriggers } from './PxAnimatorTriggers';\nimport type { PxAnimatorAPI } from './PxAnimatorWebTypes';\n\n\n/**\n * Converts a single PxKeyframe into a Web Animations API Keyframe object.\n *\n * Handles three categories of CSS property:\n * - **Colour attributes** (e.g. fill, stroke): array values are converted to an rgba() string.\n * - **Transform functions** (e.g. translate, rotate, scale): values are formatted as a\n * CSS transform function string and mapped to the transform property.\n * - **All other properties**: the value is coerced to a string as-is.\n *\n * If the resulting (cssKey, cssValue) pair is not supported by the browser (CSS.supports returns\n * false), cssKey is added to unsupportedSet so the caller can decide whether to fall back to the\n * frame-loop animator.\n */\nfunction createCssKf(kf: PxKeyframe, t: number, propName: string, unsupportedSet: Set<string>) {\n let value = kf.v ?? kf.value;\n const e = kf.e ?? kf.easing; // e is on the source keyframe: applied from this KF to the next (matches WAAPI easing convention)\n\n const cssKf: Keyframe = {\n offset: t,\n easing: e && Array.isArray(e) ? \"cubic-bezier(\" + e.join(',') + \")\" : undefined\n };\n\n let cssValue: any;\n let cssKey = propName;\n\n if (COLOUR_ATTR_NAMES.has(propName) && Array.isArray(value)) {\n cssValue = toRGBA(value);\n } else if (propName === 'transform' && value !== null && typeof value === 'object' && !Array.isArray(value)) {\n // Unified transform: keyframe value is a parts record (PxTransformParts).\n // Compose all present parts into one CSS transform string.\n cssValue = composeTransformParts(value, { withUnits: true });\n cssKey = 'transform';\n } else if (TRANSFORM_FN_NAMES.has(propName)) {\n if (Array.isArray(value)) {\n if (propName === 'translate') value = value.map(v => v + 'px');\n value = value.join(',');\n }\n if (propName === 'rotate') value = value + 'deg';\n cssValue = propName + '(' + value + ')';\n cssKey = 'transform';\n } else if (propName === 'd') {\n // Animated path. The value is a { paths: PxBezierPath[] } record (same shape the CSS/frame\n // builder consumes). Without this branch it stringified to \"[object Object]\", an invalid\n // `d`, which empties the <path> — the shape vanished in forced WAAPI while svg-css (which\n // emits `d: path(...)`) rendered it. Emit the CSS `d` presentation-attr syntax `path(\"…\")`\n // via the same bezierToSvgPath used by the CSS path, so WAAPI animates it identically.\n const paths: Array<PxBezierPath> = (value && typeof value === 'object' && Array.isArray(value.paths))\n ? value.paths : [];\n // forceCurves: CSS/WAAPI only interpolates `path()` values with IDENTICAL command\n // sequences — uniform all-`C` output keeps every keyframe structurally equal\n // (mixed L/C, e.g. round-corner radius 0 vs >0, would go DISCRETE → 50% flip).\n cssValue = 'path(\"' + paths.map(bz => bezierToSvgPath(bz, true)).join('') + '\")';\n } else {\n cssValue = '' + value;\n }\n\n if (!CSS.supports(cssKey, cssValue)) unsupportedSet.add(cssKey);\n\n cssKey = kebabToCamelCaseWord(cssKey);\n cssKf[cssKey] = cssValue;\n return cssKf;\n}\n\n/**\n * Clips keyframes to the [0, duration] range.\n * If a keyframe pair straddles a boundary (t=0 or t=duration), inserts an interpolated\n * keyframe at the boundary with the correct value and split easing, so WAAPI sees\n * exact start/end values rather than out-of-range ones.\n */\nfunction clipKeyframesToDuration(\n propName: string,\n keyframes: PxKeyframe[],\n duration: number\n): PxKeyframe[] {\n const result: PxKeyframe[] = [];\n\n for (let i = 0; i < keyframes.length; i++) {\n const kf = keyframes[i];\n const t = kf.t ?? 0;\n\n if (t < 0) {\n // If the next keyframe is in range, interpolate value at t=0\n const next = keyframes[i + 1];\n if (next && (next.t ?? 0) >= 0) {\n const nextT = next.t ?? 0;\n const localFrac = (0 - t) / (nextT - t);\n const easedFrac = kf.e ? cubicBezier(kf.e as [number, number, number, number])(localFrac) : localFrac;\n const { right: rightEasing } = splitEasing(kf.e as any, localFrac);\n result.push({ t: 0, v: interpolateValue(propName, kf.v, next.v, easedFrac), e: rightEasing });\n }\n continue;\n }\n\n if (t > duration) {\n // If the previous keyframe was in range, interpolate value at t=duration\n const prev = keyframes[i - 1];\n if (prev && (prev.t ?? 0) <= duration) {\n const prevT = prev.t ?? 0;\n const localFrac = (duration - prevT) / (t - prevT);\n const easedFrac = prev.e ? cubicBezier(prev.e as [number, number, number, number])(localFrac) : localFrac;\n const { left: leftEasing } = splitEasing(prev.e as any, localFrac);\n if (result.length > 0) result[result.length - 1] = { ...result[result.length - 1], e: leftEasing };\n result.push({ t: duration, v: interpolateValue(propName, prev.v, kf.v, easedFrac), e: undefined });\n }\n break;\n }\n\n result.push(kf);\n }\n\n return result;\n}\n\n/**\n * Converts a PxAnimationDefinition into a map of Web Animations API Keyframe arrays, one per\n * animated property.\n *\n * For each property in the definition the function:\n * 1. Clips keyframes to [0, duration], interpolating boundary values when a pair straddles an edge.\n * 2. Normalises keyframe time values to the [0, 1] offset range (time / duration).\n * 3. Delegates CSS value conversion to createCssKf.\n * 4. Ensures the keyframe sequence always starts at offset: 0 and ends at offset: 1 — a\n * requirement of the Web Animations API for correct looping behaviour. If the first keyframe\n * starts after 0 or the last keyframe ends before 1, a copy of that keyframe is inserted at the\n * boundary with the adjusted offset.\n */\nexport function convertToWebApiKeyframes(\n animDef: PxAnimationDefinition,\n unsupportedSet: Set<string>,\n config: PxAnimatorConfig\n): Map<string, Keyframe[]> {\n const result = new Map<string, Keyframe[]>();\n\n for (const [propName, propAnim] of Object.entries(animDef)) {\n const duration = config.duration || 1;\n const clippedKeyframes = clipKeyframesToDuration(propName, propAnim.kfs || propAnim.keyframes || [], duration);\n const cssKeyframes: Keyframe[] = [];\n\n for (let i = 0; i < clippedKeyframes.length; i++) {\n const kf = clippedKeyframes[i];\n\n const t = clamp((kf.t ?? 0) / duration, 0, 1);\n const cssKf: Keyframe = createCssKf(kf, t, propName, unsupportedSet);\n\n // Keyframes need to start with offset:0 to work correctly with loops\n if (i === 0 && (cssKf.offset || 0) > 0) {\n cssKeyframes.push({ ...cssKf, offset: 0 });\n }\n\n cssKeyframes.push(cssKf);\n }\n\n // Keyframes need to end with offset:1 to work correctly with loops\n if (cssKeyframes.length > 0 && (cssKeyframes[cssKeyframes.length - 1].offset || 0) < 1) {\n cssKeyframes.push({\n ...cssKeyframes[cssKeyframes.length - 1],\n offset: 1\n });\n }\n\n if (cssKeyframes.length > 0) {\n result.set(propName, cssKeyframes);\n }\n }\n\n return result;\n}\n\n/**\n * Creates an animator instance that uses the native Web Animations API.\n *\n * This is the preferred, more performant animator. It will return null if the\n * animation configuration contains properties not supported by the browser's\n * Web Animations API implementation, unless forceEvenIfHasUnsupportedAttrs is true.\n *\n * @param callbacks Optional lifecycle callbacks.\n * @param rootElement Root element.\n * @param forceEvenIfHasUnsupportedAttrs If true, an animator will be created even if some CSS properties are not supported.\n * @returns An PxAnimatorAPI instance, or null if unsupported features are used and not forced.\n */\nexport function createWebApiAnimator(\n doc: PxAnimatedSvgDocument,\n callbacks?: PxAnimatorCallbacksConfig,\n rootElement?: Element | null,\n forceEvenIfHasUnsupportedAttrs?: boolean\n): PxAnimatorAPI | null {\n\n const config = getAnimatorConfig(doc) || {};\n\n // Use provided root element or try to find by selector\n if (!rootElement) {\n if (doc.id) {\n const rootSelector = getSelector(doc.id);\n rootElement = document.querySelector(rootSelector);\n if (!rootElement) console.warn(\"createFrameLoopAnimator: No root element found for selector: \", rootSelector);\n } else {\n console.warn(\"createFrameLoopAnimator: No root element provided\");\n }\n }\n\n // WAAPI bindings: motion-along-path is materialised into plain `{ translate,\n // rotate }` transform kfs inside `normalizeAnimationDefinition` (gated on\n // `engine === 'webapi'`). The WAAPI keyframe builder then sees a vanilla\n // unified-transform animation — no DOM-style mutation, no offset-path.\n const bindings = getNormalisedBindings(doc, PxAnimatorEngine.webapi);\n\n const animations: Array<Animation> = [];\n\n const _iterations = config.iterations;\n let iterations: number | undefined;\n if (typeof _iterations === 'number') iterations = _iterations;\n if (_iterations === 'infinite') iterations = Infinity;\n\n const unsupportedSet = new Set<string>();\n\n // A document commonly produces many Animation objects (one per element ×\n // animated property), but the public callbacks describe the document\n // timeline as a whole — guard so each fires once per finish/remove episode.\n // `finishNotified` re-arms on play/cancel/seek.\n let finishNotified = false;\n let removeCalled = false;\n\n ////////////////////////////////////////////////////////////////\n\n // Warn if no bindings defined\n if (!bindings?.length) {\n console.warn('createWebApiAnimator: No animation bindings defined');\n }\n\n for (const binding of bindings || []) {\n const animDef = binding.animate;\n if (!animDef || typeof animDef !== 'object' || Array.isArray(animDef)) {\n console.warn('createWebApiAnimator: Empty or unresolved binding', binding);\n continue;\n }\n\n const selector = getSelector(binding.id);\n\n // Use CSS selector to find elements\n const elements = rootElement?.querySelectorAll(selector) || document.querySelectorAll(selector);\n\n if (elements.length === 0) {\n console.warn('createWebApiAnimator: No elements found for selector \"' + selector + '\"');\n }\n\n // Convert animation definition to Web API keyframes\n const keyframesMap = convertToWebApiKeyframes(animDef, unsupportedSet, config);\n\n\n // Delay handling:\n // - Positive delay (e.g., 500): Wait before starting → use delay option\n // - Negative delay (e.g., -500): Start mid-animation → use currentTime to seek\n // (Web Animations API doesn't reliably support negative delay values)\n // WAAPI `currentTime` spans ALL iterations, so a finite timeline clamps\n // the seek to duration × iterations (seeking to exactly the end must\n // land on the final frame, not wrap to 0); an infinite timeline wraps\n // within one iteration instead.\n const positiveDelay = config.delay && config.delay > 0 ? config.delay : undefined;\n let seekPosition: number | undefined;\n if (config.delay && config.delay < 0 && config.duration) {\n const rawSeek = -config.delay;\n seekPosition = iterations === Infinity\n ? rawSeek % config.duration\n : Math.min(rawSeek, config.duration * (iterations ?? 1));\n }\n\n const effectOptions: KeyframeEffectOptions = {\n duration: config.duration,\n delay: positiveDelay,\n // Default to 'forwards' so elements hold their final state after the\n // animation ends — consistent with Lottie and other animation runtimes.\n // Without this, seeking to the last frame reverts elements to their\n // pre-animation state (the Web Animations API \"after\" phase with fill:'none').\n fill: config.fill ?? 'forwards',\n direction: config.direction,\n iterations: iterations\n };\n\n for (let i = 0; i < elements.length; i++) {\n const element = elements[i];\n\n for (const [, keyframes] of keyframesMap) {\n if (keyframes.length > 0) {\n try {\n const effect = new KeyframeEffect(element, keyframes, effectOptions);\n const anim = new Animation(effect, document.timeline);\n\n if (callbacks?.onFinish) anim.onfinish = () => {\n if (finishNotified) return;\n finishNotified = true;\n callbacks.onFinish?.();\n };\n if (callbacks?.onRemove) anim.onremove = () => {\n if (removeCalled) return;\n removeCalled = true;\n callbacks.onRemove?.();\n };\n\n // Seek forward for negative delay (e.g., delay=-500 → seek to 500ms).\n // `!== undefined` — a seek of exactly 0 is still a seek.\n if (seekPosition !== undefined) {\n anim.currentTime = seekPosition;\n }\n\n animations.push(anim);\n } catch (e) {\n console.warn(e);\n }\n }\n }\n }\n }\n\n ////////////////////////////////////////////////////////////////\n\n if (!forceEvenIfHasUnsupportedAttrs && unsupportedSet.size) {\n console.warn('Unsupported CSS attrs: ' + [...unsupportedSet].join(', '));\n return null;\n }\n\n ////////////////////////////////////////////////////////////////\n\n const api: PxAnimatorAPI = {\n\n \"isReady\": () => true,\n\n \"getRootElement\": () => rootElement || null,\n\n \"isPlaying\": (): boolean => { return animations[0]?.playState === 'running'; },\n\n \"play\": () => {\n finishNotified = false; // re-arm finish notification\n animations.forEach(a => a.play());\n callbacks?.onPlay?.();\n },\n \"pause\": () => {\n animations.forEach(a => a.pause());\n callbacks?.onPause?.();\n },\n \"cancel\": () => {\n finishNotified = false; // re-arm finish notification\n animations.forEach(a => a.cancel());\n callbacks?.onCancel?.();\n },\n \"finish\": () => {\n for (const a of animations) {\n try {\n if (a.effect?.getTiming().iterations === Infinity) {\n a.effect.updateTiming({ iterations: 1 });\n a.finish();\n a.effect.updateTiming({ iterations: Infinity });\n } else {\n a.finish();\n }\n } catch (e) {\n a.cancel();\n }\n }\n // Natural finish also reaches onFinish via the native `anim.onfinish`\n // handler wired at construction time.\n },\n\n \"setPlaybackRate\": (rate: number) => {\n animations.forEach(a => (a.playbackRate = rate));\n return api;\n },\n \"getCurrentTime\": (): number | null => {\n const res = animations[0]?.currentTime ?? null;\n return res !== null ? +res : null;\n },\n \"setCurrentTime\": (time: number) => {\n finishNotified = false; // re-arm finish notification\n animations.forEach(a => {\n a.currentTime = time;\n });\n },\n\n \"destroy\": () => {\n api.cancel();\n animations.splice(0, animations.length);\n if (!removeCalled) {\n removeCalled = true;\n callbacks?.onRemove?.();\n }\n }\n };\n\n ////////////////////////////////////////////////////////////////\n\n if (config.trigger) {\n setupAnimationTriggers(api, config.trigger);\n }\n\n return api;\n}\n","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { generateNewIds, getAnimatorConfig, isPxElementFileFormat, materialiseAllInTree, PX_ANIM_ATTR_NAME, PX_ANIM_SRC_ATTR_NAME, PxAnimatorEngine, PxAnimatorMode, validateNodeEffects, type PxAnimatedSvgDocument, type PxAnimatorCallbacksConfig, type PxPlatformAdapter } from '@pixodesk/svg-animator-core';\nimport { renderNode } from './PxAnimatorDOM';\nimport { createFrameLoopAnimator } from './PxAnimatorFrameLoop';\nimport { setupAnimationTriggers } from './PxAnimatorTriggers';\nimport type { PxAnimatorAPI } from './PxAnimatorWebTypes';\nimport { createWebApiAnimator } from './PxAnimatorWebApi';\n\n// Re-export so the package surface keeps `generateNewIds` at its historical home.\nexport { generateNewIds };\n\n\n/**\n * Creates an animator instance from a normalized player config.\n * This is the internal implementation that both engines use.\n */\nfunction createAnimatorFromConfig(\n doc: PxAnimatedSvgDocument,\n adapter?: PxPlatformAdapter,\n callbacks?: PxAnimatorCallbacksConfig,\n rootElement?: Element | null\n): PxAnimatorAPI {\n\n const animatorConfig = getAnimatorConfig(doc) || {};\n\n // `resetOnFinish`: after a NATURAL finish, snap the document back to its start\n // state — the same mechanics as the trigger `reset` out-action (`api.cancel()`\n // clears the animation state so the base attributes show). Composed centrally so\n // BOTH engines get it; the caller's own `onFinish` still fires first. `apiRef` is\n // assigned right after creation — finish always happens asynchronously later.\n let apiRef: PxAnimatorAPI | undefined;\n let effectiveCallbacks = callbacks;\n if (animatorConfig.resetOnFinish) {\n effectiveCallbacks = {\n ...callbacks,\n onFinish: () => {\n callbacks?.onFinish?.();\n apiRef?.cancel();\n },\n };\n }\n\n let res: PxAnimatorAPI;\n if (animatorConfig.mode === PxAnimatorMode.frames) {\n // Forcing frames, even if webapi could be used.\n res = createFrameLoopAnimator(doc, adapter, effectiveCallbacks, rootElement);\n } else {\n // Try webapi first; fall back to frames if it returns null (unsupported\n // attrs) unless the user explicitly forced webapi.\n res = (\n createWebApiAnimator(doc, effectiveCallbacks, rootElement,\n animatorConfig.mode === PxAnimatorMode.webapi // forcing webapi\n ) ||\n createFrameLoopAnimator(doc, adapter, effectiveCallbacks, rootElement)\n );\n }\n apiRef = res;\n\n if (animatorConfig.debugInstName) {\n (window as any)[animatorConfig.debugInstName] = res; // Exposing as global variable for debug\n }\n\n return res;\n}\n\n\n/**\n * Creates an animator instance from an AnimatedSvgDocument.\n *\n * This function serves as the main entry point for the animation library. It automatically\n * chooses the best animation engine available ('webapi' or 'frames') or can be\n * forced to use a specific one.\n *\n * @param doc The animated SVG document.\n * @param callbacks Optional object with callback functions for animation lifecycle events (play, pause, finish, etc.).\n * @param containerElement Optional selector or element to render the SVG into.\n * @returns An PxAnimatorAPI instance to programmatically control the animation.\n */\nexport function createAnimatorImpl(\n doc: PxAnimatedSvgDocument,\n adapter?: PxPlatformAdapter,\n callbacks?: PxAnimatorCallbacksConfig,\n containerElement?: string | Element\n): PxAnimatorAPI {\n\n // Validate every `node.effects` bucket against `PxEffectsSchema` and warn\n // about any shape drift. Doesn't mutate or block — the materialiser tries\n // its best even when shapes are off, but a warning helps spot wire-format\n // regressions early.\n const effectsWarnings = validateNodeEffects(doc as any);\n for (const w of effectsWarnings) console.warn('[PxAnimator] effects shape warning:', w);\n\n // Decide the engine upfront so the materialisation pipeline knows which\n // stages to run. `auto` (and any non-`frames` value) resolves to `webapi`\n // for materialisation purposes; if webapi later returns null at engine\n // construction, frames is used as fallback — slight over-materialisation\n // for that doc, but no correctness issue.\n const animatorConfig = getAnimatorConfig(doc) || {};\n const engine: PxAnimatorEngine = animatorConfig.mode === PxAnimatorMode.frames\n ? PxAnimatorEngine.frames\n : PxAnimatorEngine.webapi;\n\n // Run the full document materialisation pipeline:\n // effects → loops → motion-path (webapi only) → animated-use (webapi only)\n // The exact same function is exported for the Editor — no parallel pipeline.\n doc = materialiseAllInTree(doc, engine);\n\n let rootElement: Element | null = null;\n\n // Render whenever there's a container. A document with no children is still a\n // document — it carries the viewBox/size that make it a viewport — so it renders as an\n // EMPTY `<svg>`. Gating on `doc.children` left `getRootElement()` answering `null`,\n // which a consumer cannot tell apart from \"the render failed\".\n if (containerElement) {\n\n doc = generateNewIds(doc); // Regenerate IDs so repeated calls to createAnimator(...) produce different ids in elements\n\n const containerEl = typeof containerElement === 'string' ?\n document.querySelector(containerElement) : containerElement;\n\n if (containerEl) {\n rootElement = renderNode(doc);\n if (rootElement) {\n containerEl.replaceChildren(rootElement);\n }\n }\n }\n\n return createAnimatorFromConfig(doc, adapter, callbacks, rootElement);\n}\n\nexport const PX_ANIMATOR_DATA_KEY = 'data';\n\nexport interface PxAnimatorOptions {\n /** URL to fetch the animation document from. Provide either this or `data`, not both. */\n src?: string;\n /** Inline animation document object. Provide either this or `src`, not both. */\n data?: PxAnimatedSvgDocument;\n /** Platform adapter for frame-loop rendering. */\n adapter?: PxPlatformAdapter;\n /** Callback functions for animation lifecycle events. */\n callbacks?: PxAnimatorCallbacksConfig;\n /** CSS selector or element to render the SVG into. */\n container?: string | Element;\n}\n\n/**\n * Creates an animator instance to control SVG animations.\n *\n * @param options.src URL to fetch the animation document from.\n * @param options.data Inline animation document object.\n * @param options.container CSS selector or element to render the SVG into.\n * @returns A PxAnimatorAPI instance to programmatically control the animation.\n */\nexport function createAnimator(options: PxAnimatorOptions): PxAnimatorAPI {\n\n const { src, data, adapter, callbacks, container } = options;\n\n if (data !== undefined && src !== undefined) {\n throw new Error('createAnimator: provide either `src` or `data`, not both');\n }\n if (data === undefined && src === undefined) {\n throw new Error('createAnimator: either `src` or `data` is required');\n }\n\n if (data !== undefined) {\n return createAnimatorImpl(data, adapter, callbacks, container);\n }\n\n // URL provided - fetch and create animator\n let animator: PxAnimatorAPI | null = null;\n\n // Control calls made before the fetch resolves are queued and replayed (in\n // order) once the animator is ready, so e.g. `createAnimator({src}).play()`\n // works as expected. Getters are not queued — they return their \"not ready\n // yet\" value until the document loads.\n let pending: Array<(api: PxAnimatorAPI) => void> | null = [];\n let destroyed = false;\n\n const enqueue = (call: (api: PxAnimatorAPI) => void) => {\n if (animator) {\n call(animator);\n } else if (pending) {\n pending.push(call);\n }\n };\n\n fetch(src!).then(res => res.json()).then(json => {\n if (destroyed) return; // destroy() was called before the document loaded\n if (isPxElementFileFormat(json)) {\n animator = createAnimatorImpl(json, adapter, callbacks, container);\n const queued = pending;\n pending = null;\n queued?.forEach(call => call(animator!));\n } else {\n console.error('createAnimator: invalid animation document format at \"' + src + '\"');\n }\n }).catch(err => {\n pending = null;\n console.error('createAnimator: failed to load \"' + src + '\"', err);\n });\n\n // Return a proxy that forwards calls once loaded\n return {\n \"isReady\": () => !!animator,\n \"getRootElement\": () => animator ? animator.getRootElement() : null,\n \"isPlaying\": () => animator?.isPlaying() || false,\n \"play\": () => { enqueue(api => api.play()); },\n \"pause\": () => { enqueue(api => api.pause()); },\n \"cancel\": () => { enqueue(api => api.cancel()); },\n \"finish\": () => { enqueue(api => api.finish()); },\n \"setPlaybackRate\": (rate: number) => { enqueue(api => api.setPlaybackRate(rate)); },\n \"getCurrentTime\": () => animator ? animator.getCurrentTime() : null,\n \"setCurrentTime\": (time: number) => { enqueue(api => api.setCurrentTime(time)); },\n \"destroy\": () => {\n destroyed = true;\n pending = null; // drop any queued calls\n animator?.destroy();\n }\n };\n}\n\n/**\n * Scan and load for tags, e.g.\n * <div data-px-animation-src=\"animation.json\"></div>\n */\nexport function loadTagAnimators() {\n const elements = document.querySelectorAll('[' + PX_ANIM_SRC_ATTR_NAME + ']');\n for (let i = 0; i < elements.length; i++) {\n const element = elements[i];\n if (!(element as any)[PX_ANIM_ATTR_NAME]) {\n const src = element.getAttribute(PX_ANIM_SRC_ATTR_NAME);\n if (src) {\n (element as any)[PX_ANIM_ATTR_NAME] = createAnimator({ src, container: element });\n }\n }\n }\n}\n\nif (typeof window !== 'undefined') {\n (window as any)[\"loadTagAnimators\"] = loadTagAnimators;\n (window as any)[\"createAnimator\"] = createAnimator;\n (window as any)[\"setupAnimationTriggers\"] = setupAnimationTriggers;\n}","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport type { JsMode, OutAction, PxAnimatedSvgDocument, PxAnimatorAPI, PxNode, PxPlatformAdapter, PxTrigger, StartOn } from '@pixodesk/svg-animator-web';\nimport { camelCaseToKebabWordIfNeeded, createAnimator, FillMode, generateNewIds, getNormalizedProps, STYLE_ATTR_NAMES } from '@pixodesk/svg-animator-web';\nimport type { CSSProperties, FC, ReactElement } from 'react';\nimport React, { createElement, useEffect, useImperativeHandle, useRef } from 'react';\nimport { useDepsVersion } from './Utils';\n\n\n// -- Public types -----------------------------------------------------------\n\nexport interface ReactAnimatorApi {\n /** Returns true if the animation is currently running. */\n isPlaying(): boolean;\n\n /** Starts or resumes the animation. */\n play(): void;\n\n /** Pauses the animation at its current state. */\n pause(): void;\n\n /** Stops the animation and resets it to its initial state. */\n cancel(): void;\n\n /** Jumps to the end of the animation and holds the final state. */\n finish(): void;\n\n /** Changes the speed of the animation. 1 is normal, 2 is double, -1 is reverse. */\n setPlaybackRate(rate: number): void;\n\n /** Returns the current playback time in milliseconds. */\n getCurrentTime(): number | null;\n\n /** Jumps to a specific time (in milliseconds) in the animation. */\n setCurrentTime(time: number): void;\n}\n\nexport interface PixodeskSvgAnimatorImplProps {\n className?: string;\n style?: CSSProperties;\n doc: PxAnimatedSvgDocument;\n compMode: PixodeskSvgAnimatorCompMode;\n\n /** Imperative API handle populated by the inner component. */\n apiHolderRef: React.RefObject<PxAnimatorAPI | null>;\n\n /**\n * Latest lifecycle callbacks, read at invocation time so the memoised\n * inner component always calls the current props even though it never\n * re-renders.\n */\n callbacksRef: React.RefObject<PixodeskSvgAnimatorCallbacks>;\n}\n\n/** Lifecycle callback props (subset of {@link PixodeskSvgAnimatorProps}). */\nexport interface PixodeskSvgAnimatorCallbacks {\n onPlay?: () => void;\n onStop?: () => void;\n onPause?: () => void;\n onCancel?: () => void;\n onFinish?: () => void;\n onRemove?: () => void;\n}\n\nexport interface PixodeskSvgAnimatorProps {\n\n className?: string;\n\n style?: CSSProperties;\n\n // -- Source ---------------------------------------------------------------\n\n /**\n * The animation document to render.\n *\n * TODO: Accept PxFileConfig | string to support URL-based loading, e.g.\n * <PixodeskSvgAnimator doc=\"/animation.json\" />\n */\n doc: PxAnimatedSvgDocument;\n\n // -- Rendering mode ------------------------------------------------------\n\n /** Forces a specific rendering engine. Defaults to 'auto'. */\n mode?: JsMode;\n\n // -- Timing overrides ----------------------------------------------------\n\n /** Delay before the animation starts, in milliseconds. */\n delay?: number;\n\n /** Defines the element's style when the animation is not active. */\n fill?: FillMode;\n\n /** Number of iterations, or 'infinite' for endless looping. */\n iterations?: number | 'infinite';\n\n /** Duration of a single iteration in milliseconds. */\n duration?: number;\n\n /** Playback direction. */\n direction?: PlaybackDirection;\n\n /** Target frame rate (frames per second). */\n frameRate?: number;\n\n // -- Trigger overrides ---------------------------------------------------\n\n /** The event that starts the animation. When omitted, uses the value from the document config. */\n startOn?: StartOn;\n\n /** Behaviour when the trigger condition ends (e.g. mouse-out, second click). */\n outAction?: OutAction;\n\n /** Visibility ratio (0.0–1.0) required to trigger a scrollIntoView animation. Defaults to 0.5. */\n scrollIntoViewThreshold?: number;\n\n // -- Declarative control -------------------------------------------------\n\n /** When true, uses triggers defined in the animation document. */\n autoplay?: boolean;\n\n /**\n * Starts the animation unconditionally, ignoring document triggers.\n * Equivalent to `startOn=\"load\"` / `outAction=\"continue\"`.\n */\n play?: boolean;\n\n /** Pauses current playback. Only meaningful when `play` or `autoplay` is set. */\n pause?: boolean;\n\n // -- Imperative control --------------------------------------------------\n\n /** Ref populated with the imperative playback API. */\n apiRef?: React.RefObject<ReactAnimatorApi | null>;\n\n // -- Controlled (external) time ------------------------------------------\n\n /** Seek to a specific point in the animation, as a fraction (0–1) of the whole timeline (duration × iterations). */\n time?: number;\n\n /** Seek to a specific point in the animation (milliseconds). */\n timeMs?: number;\n\n // -- Callbacks -----------------------------------------------------------\n\n /** Called when the animation starts or resumes. */\n onPlay?: () => void;\n\n /** Called when the animation stops for any reason (pause / cancel / finish / removal). */\n onStop?: () => void;\n\n /** Called when the animation is paused. */\n onPause?: () => void;\n\n /** Called when the animation is cancelled. */\n onCancel?: () => void;\n\n /** Called when the animation finishes naturally. */\n onFinish?: () => void;\n\n /** Called when the animation is removed. */\n onRemove?: () => void;\n}\n\n\n// -- Internal types ---------------------------------------------------------\n\nenum PixodeskSvgAnimatorCompMode {\n static = 'static',\n autoplay = 'autoplay',\n play = 'play',\n imperativeApi = 'imperativeApi',\n fixedTime = 'fixedTime'\n}\n\n\n// -- React ↔ Animator bridge ------------------------------------------------\n\n/**\n * Creates a platform adapter that routes animator attribute updates\n * to the corresponding React-managed DOM refs.\n */\nexport function createReactAdapter(elementRefs: React.RefObject<Map<string, any>>) {\n const warnedSelectors = new Set<string>();\n\n const adapter: PxPlatformAdapter = {\n isConnected: () => {\n return true;\n },\n setAttribute: (id, attrName, value) => {\n\n attrName = camelCaseToKebabWordIfNeeded(attrName);\n\n const selector = getSelector(id);\n\n const element = elementRefs.current.get(id);\n\n if (!element && !warnedSelectors.has(selector)) {\n warnedSelectors.add(selector);\n console.warn('setAttribute: No elements found for selector \"' + selector + '\"');\n console.warn(elementRefs.current);\n }\n\n if (element) {\n element.setAttribute(attrName, value);\n if (STYLE_ATTR_NAMES.has(attrName)) {\n (element as HTMLElement).style[attrName as any] = value;\n }\n }\n },\n };\n return adapter;\n}\n\nexport function getSelector(id: string) {\n return '#' + id;\n}\n\n// FIXME: add model validation (e.g. isElementFileJson check)\n\n\n// -- Inner component (memoised, never re-renders) ---------------------------\n\nconst PixodeskSvgAnimatorImpl: FC<PixodeskSvgAnimatorImplProps> = ({\n className, style, doc, compMode, apiHolderRef, callbacksRef\n}) => {\n\n doc = generateNewIds(doc);\n\n const elementRefs = useRef(new Map<string, any>());\n\n const renderNode = (node: PxNode | undefined, isRoot = false): ReactElement | null => {\n if (!node) return null;\n\n const { type, animate, meta, children, ...props } = node;\n\n const normProps = getNormalizedProps(props);\n\n normProps['ref'] = (domEl: any) => {\n if (node['id']) elementRefs.current.set(node['id'], domEl);\n // return () => {};\n };\n\n // Apply the component's className/style props to the root SVG element.\n if (isRoot) {\n if (className) {\n normProps['className'] = normProps['className']\n ? normProps['className'] + ' ' + className\n : className;\n }\n if (style) normProps['style'] = style;\n }\n\n return createElement(type, normProps, children?.map(child => renderNode(child)));\n };\n\n const root = doc ? renderNode(doc, true) : null;\n\n // Create the animator once per document and tear it down on unmount.\n useEffect(() => {\n\n // Route lifecycle events through `callbacksRef` so the latest callback\n // props are invoked even though this component never re-renders.\n const cb = (name: keyof PixodeskSvgAnimatorCallbacks, alsoStop = false) => () => {\n callbacksRef.current?.[name]?.();\n if (alsoStop) callbacksRef.current?.onStop?.();\n };\n const callbacks = {\n onPlay: cb('onPlay'),\n onPause: cb('onPause', true),\n onCancel: cb('onCancel', true),\n onFinish: cb('onFinish', true),\n onRemove: cb('onRemove', true),\n };\n\n let api: PxAnimatorAPI | undefined = createAnimator({ data: doc, adapter: createReactAdapter(elementRefs), callbacks });\n apiHolderRef.current = api;\n\n return () => {\n api?.destroy();\n apiHolderRef.current = null;\n };\n }, [doc, apiHolderRef, callbacksRef]);\n\n return root;\n};\n\n/** Memoised wrapper — the inner component never re-renders (props are stable by design). */\nconst PixodeskSvgAnimatorImplOnce = React.memo(\n PixodeskSvgAnimatorImpl,\n () => true // Don't re-render\n);\n\n\n// -- Main public component --------------------------------------------------\n\n/**\n * React component for rendering and controlling Pixodesk SVG animations.\n *\n * Supports four mutually-exclusive control modes:\n *\n * 1. **Autoplay** – uses triggers from the animation document.\n * ```tsx\n * <PixodeskSvgAnimator doc={animation} autoplay />\n * ```\n *\n * 2. **Declarative play/pause** – controlled via boolean props.\n * ```tsx\n * <PixodeskSvgAnimator doc={animation} play pause={false} />\n * ```\n *\n * 3. **Imperative** – exposes a ref-based API for full programmatic control.\n * ```tsx\n * const api = useRef<ReactAnimatorApi>(null);\n * <PixodeskSvgAnimator doc={animation} apiRef={api} />\n * <button onClick={() => api.current?.play()}>Play</button>\n * ```\n *\n * 4. **Controlled time** – renders a single frame at a given time.\n * ```tsx\n * <PixodeskSvgAnimator doc={animation} time={0.5} />\n * <PixodeskSvgAnimator doc={animation} timeMs={500} />\n * ```\n */\nconst PixodeskSvgAnimator: FC<PixodeskSvgAnimatorProps> = ({\n className, style,\n doc, autoplay, play, pause, time, timeMs, apiRef,\n\n // Overrides\n mode, delay, fill, iterations, duration, direction, frameRate,\n\n startOn, outAction, scrollIntoViewThreshold,\n\n onPlay, onStop, onPause, onCancel, onFinish, onRemove\n}) => {\n\n // Determine which control mode is active.\n let compMode = PixodeskSvgAnimatorCompMode.static;\n if (apiRef) {\n compMode = PixodeskSvgAnimatorCompMode.imperativeApi;\n } else if (autoplay) {\n compMode = PixodeskSvgAnimatorCompMode.autoplay;\n } else if (time !== undefined || timeMs !== undefined) {\n compMode = PixodeskSvgAnimatorCompMode.fixedTime;\n } else if (play !== undefined || pause !== undefined) {\n compMode = PixodeskSvgAnimatorCompMode.play;\n }\n\n // In non-autoplay modes, override the document trigger to 'programmatic'\n // so the component can manage playback itself.\n if (compMode !== PixodeskSvgAnimatorCompMode.autoplay) {\n const startOn = doc.animator?.trigger?.startOn;\n if (\n startOn &&\n startOn !== 'programmatic' // FIXME: use enum\n ) {\n doc = {\n ...doc,\n animator: {\n ...doc.animator,\n trigger: {\n ...doc.animator?.trigger,\n startOn: 'programmatic' // FIXME: use enum\n }\n }\n };\n }\n }\n\n // Apply timing overrides from props onto the document config.\n if (\n mode !== undefined ||\n duration !== undefined ||\n delay !== undefined ||\n iterations !== undefined ||\n fill !== undefined ||\n direction !== undefined ||\n frameRate !== undefined\n ) {\n const animator = doc.animator || {};\n doc = {\n ...doc,\n animator: {\n ...animator,\n mode: mode !== undefined ? mode : animator.mode,\n duration: duration !== undefined ? duration : animator.duration,\n delay: delay !== undefined ? delay : animator.delay,\n iterations: iterations !== undefined ? iterations : animator.iterations,\n fill: fill !== undefined ? fill : animator.fill,\n direction: direction !== undefined ? direction : animator.direction,\n frameRate: frameRate !== undefined ? frameRate : animator.frameRate\n }\n };\n }\n\n // Apply trigger overrides from props.\n if (\n startOn !== undefined ||\n outAction !== undefined ||\n scrollIntoViewThreshold !== undefined\n ) {\n const trigger: PxTrigger = doc.animator?.trigger || {};\n doc = {\n ...doc,\n animator: {\n ...doc.animator,\n trigger: {\n ...trigger,\n startOn: startOn !== undefined ? startOn : trigger.startOn,\n outAction: outAction !== undefined ? outAction : trigger.outAction,\n scrollIntoViewThreshold: scrollIntoViewThreshold !== undefined ? scrollIntoViewThreshold : trigger.scrollIntoViewThreshold\n }\n }\n };\n }\n\n // Controlled-time mode: compute the absolute seek target. `time` is a\n // fraction (0–1) of the WHOLE timeline (duration × iterations); `timeMs`\n // is absolute milliseconds. The seek is applied through the animator API\n // (setCurrentTime) below — the document itself stays stable, so scrubbing\n // does NOT recreate the animator.\n let seekMs: number | undefined;\n if (compMode === PixodeskSvgAnimatorCompMode.fixedTime) {\n const animator = doc.animator || {};\n if (time !== undefined) {\n const iterationsValue = iterations ?? animator.iterations;\n const iterationsCount = typeof iterationsValue === 'number' && iterationsValue >= 1 ? iterationsValue : 1;\n const singleDuration = duration ?? animator.duration ?? 1000; // engine default duration\n seekMs = time * singleDuration * iterationsCount;\n }\n if (timeMs !== undefined) seekMs = timeMs;\n }\n\n const apiHolderRef = useRef<PxAnimatorAPI | null>(null);\n\n // Keep the latest callback props readable by the memoised inner component.\n const callbacksRef = useRef<PixodeskSvgAnimatorCallbacks>({});\n callbacksRef.current = { onPlay, onStop, onPause, onCancel, onFinish, onRemove };\n\n // Expose the imperative API via the consumer-provided ref.\n useImperativeHandle(apiRef, () => {\n return {\n isPlaying: () => apiHolderRef.current?.isPlaying() || false,\n play: () => apiHolderRef.current?.play(),\n pause: () => apiHolderRef.current?.pause(),\n cancel: () => apiHolderRef.current?.cancel(),\n finish: () => apiHolderRef.current?.finish(),\n setPlaybackRate: (rate: number) => apiHolderRef.current?.setPlaybackRate(rate),\n getCurrentTime: () => apiHolderRef.current?.getCurrentTime() ?? null,\n setCurrentTime: (time: number) => apiHolderRef.current?.setCurrentTime(time),\n };\n }, []);\n\n // Increment key when the document, mode, or root styling changes to force\n // a full remount (the inner component is memoised and never re-renders).\n const key = useDepsVersion(compMode, doc, className, style);\n\n // Sync declarative play/pause props with the animator. Re-runs after a\n // remount (`key` in deps) so a doc swap re-applies the current state.\n useEffect(() => {\n\n if (compMode === PixodeskSvgAnimatorCompMode.play) {\n if (play && !pause) {\n apiHolderRef.current?.play();\n } else if (pause) {\n apiHolderRef.current?.pause();\n } else if (play === false) {\n // explicit play=false → jump to the end state\n apiHolderRef.current?.finish();\n } else {\n // pause-only usage: pause switched off → resume\n apiHolderRef.current?.play();\n }\n }\n\n return () => {\n if (compMode === PixodeskSvgAnimatorCompMode.play) {\n // Intentionally read at cleanup time (NOT snapshotted at effect\n // time): the inner component nulls the ref when it destroys the\n // animator, so this pauses only a still-live instance. A\n // snapshot would call pause() on a destroyed animator and emit\n // a spurious onPause after teardown.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n apiHolderRef.current?.pause();\n }\n };\n }, [compMode, play, pause, key]);\n\n // Controlled-time mode: seek through the animator API. Scrubbing `time` /\n // `timeMs` only re-runs this effect — the animator is NOT recreated.\n useEffect(() => {\n if (compMode === PixodeskSvgAnimatorCompMode.fixedTime && seekMs !== undefined) {\n apiHolderRef.current?.setCurrentTime(seekMs);\n apiHolderRef.current?.pause();\n }\n }, [compMode, seekMs, key]);\n\n return (\n <PixodeskSvgAnimatorImplOnce\n key={key}\n className={className}\n style={style}\n compMode={compMode}\n doc={doc}\n apiHolderRef={apiHolderRef}\n callbacksRef={callbacksRef}\n />\n );\n};\n\nexport default PixodeskSvgAnimator;","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { useRef } from 'react';\n\nexport function deepEquals(a: any, b: any): boolean {\n // Handle primitives and null\n if (a === b) return true;\n if (a == null || b == null) return false;\n if (typeof a !== 'object' || typeof b !== 'object') return false;\n\n // Check for cycles using WeakSet\n const seen = new WeakSet();\n\n function equals(x: any, y: any): boolean {\n // Primitive/null check\n if (x === y) return true;\n if (x == null || y == null) return false;\n if (typeof x !== 'object' || typeof y !== 'object') return false;\n\n // Cycle detection\n if (seen.has(x)) {\n throw new Error('Circular reference detected');\n }\n seen.add(x);\n\n // Array check\n const xIsArray = Array.isArray(x);\n const yIsArray = Array.isArray(y);\n if (xIsArray !== yIsArray) return false;\n\n if (xIsArray) {\n if (x.length !== y.length) return false;\n for (let i = 0; i < x.length; i++) {\n if (!equals(x[i], y[i])) return false;\n }\n return true;\n }\n\n // Object check\n const xKeys = Object.keys(x);\n const yKeys = Object.keys(y);\n if (xKeys.length !== yKeys.length) return false;\n\n for (const key of xKeys) {\n if (!yKeys.includes(key)) return false;\n if (!equals(x[key], y[key])) return false;\n }\n\n return true;\n }\n\n return equals(a, b);\n}\n\n\n/**\n * Compares two arrays of dependencies using identity check first (===),\n * falling back to deep equality if references differ.\n * This is optimized for immutable data that may be recreated with same values.\n */\nfunction areDepsEqual(prevDeps: Array<any>, nextDeps: Array<any>): boolean {\n if (prevDeps.length !== nextDeps.length) return false;\n\n for (let i = 0; i < prevDeps.length; i++) {\n // Fast path: same reference (common for immutable data)\n if (prevDeps[i] === nextDeps[i]) continue;\n\n // Slow path: different reference but possibly same content\n if (!deepEquals(prevDeps[i], nextDeps[i])) return false;\n }\n\n return true;\n}\n\n/**\n * Returns a stable numeric version ID that only increments when dependencies\n * actually change (by reference or deep equality).\n */\nexport function useDepsVersion(...deps: Array<any>): number {\n const cache = useRef<{\n versionId: number;\n deps: Array<any>;\n } | null>(null);\n\n // First render - initialize with version 1\n if (cache.current === null) {\n cache.current = {\n versionId: 1,\n deps: deps\n };\n return 1;\n }\n\n // Check if any dependency changed (by reference or value)\n if (!areDepsEqual(cache.current.deps, deps)) {\n // Dependencies changed - increment version and update cache\n cache.current = {\n versionId: cache.current.versionId + 1,\n deps: deps\n };\n }\n\n return cache.current.versionId;\n}","/*---------------------------------------------------------------------------------------\n * Copyright (c) Pixodesk LTD.\n * Licensed under the MIT License. See the LICENSE file in the project root for details.\n *---------------------------------------------------------------------------------------*/\n\nimport { OutAction, StartOn } from \"@pixodesk/svg-animator-web\";\nimport { CSSProperties, FC, ReactNode, useEffect, useRef, useState } from \"react\";\n\n\ntype AnimState = 'idle' | 'paused' | 'playing';\n\n/**\n * Controls playback of a SVG+CSS animated files by toggling class names on a wrapper div.\n *\n * Intended for use with SVG files exported from the Pixodesk editor using the\n * **CSS Keyframes** (no `<script>` tag). Import the SVG as a React component\n * via SVGR (`vite-plugin-svgr` or `@svgr/webpack`) and pass it as `children`:\n *\n * ```tsx\n * import AnimationSvg from './animation.svg?react'; // SVGR\n *\n * <PixodeskSvgCssAnimator startOn=\"mouseOver\" outAction=\"pause\">\n * <AnimationSvg />\n * </PixodeskSvgCssAnimator>\n * ```\n *\n * The wrapper div carries one of three animation states via CSS class names:\n * - *(no class)* — idle, animation not started\n * - `px-anim-enabled` — started but paused\n * - `px-anim-enabled px-anim-playing` — actively playing\n *\n * @param children - The SVGR-imported SVG component to animate.\n * @param startOn - What triggers the animation to start:\n * - `'load'` — plays immediately on mount (default)\n * - `'mouseOver'` — plays on hover\n * - `'click'` — plays on click, toggles on second click\n * - `'scrollIntoView'` — plays when the element enters the viewport\n * @param outAction - What happens when the trigger ends (hover/scroll out, second click):\n * - `'continue'` — keeps playing (default)\n * - `'pause'` — pauses at the current frame\n * - `'reset'` — resets to the beginning\n * @param className - Additional CSS class names to apply to the wrapper div.\n * @param style - Inline styles for the wrapper div (e.g. `{ width: 400, height: 400 }`).\n */\nconst PixodeskSvgCssAnimator: FC<{\n className?: string;\n style?: CSSProperties;\n children: ReactNode;\n startOn?: StartOn;\n outAction?: OutAction;\n}> = ({ className, style, children, startOn = 'load', outAction = 'continue' }) => {\n\n const [state, setState] = useState<AnimState>(startOn === 'load' ? 'playing' : 'idle');\n\n const ref = useRef<HTMLDivElement>(null);\n\n useEffect(() => {\n if (startOn !== 'scrollIntoView') return;\n const el = ref.current;\n if (!el) return;\n const outState: AnimState = (\n outAction === 'reset' ? 'idle' :\n outAction === 'pause' ? 'paused' : 'playing'\n );\n const observer = new IntersectionObserver(\n ([entry]) => setState(entry.isIntersecting ? 'playing' : outState),\n { threshold: 0.1 }\n );\n observer.observe(el);\n return () => observer.disconnect();\n }, [startOn, outAction]);\n\n const goOut = () => setState(\n outAction === 'reset' ? 'idle' :\n outAction === 'pause' ? 'paused' : 'playing'\n );\n\n const handlers =\n startOn === 'mouseOver' ? { onMouseEnter: () => setState('playing'), onMouseLeave: goOut } :\n startOn === 'click' ? { onClick: () => state === 'playing' ? goOut() : setState('playing') } :\n {};\n\n return (\n <div\n ref={ref}\n className={[\n className,\n state === 'playing' ? 'px-anim-enabled px-anim-playing' :\n state === 'paused' ? 'px-anim-enabled' : ''\n ].filter(Boolean).join(' ')}\n style={style}\n {...handlers}\n >\n {children}\n </div>\n );\n};\nexport default PixodeskSvgCssAnimator;"],"mappings":"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","names":["React","__spreadValues","__spreadValues","__spreadProps","__spreadValues","__spreadProps","__spreadValues","str","pathStr","_a","_b","out","num","genId","walkAndMaterialise","clone","stripHash","kfs","remap","clamp","resolveStyle","_c","_d","resolveStyle","__spreadProps","__spreadValues","__spreadProps","__spreadValues","v","stripHash","effectiveProgress","_a","_a","import_react","getSelector","renderNode","React","startOn","time","import_react","import_jsx_runtime"]}
|