diff --git a/dist/tldraw-react-ha.js b/dist/tldraw-react-ha.js index 61eb110..b234a30 100644 --- a/dist/tldraw-react-ha.js +++ b/dist/tldraw-react-ha.js @@ -2,25695 +2,44077 @@ var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s, _t; -function _mergeNamespaces(n2, m2) { +function _mergeNamespaces(n, m2) { for (var i2 = 0; i2 < m2.length; i2++) { const e2 = m2[i2]; if (typeof e2 !== "string" && !Array.isArray(e2)) { - for (const k2 in e2) { - if (k2 !== "default" && !(k2 in n2)) { - const d2 = Object.getOwnPropertyDescriptor(e2, k2); + for (const k in e2) { + if (k !== "default" && !(k in n)) { + const d2 = Object.getOwnPropertyDescriptor(e2, k); if (d2) { - Object.defineProperty(n2, k2, d2.get ? d2 : { + Object.defineProperty(n, k, d2.get ? d2 : { enumerable: true, - get: () => e2[k2] + get: () => e2[k] }); } } } } } - return Object.freeze(Object.defineProperty(n2, Symbol.toStringTag, { value: "Module" })); + return Object.freeze(Object.defineProperty(n, Symbol.toStringTag, { value: "Module" })); } var commonjsGlobal = typeof globalThis !== "undefined" ? globalThis : typeof window !== "undefined" ? window : typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : {}; function getDefaultExportFromCjs(x2) { return x2 && x2.__esModule && Object.prototype.hasOwnProperty.call(x2, "default") ? x2["default"] : x2; } -var jsxRuntime = { exports: {} }; -var reactJsxRuntime_production_min = {}; +var jsxDevRuntime = { exports: {} }; +var reactJsxDevRuntime_development = {}; var react$1 = { exports: {} }; -var react_production_min = {}; -/** - * @license React - * react.production.min.js - * - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ -var l$3 = Symbol.for("react.element"), n$2 = Symbol.for("react.portal"), p$4 = Symbol.for("react.fragment"), q$2 = Symbol.for("react.strict_mode"), r$1 = Symbol.for("react.profiler"), t$3 = Symbol.for("react.provider"), u$2 = Symbol.for("react.context"), v$2 = Symbol.for("react.forward_ref"), w$2 = Symbol.for("react.suspense"), x$1 = Symbol.for("react.memo"), y$1 = Symbol.for("react.lazy"), z$1 = Symbol.iterator; -function A$1(a2) { - if (null === a2 || "object" !== typeof a2) return null; - a2 = z$1 && a2[z$1] || a2["@@iterator"]; - return "function" === typeof a2 ? a2 : null; +var react_development = { exports: {} }; +react_development.exports; +(function(module, exports) { + /** + * @license React + * react.development.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + { + (function() { + if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart === "function") { + __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error()); + } + var ReactVersion = "18.3.1"; + var REACT_ELEMENT_TYPE = Symbol.for("react.element"); + var REACT_PORTAL_TYPE = Symbol.for("react.portal"); + var REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"); + var REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"); + var REACT_PROFILER_TYPE = Symbol.for("react.profiler"); + var REACT_PROVIDER_TYPE = Symbol.for("react.provider"); + var REACT_CONTEXT_TYPE = Symbol.for("react.context"); + var REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"); + var REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"); + var REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"); + var REACT_MEMO_TYPE = Symbol.for("react.memo"); + var REACT_LAZY_TYPE = Symbol.for("react.lazy"); + var REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"); + var MAYBE_ITERATOR_SYMBOL = Symbol.iterator; + var FAUX_ITERATOR_SYMBOL = "@@iterator"; + function getIteratorFn(maybeIterable) { + if (maybeIterable === null || typeof maybeIterable !== "object") { + return null; + } + var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]; + if (typeof maybeIterator === "function") { + return maybeIterator; + } + return null; + } + var ReactCurrentDispatcher = { + /** + * @internal + * @type {ReactComponent} + */ + current: null + }; + var ReactCurrentBatchConfig = { + transition: null + }; + var ReactCurrentActQueue = { + current: null, + // Used to reproduce behavior of `batchedUpdates` in legacy mode. + isBatchingLegacy: false, + didScheduleLegacyUpdate: false + }; + var ReactCurrentOwner = { + /** + * @internal + * @type {ReactComponent} + */ + current: null + }; + var ReactDebugCurrentFrame = {}; + var currentExtraStackFrame = null; + function setExtraStackFrame(stack2) { + { + currentExtraStackFrame = stack2; + } + } + { + ReactDebugCurrentFrame.setExtraStackFrame = function(stack2) { + { + currentExtraStackFrame = stack2; + } + }; + ReactDebugCurrentFrame.getCurrentStack = null; + ReactDebugCurrentFrame.getStackAddendum = function() { + var stack2 = ""; + if (currentExtraStackFrame) { + stack2 += currentExtraStackFrame; + } + var impl2 = ReactDebugCurrentFrame.getCurrentStack; + if (impl2) { + stack2 += impl2() || ""; + } + return stack2; + }; + } + var enableScopeAPI = false; + var enableCacheElement = false; + var enableTransitionTracing = false; + var enableLegacyHidden = false; + var enableDebugTracing = false; + var ReactSharedInternals = { + ReactCurrentDispatcher, + ReactCurrentBatchConfig, + ReactCurrentOwner + }; + { + ReactSharedInternals.ReactDebugCurrentFrame = ReactDebugCurrentFrame; + ReactSharedInternals.ReactCurrentActQueue = ReactCurrentActQueue; + } + function warn(format2) { + { + { + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + printWarning("warn", format2, args); + } + } + } + function error(format2) { + { + { + for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + args[_key2 - 1] = arguments[_key2]; + } + printWarning("error", format2, args); + } + } + } + function printWarning(level, format2, args) { + { + var ReactDebugCurrentFrame2 = ReactSharedInternals.ReactDebugCurrentFrame; + var stack2 = ReactDebugCurrentFrame2.getStackAddendum(); + if (stack2 !== "") { + format2 += "%s"; + args = args.concat([stack2]); + } + var argsWithFormat = args.map(function(item) { + return String(item); + }); + argsWithFormat.unshift("Warning: " + format2); + Function.prototype.apply.call(console[level], console, argsWithFormat); + } + } + var didWarnStateUpdateForUnmountedComponent = {}; + function warnNoop(publicInstance, callerName) { + { + var _constructor = publicInstance.constructor; + var componentName = _constructor && (_constructor.displayName || _constructor.name) || "ReactClass"; + var warningKey = componentName + "." + callerName; + if (didWarnStateUpdateForUnmountedComponent[warningKey]) { + return; + } + error("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.", callerName, componentName); + didWarnStateUpdateForUnmountedComponent[warningKey] = true; + } + } + var ReactNoopUpdateQueue = { + /** + * Checks whether or not this composite component is mounted. + * @param {ReactClass} publicInstance The instance we want to test. + * @return {boolean} True if mounted, false otherwise. + * @protected + * @final + */ + isMounted: function(publicInstance) { + return false; + }, + /** + * Forces an update. This should only be invoked when it is known with + * certainty that we are **not** in a DOM transaction. + * + * You may want to call this when you know that some deeper aspect of the + * component's state has changed but `setState` was not called. + * + * This will not invoke `shouldComponentUpdate`, but it will invoke + * `componentWillUpdate` and `componentDidUpdate`. + * + * @param {ReactClass} publicInstance The instance that should rerender. + * @param {?function} callback Called after component is updated. + * @param {?string} callerName name of the calling function in the public API. + * @internal + */ + enqueueForceUpdate: function(publicInstance, callback, callerName) { + warnNoop(publicInstance, "forceUpdate"); + }, + /** + * Replaces all of the state. Always use this or `setState` to mutate state. + * You should treat `this.state` as immutable. + * + * There is no guarantee that `this.state` will be immediately updated, so + * accessing `this.state` after calling this method may return the old value. + * + * @param {ReactClass} publicInstance The instance that should rerender. + * @param {object} completeState Next state. + * @param {?function} callback Called after component is updated. + * @param {?string} callerName name of the calling function in the public API. + * @internal + */ + enqueueReplaceState: function(publicInstance, completeState, callback, callerName) { + warnNoop(publicInstance, "replaceState"); + }, + /** + * Sets a subset of the state. This only exists because _pendingState is + * internal. This provides a merging strategy that is not available to deep + * properties which is confusing. TODO: Expose pendingState or don't use it + * during the merge. + * + * @param {ReactClass} publicInstance The instance that should rerender. + * @param {object} partialState Next partial state to be merged with state. + * @param {?function} callback Called after component is updated. + * @param {?string} Name of the calling function in the public API. + * @internal + */ + enqueueSetState: function(publicInstance, partialState, callback, callerName) { + warnNoop(publicInstance, "setState"); + } + }; + var assign = Object.assign; + var emptyObject = {}; + { + Object.freeze(emptyObject); + } + function Component(props, context, updater) { + this.props = props; + this.context = context; + this.refs = emptyObject; + this.updater = updater || ReactNoopUpdateQueue; + } + Component.prototype.isReactComponent = {}; + Component.prototype.setState = function(partialState, callback) { + if (typeof partialState !== "object" && typeof partialState !== "function" && partialState != null) { + throw new Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables."); + } + this.updater.enqueueSetState(this, partialState, callback, "setState"); + }; + Component.prototype.forceUpdate = function(callback) { + this.updater.enqueueForceUpdate(this, callback, "forceUpdate"); + }; + { + var deprecatedAPIs = { + isMounted: ["isMounted", "Instead, make sure to clean up subscriptions and pending requests in componentWillUnmount to prevent memory leaks."], + replaceState: ["replaceState", "Refactor your code to use setState instead (see https://github.com/facebook/react/issues/3236)."] + }; + var defineDeprecationWarning = function(methodName, info) { + Object.defineProperty(Component.prototype, methodName, { + get: function() { + warn("%s(...) is deprecated in plain JavaScript React classes. %s", info[0], info[1]); + return void 0; + } + }); + }; + for (var fnName in deprecatedAPIs) { + if (deprecatedAPIs.hasOwnProperty(fnName)) { + defineDeprecationWarning(fnName, deprecatedAPIs[fnName]); + } + } + } + function ComponentDummy() { + } + ComponentDummy.prototype = Component.prototype; + function PureComponent(props, context, updater) { + this.props = props; + this.context = context; + this.refs = emptyObject; + this.updater = updater || ReactNoopUpdateQueue; + } + var pureComponentPrototype = PureComponent.prototype = new ComponentDummy(); + pureComponentPrototype.constructor = PureComponent; + assign(pureComponentPrototype, Component.prototype); + pureComponentPrototype.isPureReactComponent = true; + function createRef() { + var refObject = { + current: null + }; + { + Object.seal(refObject); + } + return refObject; + } + var isArrayImpl = Array.isArray; + function isArray3(a2) { + return isArrayImpl(a2); + } + function typeName(value) { + { + var hasToStringTag = typeof Symbol === "function" && Symbol.toStringTag; + var type = hasToStringTag && value[Symbol.toStringTag] || value.constructor.name || "Object"; + return type; + } + } + function willCoercionThrow(value) { + { + try { + testStringCoercion(value); + return false; + } catch (e2) { + return true; + } + } + } + function testStringCoercion(value) { + return "" + value; + } + function checkKeyStringCoercion(value) { + { + if (willCoercionThrow(value)) { + error("The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.", typeName(value)); + return testStringCoercion(value); + } + } + } + function getWrappedName(outerType, innerType, wrapperName) { + var displayName = outerType.displayName; + if (displayName) { + return displayName; + } + var functionName2 = innerType.displayName || innerType.name || ""; + return functionName2 !== "" ? wrapperName + "(" + functionName2 + ")" : wrapperName; + } + function getContextName(type) { + return type.displayName || "Context"; + } + function getComponentNameFromType(type) { + if (type == null) { + return null; + } + { + if (typeof type.tag === "number") { + error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."); + } + } + if (typeof type === "function") { + return type.displayName || type.name || null; + } + if (typeof type === "string") { + return type; + } + switch (type) { + case REACT_FRAGMENT_TYPE: + return "Fragment"; + case REACT_PORTAL_TYPE: + return "Portal"; + case REACT_PROFILER_TYPE: + return "Profiler"; + case REACT_STRICT_MODE_TYPE: + return "StrictMode"; + case REACT_SUSPENSE_TYPE: + return "Suspense"; + case REACT_SUSPENSE_LIST_TYPE: + return "SuspenseList"; + } + if (typeof type === "object") { + switch (type.$$typeof) { + case REACT_CONTEXT_TYPE: + var context = type; + return getContextName(context) + ".Consumer"; + case REACT_PROVIDER_TYPE: + var provider = type; + return getContextName(provider._context) + ".Provider"; + case REACT_FORWARD_REF_TYPE: + return getWrappedName(type, type.render, "ForwardRef"); + case REACT_MEMO_TYPE: + var outerName = type.displayName || null; + if (outerName !== null) { + return outerName; + } + return getComponentNameFromType(type.type) || "Memo"; + case REACT_LAZY_TYPE: { + var lazyComponent = type; + var payload = lazyComponent._payload; + var init = lazyComponent._init; + try { + return getComponentNameFromType(init(payload)); + } catch (x2) { + return null; + } + } + } + } + return null; + } + var hasOwnProperty2 = Object.prototype.hasOwnProperty; + var RESERVED_PROPS = { + key: true, + ref: true, + __self: true, + __source: true + }; + var specialPropKeyWarningShown, specialPropRefWarningShown, didWarnAboutStringRefs; + { + didWarnAboutStringRefs = {}; + } + function hasValidRef(config) { + { + if (hasOwnProperty2.call(config, "ref")) { + var getter = Object.getOwnPropertyDescriptor(config, "ref").get; + if (getter && getter.isReactWarning) { + return false; + } + } + } + return config.ref !== void 0; + } + function hasValidKey(config) { + { + if (hasOwnProperty2.call(config, "key")) { + var getter = Object.getOwnPropertyDescriptor(config, "key").get; + if (getter && getter.isReactWarning) { + return false; + } + } + } + return config.key !== void 0; + } + function defineKeyPropWarningGetter(props, displayName) { + var warnAboutAccessingKey = function() { + { + if (!specialPropKeyWarningShown) { + specialPropKeyWarningShown = true; + error("%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://reactjs.org/link/special-props)", displayName); + } + } + }; + warnAboutAccessingKey.isReactWarning = true; + Object.defineProperty(props, "key", { + get: warnAboutAccessingKey, + configurable: true + }); + } + function defineRefPropWarningGetter(props, displayName) { + var warnAboutAccessingRef = function() { + { + if (!specialPropRefWarningShown) { + specialPropRefWarningShown = true; + error("%s: `ref` 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://reactjs.org/link/special-props)", displayName); + } + } + }; + warnAboutAccessingRef.isReactWarning = true; + Object.defineProperty(props, "ref", { + get: warnAboutAccessingRef, + configurable: true + }); + } + function warnIfStringRefCannotBeAutoConverted(config) { + { + if (typeof config.ref === "string" && ReactCurrentOwner.current && config.__self && ReactCurrentOwner.current.stateNode !== config.__self) { + var componentName = getComponentNameFromType(ReactCurrentOwner.current.type); + if (!didWarnAboutStringRefs[componentName]) { + error('Component "%s" contains the string ref "%s". Support for string refs will be removed in a future major release. This case cannot be automatically converted to an arrow function. We ask you to manually fix this case by using useRef() or createRef() instead. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref', componentName, config.ref); + didWarnAboutStringRefs[componentName] = true; + } + } + } + } + var ReactElement = function(type, key, ref, self2, source, owner, props) { + var element = { + // This tag allows us to uniquely identify this as a React Element + $$typeof: REACT_ELEMENT_TYPE, + // Built-in properties that belong on the element + type, + key, + ref, + props, + // Record the component responsible for creating this element. + _owner: owner + }; + { + element._store = {}; + Object.defineProperty(element._store, "validated", { + configurable: false, + enumerable: false, + writable: true, + value: false + }); + Object.defineProperty(element, "_self", { + configurable: false, + enumerable: false, + writable: false, + value: self2 + }); + Object.defineProperty(element, "_source", { + configurable: false, + enumerable: false, + writable: false, + value: source + }); + if (Object.freeze) { + Object.freeze(element.props); + Object.freeze(element); + } + } + return element; + }; + function createElement2(type, config, children) { + var propName; + var props = {}; + var key = null; + var ref = null; + var self2 = null; + var source = null; + if (config != null) { + if (hasValidRef(config)) { + ref = config.ref; + { + warnIfStringRefCannotBeAutoConverted(config); + } + } + if (hasValidKey(config)) { + { + checkKeyStringCoercion(config.key); + } + key = "" + config.key; + } + self2 = config.__self === void 0 ? null : config.__self; + source = config.__source === void 0 ? null : config.__source; + for (propName in config) { + if (hasOwnProperty2.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) { + props[propName] = config[propName]; + } + } + } + var childrenLength = arguments.length - 2; + if (childrenLength === 1) { + props.children = children; + } else if (childrenLength > 1) { + var childArray = Array(childrenLength); + for (var i2 = 0; i2 < childrenLength; i2++) { + childArray[i2] = arguments[i2 + 2]; + } + { + if (Object.freeze) { + Object.freeze(childArray); + } + } + props.children = childArray; + } + if (type && type.defaultProps) { + var defaultProps = type.defaultProps; + for (propName in defaultProps) { + if (props[propName] === void 0) { + props[propName] = defaultProps[propName]; + } + } + } + { + if (key || ref) { + var displayName = typeof type === "function" ? type.displayName || type.name || "Unknown" : type; + if (key) { + defineKeyPropWarningGetter(props, displayName); + } + if (ref) { + defineRefPropWarningGetter(props, displayName); + } + } + } + return ReactElement(type, key, ref, self2, source, ReactCurrentOwner.current, props); + } + function cloneAndReplaceKey(oldElement, newKey) { + var newElement = ReactElement(oldElement.type, newKey, oldElement.ref, oldElement._self, oldElement._source, oldElement._owner, oldElement.props); + return newElement; + } + function cloneElement(element, config, children) { + if (element === null || element === void 0) { + throw new Error("React.cloneElement(...): The argument must be a React element, but you passed " + element + "."); + } + var propName; + var props = assign({}, element.props); + var key = element.key; + var ref = element.ref; + var self2 = element._self; + var source = element._source; + var owner = element._owner; + if (config != null) { + if (hasValidRef(config)) { + ref = config.ref; + owner = ReactCurrentOwner.current; + } + if (hasValidKey(config)) { + { + checkKeyStringCoercion(config.key); + } + key = "" + config.key; + } + var defaultProps; + if (element.type && element.type.defaultProps) { + defaultProps = element.type.defaultProps; + } + for (propName in config) { + if (hasOwnProperty2.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) { + if (config[propName] === void 0 && defaultProps !== void 0) { + props[propName] = defaultProps[propName]; + } else { + props[propName] = config[propName]; + } + } + } + } + var childrenLength = arguments.length - 2; + if (childrenLength === 1) { + props.children = children; + } else if (childrenLength > 1) { + var childArray = Array(childrenLength); + for (var i2 = 0; i2 < childrenLength; i2++) { + childArray[i2] = arguments[i2 + 2]; + } + props.children = childArray; + } + return ReactElement(element.type, key, ref, self2, source, owner, props); + } + function isValidElement(object2) { + return typeof object2 === "object" && object2 !== null && object2.$$typeof === REACT_ELEMENT_TYPE; + } + var SEPARATOR = "."; + var SUBSEPARATOR = ":"; + function escape(key) { + var escapeRegex = /[=:]/g; + var escaperLookup = { + "=": "=0", + ":": "=2" + }; + var escapedString = key.replace(escapeRegex, function(match2) { + return escaperLookup[match2]; + }); + return "$" + escapedString; + } + var didWarnAboutMaps = false; + var userProvidedKeyEscapeRegex = /\/+/g; + function escapeUserProvidedKey(text) { + return text.replace(userProvidedKeyEscapeRegex, "$&/"); + } + function getElementKey(element, index2) { + if (typeof element === "object" && element !== null && element.key != null) { + { + checkKeyStringCoercion(element.key); + } + return escape("" + element.key); + } + return index2.toString(36); + } + function mapIntoArray(children, array2, escapedPrefix, nameSoFar, callback) { + var type = typeof children; + if (type === "undefined" || type === "boolean") { + children = null; + } + var invokeCallback = false; + if (children === null) { + invokeCallback = true; + } else { + switch (type) { + case "string": + case "number": + invokeCallback = true; + break; + case "object": + switch (children.$$typeof) { + case REACT_ELEMENT_TYPE: + case REACT_PORTAL_TYPE: + invokeCallback = true; + } + } + } + if (invokeCallback) { + var _child = children; + var mappedChild = callback(_child); + var childKey = nameSoFar === "" ? SEPARATOR + getElementKey(_child, 0) : nameSoFar; + if (isArray3(mappedChild)) { + var escapedChildKey = ""; + if (childKey != null) { + escapedChildKey = escapeUserProvidedKey(childKey) + "/"; + } + mapIntoArray(mappedChild, array2, escapedChildKey, "", function(c2) { + return c2; + }); + } else if (mappedChild != null) { + if (isValidElement(mappedChild)) { + { + if (mappedChild.key && (!_child || _child.key !== mappedChild.key)) { + checkKeyStringCoercion(mappedChild.key); + } + } + mappedChild = cloneAndReplaceKey( + mappedChild, + // Keep both the (mapped) and old keys if they differ, just as + // traverseAllChildren used to do for objects as children + escapedPrefix + // $FlowFixMe Flow incorrectly thinks React.Portal doesn't have a key + (mappedChild.key && (!_child || _child.key !== mappedChild.key) ? ( + // $FlowFixMe Flow incorrectly thinks existing element's key can be a number + // eslint-disable-next-line react-internal/safe-string-coercion + escapeUserProvidedKey("" + mappedChild.key) + "/" + ) : "") + childKey + ); + } + array2.push(mappedChild); + } + return 1; + } + var child; + var nextName; + var subtreeCount = 0; + var nextNamePrefix = nameSoFar === "" ? SEPARATOR : nameSoFar + SUBSEPARATOR; + if (isArray3(children)) { + for (var i2 = 0; i2 < children.length; i2++) { + child = children[i2]; + nextName = nextNamePrefix + getElementKey(child, i2); + subtreeCount += mapIntoArray(child, array2, escapedPrefix, nextName, callback); + } + } else { + var iteratorFn = getIteratorFn(children); + if (typeof iteratorFn === "function") { + var iterableChildren = children; + { + if (iteratorFn === iterableChildren.entries) { + if (!didWarnAboutMaps) { + warn("Using Maps as children is not supported. Use an array of keyed ReactElements instead."); + } + didWarnAboutMaps = true; + } + } + var iterator = iteratorFn.call(iterableChildren); + var step; + var ii = 0; + while (!(step = iterator.next()).done) { + child = step.value; + nextName = nextNamePrefix + getElementKey(child, ii++); + subtreeCount += mapIntoArray(child, array2, escapedPrefix, nextName, callback); + } + } else if (type === "object") { + var childrenString = String(children); + throw new Error("Objects are not valid as a React child (found: " + (childrenString === "[object Object]" ? "object with keys {" + Object.keys(children).join(", ") + "}" : childrenString) + "). If you meant to render a collection of children, use an array instead."); + } + } + return subtreeCount; + } + function mapChildren(children, func, context) { + if (children == null) { + return children; + } + var result = []; + var count2 = 0; + mapIntoArray(children, result, "", "", function(child) { + return func.call(context, child, count2++); + }); + return result; + } + function countChildren(children) { + var n = 0; + mapChildren(children, function() { + n++; + }); + return n; + } + function forEachChildren(children, forEachFunc, forEachContext) { + mapChildren(children, function() { + forEachFunc.apply(this, arguments); + }, forEachContext); + } + function toArray(children) { + return mapChildren(children, function(child) { + return child; + }) || []; + } + function onlyChild(children) { + if (!isValidElement(children)) { + throw new Error("React.Children.only expected to receive a single React element child."); + } + return children; + } + function createContext(defaultValue) { + var context = { + $$typeof: REACT_CONTEXT_TYPE, + // As a workaround to support multiple concurrent renderers, we categorize + // some renderers as primary and others as secondary. We only expect + // there to be two concurrent renderers at most: React Native (primary) and + // Fabric (secondary); React DOM (primary) and React ART (secondary). + // Secondary renderers store their context values on separate fields. + _currentValue: defaultValue, + _currentValue2: defaultValue, + // Used to track how many concurrent renderers this context currently + // supports within in a single renderer. Such as parallel server rendering. + _threadCount: 0, + // These are circular + Provider: null, + Consumer: null, + // Add these to use same hidden class in VM as ServerContext + _defaultValue: null, + _globalName: null + }; + context.Provider = { + $$typeof: REACT_PROVIDER_TYPE, + _context: context + }; + var hasWarnedAboutUsingNestedContextConsumers = false; + var hasWarnedAboutUsingConsumerProvider = false; + var hasWarnedAboutDisplayNameOnConsumer = false; + { + var Consumer = { + $$typeof: REACT_CONTEXT_TYPE, + _context: context + }; + Object.defineProperties(Consumer, { + Provider: { + get: function() { + if (!hasWarnedAboutUsingConsumerProvider) { + hasWarnedAboutUsingConsumerProvider = true; + error("Rendering is not supported and will be removed in a future major release. Did you mean to render instead?"); + } + return context.Provider; + }, + set: function(_Provider) { + context.Provider = _Provider; + } + }, + _currentValue: { + get: function() { + return context._currentValue; + }, + set: function(_currentValue) { + context._currentValue = _currentValue; + } + }, + _currentValue2: { + get: function() { + return context._currentValue2; + }, + set: function(_currentValue2) { + context._currentValue2 = _currentValue2; + } + }, + _threadCount: { + get: function() { + return context._threadCount; + }, + set: function(_threadCount) { + context._threadCount = _threadCount; + } + }, + Consumer: { + get: function() { + if (!hasWarnedAboutUsingNestedContextConsumers) { + hasWarnedAboutUsingNestedContextConsumers = true; + error("Rendering is not supported and will be removed in a future major release. Did you mean to render instead?"); + } + return context.Consumer; + } + }, + displayName: { + get: function() { + return context.displayName; + }, + set: function(displayName) { + if (!hasWarnedAboutDisplayNameOnConsumer) { + warn("Setting `displayName` on Context.Consumer has no effect. You should set it directly on the context with Context.displayName = '%s'.", displayName); + hasWarnedAboutDisplayNameOnConsumer = true; + } + } + } + }); + context.Consumer = Consumer; + } + { + context._currentRenderer = null; + context._currentRenderer2 = null; + } + return context; + } + var Uninitialized = -1; + var Pending = 0; + var Resolved = 1; + var Rejected = 2; + function lazyInitializer(payload) { + if (payload._status === Uninitialized) { + var ctor = payload._result; + var thenable = ctor(); + thenable.then(function(moduleObject2) { + if (payload._status === Pending || payload._status === Uninitialized) { + var resolved = payload; + resolved._status = Resolved; + resolved._result = moduleObject2; + } + }, function(error2) { + if (payload._status === Pending || payload._status === Uninitialized) { + var rejected = payload; + rejected._status = Rejected; + rejected._result = error2; + } + }); + if (payload._status === Uninitialized) { + var pending = payload; + pending._status = Pending; + pending._result = thenable; + } + } + if (payload._status === Resolved) { + var moduleObject = payload._result; + { + if (moduleObject === void 0) { + error("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?", moduleObject); + } + } + { + if (!("default" in moduleObject)) { + error("lazy: Expected the result of a dynamic import() call. Instead received: %s\n\nYour code should look like: \n const MyComponent = lazy(() => import('./MyComponent'))", moduleObject); + } + } + return moduleObject.default; + } else { + throw payload._result; + } + } + function lazy(ctor) { + var payload = { + // We use these fields to store the result. + _status: Uninitialized, + _result: ctor + }; + var lazyType = { + $$typeof: REACT_LAZY_TYPE, + _payload: payload, + _init: lazyInitializer + }; + { + var defaultProps; + var propTypes; + Object.defineProperties(lazyType, { + defaultProps: { + configurable: true, + get: function() { + return defaultProps; + }, + set: function(newDefaultProps) { + error("React.lazy(...): It is not supported to assign `defaultProps` to a lazy component import. Either specify them where the component is defined, or create a wrapping component around it."); + defaultProps = newDefaultProps; + Object.defineProperty(lazyType, "defaultProps", { + enumerable: true + }); + } + }, + propTypes: { + configurable: true, + get: function() { + return propTypes; + }, + set: function(newPropTypes) { + error("React.lazy(...): It is not supported to assign `propTypes` to a lazy component import. Either specify them where the component is defined, or create a wrapping component around it."); + propTypes = newPropTypes; + Object.defineProperty(lazyType, "propTypes", { + enumerable: true + }); + } + } + }); + } + return lazyType; + } + function forwardRef(render) { + { + if (render != null && render.$$typeof === REACT_MEMO_TYPE) { + error("forwardRef requires a render function but received a `memo` component. Instead of forwardRef(memo(...)), use memo(forwardRef(...))."); + } else if (typeof render !== "function") { + error("forwardRef requires a render function but was given %s.", render === null ? "null" : typeof render); + } else { + if (render.length !== 0 && render.length !== 2) { + error("forwardRef render functions accept exactly two parameters: props and ref. %s", render.length === 1 ? "Did you forget to use the ref parameter?" : "Any additional parameter will be undefined."); + } + } + if (render != null) { + if (render.defaultProps != null || render.propTypes != null) { + error("forwardRef render functions do not support propTypes or defaultProps. Did you accidentally pass a React component?"); + } + } + } + var elementType = { + $$typeof: REACT_FORWARD_REF_TYPE, + render + }; + { + var ownName; + Object.defineProperty(elementType, "displayName", { + enumerable: false, + configurable: true, + get: function() { + return ownName; + }, + set: function(name) { + ownName = name; + if (!render.name && !render.displayName) { + render.displayName = name; + } + } + }); + } + return elementType; + } + var REACT_MODULE_REFERENCE; + { + REACT_MODULE_REFERENCE = Symbol.for("react.module.reference"); + } + function isValidElementType(type) { + if (typeof type === "string" || typeof type === "function") { + return true; + } + if (type === REACT_FRAGMENT_TYPE || type === REACT_PROFILER_TYPE || enableDebugTracing || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || enableLegacyHidden || type === REACT_OFFSCREEN_TYPE || enableScopeAPI || enableCacheElement || enableTransitionTracing) { + return true; + } + if (typeof type === "object" && type !== null) { + if (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || // This needs to include all possible module reference object + // types supported by any Flight configuration anywhere since + // we don't know which Flight build this will end up being used + // with. + type.$$typeof === REACT_MODULE_REFERENCE || type.getModuleId !== void 0) { + return true; + } + } + return false; + } + function memo2(type, compare) { + { + if (!isValidElementType(type)) { + error("memo: The first argument must be a component. Instead received: %s", type === null ? "null" : typeof type); + } + } + var elementType = { + $$typeof: REACT_MEMO_TYPE, + type, + compare: compare === void 0 ? null : compare + }; + { + var ownName; + Object.defineProperty(elementType, "displayName", { + enumerable: false, + configurable: true, + get: function() { + return ownName; + }, + set: function(name) { + ownName = name; + if (!type.name && !type.displayName) { + type.displayName = name; + } + } + }); + } + return elementType; + } + function resolveDispatcher() { + var dispatcher = ReactCurrentDispatcher.current; + { + if (dispatcher === null) { + error("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://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem."); + } + } + return dispatcher; + } + function useContext(Context2) { + var dispatcher = resolveDispatcher(); + { + if (Context2._context !== void 0) { + var realContext = Context2._context; + if (realContext.Consumer === Context2) { + error("Calling useContext(Context.Consumer) is not supported, may cause bugs, and will be removed in a future major release. Did you mean to call useContext(Context) instead?"); + } else if (realContext.Provider === Context2) { + error("Calling useContext(Context.Provider) is not supported. Did you mean to call useContext(Context) instead?"); + } + } + } + return dispatcher.useContext(Context2); + } + function useState(initialState2) { + var dispatcher = resolveDispatcher(); + return dispatcher.useState(initialState2); + } + function useReducer(reducer, initialArg, init) { + var dispatcher = resolveDispatcher(); + return dispatcher.useReducer(reducer, initialArg, init); + } + function useRef(initialValue) { + var dispatcher = resolveDispatcher(); + return dispatcher.useRef(initialValue); + } + function useEffect(create3, deps) { + var dispatcher = resolveDispatcher(); + return dispatcher.useEffect(create3, deps); + } + function useInsertionEffect(create3, deps) { + var dispatcher = resolveDispatcher(); + return dispatcher.useInsertionEffect(create3, deps); + } + function useLayoutEffect(create3, deps) { + var dispatcher = resolveDispatcher(); + return dispatcher.useLayoutEffect(create3, deps); + } + function useCallback(callback, deps) { + var dispatcher = resolveDispatcher(); + return dispatcher.useCallback(callback, deps); + } + function useMemo(create3, deps) { + var dispatcher = resolveDispatcher(); + return dispatcher.useMemo(create3, deps); + } + function useImperativeHandle(ref, create3, deps) { + var dispatcher = resolveDispatcher(); + return dispatcher.useImperativeHandle(ref, create3, deps); + } + function useDebugValue(value, formatterFn) { + { + var dispatcher = resolveDispatcher(); + return dispatcher.useDebugValue(value, formatterFn); + } + } + function useTransition() { + var dispatcher = resolveDispatcher(); + return dispatcher.useTransition(); + } + function useDeferredValue(value) { + var dispatcher = resolveDispatcher(); + return dispatcher.useDeferredValue(value); + } + function useId2() { + var dispatcher = resolveDispatcher(); + return dispatcher.useId(); + } + function useSyncExternalStore(subscribe, getSnapshot2, getServerSnapshot) { + var dispatcher = resolveDispatcher(); + return dispatcher.useSyncExternalStore(subscribe, getSnapshot2, getServerSnapshot); + } + var disabledDepth = 0; + var prevLog; + var prevInfo; + var prevWarn; + var prevError; + var prevGroup; + var prevGroupCollapsed; + var prevGroupEnd; + function disabledLog() { + } + disabledLog.__reactDisabledLog = true; + function disableLogs() { + { + if (disabledDepth === 0) { + prevLog = console.log; + prevInfo = console.info; + prevWarn = console.warn; + prevError = console.error; + prevGroup = console.group; + prevGroupCollapsed = console.groupCollapsed; + prevGroupEnd = console.groupEnd; + var props = { + configurable: true, + enumerable: true, + value: disabledLog, + writable: true + }; + Object.defineProperties(console, { + info: props, + log: props, + warn: props, + error: props, + group: props, + groupCollapsed: props, + groupEnd: props + }); + } + disabledDepth++; + } + } + function reenableLogs() { + { + disabledDepth--; + if (disabledDepth === 0) { + var props = { + configurable: true, + enumerable: true, + writable: true + }; + Object.defineProperties(console, { + log: assign({}, props, { + value: prevLog + }), + info: assign({}, props, { + value: prevInfo + }), + warn: assign({}, props, { + value: prevWarn + }), + error: assign({}, props, { + value: prevError + }), + group: assign({}, props, { + value: prevGroup + }), + groupCollapsed: assign({}, props, { + value: prevGroupCollapsed + }), + groupEnd: assign({}, props, { + value: prevGroupEnd + }) + }); + } + if (disabledDepth < 0) { + error("disabledDepth fell below zero. This is a bug in React. Please file an issue."); + } + } + } + var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher; + var prefix; + function describeBuiltInComponentFrame(name, source, ownerFn) { + { + if (prefix === void 0) { + try { + throw Error(); + } catch (x2) { + var match2 = x2.stack.trim().match(/\n( *(at )?)/); + prefix = match2 && match2[1] || ""; + } + } + return "\n" + prefix + name; + } + } + var reentry = false; + var componentFrameCache; + { + var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; + componentFrameCache = new PossiblyWeakMap(); + } + function describeNativeComponentFrame(fn, construct2) { + if (!fn || reentry) { + return ""; + } + { + var frame2 = componentFrameCache.get(fn); + if (frame2 !== void 0) { + return frame2; + } + } + var control; + reentry = true; + var previousPrepareStackTrace = Error.prepareStackTrace; + Error.prepareStackTrace = void 0; + var previousDispatcher; + { + previousDispatcher = ReactCurrentDispatcher$1.current; + ReactCurrentDispatcher$1.current = null; + disableLogs(); + } + try { + if (construct2) { + var Fake = function() { + throw Error(); + }; + Object.defineProperty(Fake.prototype, "props", { + set: function() { + throw Error(); + } + }); + if (typeof Reflect === "object" && Reflect.construct) { + try { + Reflect.construct(Fake, []); + } catch (x2) { + control = x2; + } + Reflect.construct(fn, [], Fake); + } else { + try { + Fake.call(); + } catch (x2) { + control = x2; + } + fn.call(Fake.prototype); + } + } else { + try { + throw Error(); + } catch (x2) { + control = x2; + } + fn(); + } + } catch (sample) { + if (sample && control && typeof sample.stack === "string") { + var sampleLines = sample.stack.split("\n"); + var controlLines = control.stack.split("\n"); + var s2 = sampleLines.length - 1; + var c2 = controlLines.length - 1; + while (s2 >= 1 && c2 >= 0 && sampleLines[s2] !== controlLines[c2]) { + c2--; + } + for (; s2 >= 1 && c2 >= 0; s2--, c2--) { + if (sampleLines[s2] !== controlLines[c2]) { + if (s2 !== 1 || c2 !== 1) { + do { + s2--; + c2--; + if (c2 < 0 || sampleLines[s2] !== controlLines[c2]) { + var _frame = "\n" + sampleLines[s2].replace(" at new ", " at "); + if (fn.displayName && _frame.includes("")) { + _frame = _frame.replace("", fn.displayName); + } + { + if (typeof fn === "function") { + componentFrameCache.set(fn, _frame); + } + } + return _frame; + } + } while (s2 >= 1 && c2 >= 0); + } + break; + } + } + } + } finally { + reentry = false; + { + ReactCurrentDispatcher$1.current = previousDispatcher; + reenableLogs(); + } + Error.prepareStackTrace = previousPrepareStackTrace; + } + var name = fn ? fn.displayName || fn.name : ""; + var syntheticFrame = name ? describeBuiltInComponentFrame(name) : ""; + { + if (typeof fn === "function") { + componentFrameCache.set(fn, syntheticFrame); + } + } + return syntheticFrame; + } + function describeFunctionComponentFrame(fn, source, ownerFn) { + { + return describeNativeComponentFrame(fn, false); + } + } + function shouldConstruct(Component2) { + var prototype = Component2.prototype; + return !!(prototype && prototype.isReactComponent); + } + function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { + if (type == null) { + return ""; + } + if (typeof type === "function") { + { + return describeNativeComponentFrame(type, shouldConstruct(type)); + } + } + if (typeof type === "string") { + return describeBuiltInComponentFrame(type); + } + switch (type) { + case REACT_SUSPENSE_TYPE: + return describeBuiltInComponentFrame("Suspense"); + case REACT_SUSPENSE_LIST_TYPE: + return describeBuiltInComponentFrame("SuspenseList"); + } + if (typeof type === "object") { + switch (type.$$typeof) { + case REACT_FORWARD_REF_TYPE: + return describeFunctionComponentFrame(type.render); + case REACT_MEMO_TYPE: + return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); + case REACT_LAZY_TYPE: { + var lazyComponent = type; + var payload = lazyComponent._payload; + var init = lazyComponent._init; + try { + return describeUnknownElementTypeFrameInDEV(init(payload), source, ownerFn); + } catch (x2) { + } + } + } + } + return ""; + } + var loggedTypeFailures = {}; + var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame; + function setCurrentlyValidatingElement(element) { + { + if (element) { + var owner = element._owner; + var stack2 = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null); + ReactDebugCurrentFrame$1.setExtraStackFrame(stack2); + } else { + ReactDebugCurrentFrame$1.setExtraStackFrame(null); + } + } + } + function checkPropTypes(typeSpecs, values, location, componentName, element) { + { + var has2 = Function.call.bind(hasOwnProperty2); + for (var typeSpecName in typeSpecs) { + if (has2(typeSpecs, typeSpecName)) { + var error$1 = void 0; + try { + if (typeof typeSpecs[typeSpecName] !== "function") { + var err = Error((componentName || "React class") + ": " + location + " type `" + typeSpecName + "` is invalid; it must be a function, usually from the `prop-types` package, but received `" + typeof typeSpecs[typeSpecName] + "`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`."); + err.name = "Invariant Violation"; + throw err; + } + error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"); + } catch (ex) { + error$1 = ex; + } + if (error$1 && !(error$1 instanceof Error)) { + setCurrentlyValidatingElement(element); + error("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).", componentName || "React class", location, typeSpecName, typeof error$1); + setCurrentlyValidatingElement(null); + } + if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) { + loggedTypeFailures[error$1.message] = true; + setCurrentlyValidatingElement(element); + error("Failed %s type: %s", location, error$1.message); + setCurrentlyValidatingElement(null); + } + } + } + } + } + function setCurrentlyValidatingElement$1(element) { + { + if (element) { + var owner = element._owner; + var stack2 = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null); + setExtraStackFrame(stack2); + } else { + setExtraStackFrame(null); + } + } + } + var propTypesMisspellWarningShown; + { + propTypesMisspellWarningShown = false; + } + function getDeclarationErrorAddendum() { + if (ReactCurrentOwner.current) { + var name = getComponentNameFromType(ReactCurrentOwner.current.type); + if (name) { + return "\n\nCheck the render method of `" + name + "`."; + } + } + return ""; + } + function getSourceInfoErrorAddendum(source) { + if (source !== void 0) { + var fileName = source.fileName.replace(/^.*[\\\/]/, ""); + var lineNumber = source.lineNumber; + return "\n\nCheck your code at " + fileName + ":" + lineNumber + "."; + } + return ""; + } + function getSourceInfoErrorAddendumForProps(elementProps) { + if (elementProps !== null && elementProps !== void 0) { + return getSourceInfoErrorAddendum(elementProps.__source); + } + return ""; + } + var ownerHasKeyUseWarning = {}; + function getCurrentComponentErrorInfo(parentType) { + var info = getDeclarationErrorAddendum(); + if (!info) { + var parentName = typeof parentType === "string" ? parentType : parentType.displayName || parentType.name; + if (parentName) { + info = "\n\nCheck the top-level render call using <" + parentName + ">."; + } + } + return info; + } + function validateExplicitKey(element, parentType) { + if (!element._store || element._store.validated || element.key != null) { + return; + } + element._store.validated = true; + var currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType); + if (ownerHasKeyUseWarning[currentComponentErrorInfo]) { + return; + } + ownerHasKeyUseWarning[currentComponentErrorInfo] = true; + var childOwner = ""; + if (element && element._owner && element._owner !== ReactCurrentOwner.current) { + childOwner = " It was passed a child from " + getComponentNameFromType(element._owner.type) + "."; + } + { + setCurrentlyValidatingElement$1(element); + error('Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.', currentComponentErrorInfo, childOwner); + setCurrentlyValidatingElement$1(null); + } + } + function validateChildKeys(node, parentType) { + if (typeof node !== "object") { + return; + } + if (isArray3(node)) { + for (var i2 = 0; i2 < node.length; i2++) { + var child = node[i2]; + if (isValidElement(child)) { + validateExplicitKey(child, parentType); + } + } + } else if (isValidElement(node)) { + if (node._store) { + node._store.validated = true; + } + } else if (node) { + var iteratorFn = getIteratorFn(node); + if (typeof iteratorFn === "function") { + if (iteratorFn !== node.entries) { + var iterator = iteratorFn.call(node); + var step; + while (!(step = iterator.next()).done) { + if (isValidElement(step.value)) { + validateExplicitKey(step.value, parentType); + } + } + } + } + } + } + function validatePropTypes(element) { + { + var type = element.type; + if (type === null || type === void 0 || typeof type === "string") { + return; + } + var propTypes; + if (typeof type === "function") { + propTypes = type.propTypes; + } else if (typeof type === "object" && (type.$$typeof === REACT_FORWARD_REF_TYPE || // Note: Memo only checks outer props here. + // Inner props are checked in the reconciler. + type.$$typeof === REACT_MEMO_TYPE)) { + propTypes = type.propTypes; + } else { + return; + } + if (propTypes) { + var name = getComponentNameFromType(type); + checkPropTypes(propTypes, element.props, "prop", name, element); + } else if (type.PropTypes !== void 0 && !propTypesMisspellWarningShown) { + propTypesMisspellWarningShown = true; + var _name = getComponentNameFromType(type); + error("Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?", _name || "Unknown"); + } + if (typeof type.getDefaultProps === "function" && !type.getDefaultProps.isReactClassApproved) { + error("getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead."); + } + } + } + function validateFragmentProps(fragment) { + { + var keys3 = Object.keys(fragment.props); + for (var i2 = 0; i2 < keys3.length; i2++) { + var key = keys3[i2]; + if (key !== "children" && key !== "key") { + setCurrentlyValidatingElement$1(fragment); + error("Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.", key); + setCurrentlyValidatingElement$1(null); + break; + } + } + if (fragment.ref !== null) { + setCurrentlyValidatingElement$1(fragment); + error("Invalid attribute `ref` supplied to `React.Fragment`."); + setCurrentlyValidatingElement$1(null); + } + } + } + function createElementWithValidation(type, props, children) { + var validType = isValidElementType(type); + if (!validType) { + var info = ""; + if (type === void 0 || typeof type === "object" && type !== null && Object.keys(type).length === 0) { + info += " You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports."; + } + var sourceInfo = getSourceInfoErrorAddendumForProps(props); + if (sourceInfo) { + info += sourceInfo; + } else { + info += getDeclarationErrorAddendum(); + } + var typeString; + if (type === null) { + typeString = "null"; + } else if (isArray3(type)) { + typeString = "array"; + } else if (type !== void 0 && type.$$typeof === REACT_ELEMENT_TYPE) { + typeString = "<" + (getComponentNameFromType(type.type) || "Unknown") + " />"; + info = " Did you accidentally export a JSX literal instead of a component?"; + } else { + typeString = typeof type; + } + { + error("React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s", typeString, info); + } + } + var element = createElement2.apply(this, arguments); + if (element == null) { + return element; + } + if (validType) { + for (var i2 = 2; i2 < arguments.length; i2++) { + validateChildKeys(arguments[i2], type); + } + } + if (type === REACT_FRAGMENT_TYPE) { + validateFragmentProps(element); + } else { + validatePropTypes(element); + } + return element; + } + var didWarnAboutDeprecatedCreateFactory = false; + function createFactoryWithValidation(type) { + var validatedFactory = createElementWithValidation.bind(null, type); + validatedFactory.type = type; + { + if (!didWarnAboutDeprecatedCreateFactory) { + didWarnAboutDeprecatedCreateFactory = true; + warn("React.createFactory() is deprecated and will be removed in a future major release. Consider using JSX or use React.createElement() directly instead."); + } + Object.defineProperty(validatedFactory, "type", { + enumerable: false, + get: function() { + warn("Factory.type is deprecated. Access the class directly before passing it to createFactory."); + Object.defineProperty(this, "type", { + value: type + }); + return type; + } + }); + } + return validatedFactory; + } + function cloneElementWithValidation(element, props, children) { + var newElement = cloneElement.apply(this, arguments); + for (var i2 = 2; i2 < arguments.length; i2++) { + validateChildKeys(arguments[i2], newElement.type); + } + validatePropTypes(newElement); + return newElement; + } + function startTransition(scope, options) { + var prevTransition = ReactCurrentBatchConfig.transition; + ReactCurrentBatchConfig.transition = {}; + var currentTransition = ReactCurrentBatchConfig.transition; + { + ReactCurrentBatchConfig.transition._updatedFibers = /* @__PURE__ */ new Set(); + } + try { + scope(); + } finally { + ReactCurrentBatchConfig.transition = prevTransition; + { + if (prevTransition === null && currentTransition._updatedFibers) { + var updatedFibersCount = currentTransition._updatedFibers.size; + if (updatedFibersCount > 10) { + warn("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."); + } + currentTransition._updatedFibers.clear(); + } + } + } + } + var didWarnAboutMessageChannel = false; + var enqueueTaskImpl = null; + function enqueueTask(task) { + if (enqueueTaskImpl === null) { + try { + var requireString = ("require" + Math.random()).slice(0, 7); + var nodeRequire = module && module[requireString]; + enqueueTaskImpl = nodeRequire.call(module, "timers").setImmediate; + } catch (_err) { + enqueueTaskImpl = function(callback) { + { + if (didWarnAboutMessageChannel === false) { + didWarnAboutMessageChannel = true; + if (typeof MessageChannel === "undefined") { + error("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."); + } + } + } + var channel2 = new MessageChannel(); + channel2.port1.onmessage = callback; + channel2.port2.postMessage(void 0); + }; + } + } + return enqueueTaskImpl(task); + } + var actScopeDepth = 0; + var didWarnNoAwaitAct = false; + function act(callback) { + { + var prevActScopeDepth = actScopeDepth; + actScopeDepth++; + if (ReactCurrentActQueue.current === null) { + ReactCurrentActQueue.current = []; + } + var prevIsBatchingLegacy = ReactCurrentActQueue.isBatchingLegacy; + var result; + try { + ReactCurrentActQueue.isBatchingLegacy = true; + result = callback(); + if (!prevIsBatchingLegacy && ReactCurrentActQueue.didScheduleLegacyUpdate) { + var queue = ReactCurrentActQueue.current; + if (queue !== null) { + ReactCurrentActQueue.didScheduleLegacyUpdate = false; + flushActQueue(queue); + } + } + } catch (error2) { + popActScope(prevActScopeDepth); + throw error2; + } finally { + ReactCurrentActQueue.isBatchingLegacy = prevIsBatchingLegacy; + } + if (result !== null && typeof result === "object" && typeof result.then === "function") { + var thenableResult = result; + var wasAwaited = false; + var thenable = { + then: function(resolve, reject) { + wasAwaited = true; + thenableResult.then(function(returnValue2) { + popActScope(prevActScopeDepth); + if (actScopeDepth === 0) { + recursivelyFlushAsyncActWork(returnValue2, resolve, reject); + } else { + resolve(returnValue2); + } + }, function(error2) { + popActScope(prevActScopeDepth); + reject(error2); + }); + } + }; + { + if (!didWarnNoAwaitAct && typeof Promise !== "undefined") { + Promise.resolve().then(function() { + }).then(function() { + if (!wasAwaited) { + didWarnNoAwaitAct = true; + error("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 () => ...);"); + } + }); + } + } + return thenable; + } else { + var returnValue = result; + popActScope(prevActScopeDepth); + if (actScopeDepth === 0) { + var _queue = ReactCurrentActQueue.current; + if (_queue !== null) { + flushActQueue(_queue); + ReactCurrentActQueue.current = null; + } + var _thenable = { + then: function(resolve, reject) { + if (ReactCurrentActQueue.current === null) { + ReactCurrentActQueue.current = []; + recursivelyFlushAsyncActWork(returnValue, resolve, reject); + } else { + resolve(returnValue); + } + } + }; + return _thenable; + } else { + var _thenable2 = { + then: function(resolve, reject) { + resolve(returnValue); + } + }; + return _thenable2; + } + } + } + } + function popActScope(prevActScopeDepth) { + { + if (prevActScopeDepth !== actScopeDepth - 1) { + error("You seem to have overlapping act() calls, this is not supported. Be sure to await previous act() calls before making a new one. "); + } + actScopeDepth = prevActScopeDepth; + } + } + function recursivelyFlushAsyncActWork(returnValue, resolve, reject) { + { + var queue = ReactCurrentActQueue.current; + if (queue !== null) { + try { + flushActQueue(queue); + enqueueTask(function() { + if (queue.length === 0) { + ReactCurrentActQueue.current = null; + resolve(returnValue); + } else { + recursivelyFlushAsyncActWork(returnValue, resolve, reject); + } + }); + } catch (error2) { + reject(error2); + } + } else { + resolve(returnValue); + } + } + } + var isFlushing = false; + function flushActQueue(queue) { + { + if (!isFlushing) { + isFlushing = true; + var i2 = 0; + try { + for (; i2 < queue.length; i2++) { + var callback = queue[i2]; + do { + callback = callback(true); + } while (callback !== null); + } + queue.length = 0; + } catch (error2) { + queue = queue.slice(i2 + 1); + throw error2; + } finally { + isFlushing = false; + } + } + } + } + var createElement$1 = createElementWithValidation; + var cloneElement$1 = cloneElementWithValidation; + var createFactory = createFactoryWithValidation; + var Children = { + map: mapChildren, + forEach: forEachChildren, + count: countChildren, + toArray, + only: onlyChild + }; + exports.Children = Children; + exports.Component = Component; + exports.Fragment = REACT_FRAGMENT_TYPE; + exports.Profiler = REACT_PROFILER_TYPE; + exports.PureComponent = PureComponent; + exports.StrictMode = REACT_STRICT_MODE_TYPE; + exports.Suspense = REACT_SUSPENSE_TYPE; + exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = ReactSharedInternals; + exports.act = act; + exports.cloneElement = cloneElement$1; + exports.createContext = createContext; + exports.createElement = createElement$1; + exports.createFactory = createFactory; + exports.createRef = createRef; + exports.forwardRef = forwardRef; + exports.isValidElement = isValidElement; + exports.lazy = lazy; + exports.memo = memo2; + exports.startTransition = startTransition; + exports.unstable_act = act; + exports.useCallback = useCallback; + exports.useContext = useContext; + exports.useDebugValue = useDebugValue; + exports.useDeferredValue = useDeferredValue; + exports.useEffect = useEffect; + exports.useId = useId2; + exports.useImperativeHandle = useImperativeHandle; + exports.useInsertionEffect = useInsertionEffect; + exports.useLayoutEffect = useLayoutEffect; + exports.useMemo = useMemo; + exports.useReducer = useReducer; + exports.useRef = useRef; + exports.useState = useState; + exports.useSyncExternalStore = useSyncExternalStore; + exports.useTransition = useTransition; + exports.version = ReactVersion; + if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop === "function") { + __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error()); + } + })(); + } +})(react_development, react_development.exports); +var react_developmentExports = react_development.exports; +{ + react$1.exports = react_developmentExports; +} +var reactExports = react$1.exports; +const React = /* @__PURE__ */ getDefaultExportFromCjs(reactExports); +const React$1 = /* @__PURE__ */ _mergeNamespaces({ + __proto__: null, + default: React +}, [reactExports]); +/** + * @license React + * react-jsx-dev-runtime.development.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +{ + (function() { + var React2 = reactExports; + var REACT_ELEMENT_TYPE = Symbol.for("react.element"); + var REACT_PORTAL_TYPE = Symbol.for("react.portal"); + var REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"); + var REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"); + var REACT_PROFILER_TYPE = Symbol.for("react.profiler"); + var REACT_PROVIDER_TYPE = Symbol.for("react.provider"); + var REACT_CONTEXT_TYPE = Symbol.for("react.context"); + var REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"); + var REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"); + var REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"); + var REACT_MEMO_TYPE = Symbol.for("react.memo"); + var REACT_LAZY_TYPE = Symbol.for("react.lazy"); + var REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"); + var MAYBE_ITERATOR_SYMBOL = Symbol.iterator; + var FAUX_ITERATOR_SYMBOL = "@@iterator"; + function getIteratorFn(maybeIterable) { + if (maybeIterable === null || typeof maybeIterable !== "object") { + return null; + } + var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]; + if (typeof maybeIterator === "function") { + return maybeIterator; + } + return null; + } + var ReactSharedInternals = React2.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; + function error(format2) { + { + { + for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + args[_key2 - 1] = arguments[_key2]; + } + printWarning("error", format2, args); + } + } + } + function printWarning(level, format2, args) { + { + var ReactDebugCurrentFrame2 = ReactSharedInternals.ReactDebugCurrentFrame; + var stack2 = ReactDebugCurrentFrame2.getStackAddendum(); + if (stack2 !== "") { + format2 += "%s"; + args = args.concat([stack2]); + } + var argsWithFormat = args.map(function(item) { + return String(item); + }); + argsWithFormat.unshift("Warning: " + format2); + Function.prototype.apply.call(console[level], console, argsWithFormat); + } + } + var enableScopeAPI = false; + var enableCacheElement = false; + var enableTransitionTracing = false; + var enableLegacyHidden = false; + var enableDebugTracing = false; + var REACT_MODULE_REFERENCE; + { + REACT_MODULE_REFERENCE = Symbol.for("react.module.reference"); + } + function isValidElementType(type) { + if (typeof type === "string" || typeof type === "function") { + return true; + } + if (type === REACT_FRAGMENT_TYPE || type === REACT_PROFILER_TYPE || enableDebugTracing || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || enableLegacyHidden || type === REACT_OFFSCREEN_TYPE || enableScopeAPI || enableCacheElement || enableTransitionTracing) { + return true; + } + if (typeof type === "object" && type !== null) { + if (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || // This needs to include all possible module reference object + // types supported by any Flight configuration anywhere since + // we don't know which Flight build this will end up being used + // with. + type.$$typeof === REACT_MODULE_REFERENCE || type.getModuleId !== void 0) { + return true; + } + } + return false; + } + function getWrappedName(outerType, innerType, wrapperName) { + var displayName = outerType.displayName; + if (displayName) { + return displayName; + } + var functionName2 = innerType.displayName || innerType.name || ""; + return functionName2 !== "" ? wrapperName + "(" + functionName2 + ")" : wrapperName; + } + function getContextName(type) { + return type.displayName || "Context"; + } + function getComponentNameFromType(type) { + if (type == null) { + return null; + } + { + if (typeof type.tag === "number") { + error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."); + } + } + if (typeof type === "function") { + return type.displayName || type.name || null; + } + if (typeof type === "string") { + return type; + } + switch (type) { + case REACT_FRAGMENT_TYPE: + return "Fragment"; + case REACT_PORTAL_TYPE: + return "Portal"; + case REACT_PROFILER_TYPE: + return "Profiler"; + case REACT_STRICT_MODE_TYPE: + return "StrictMode"; + case REACT_SUSPENSE_TYPE: + return "Suspense"; + case REACT_SUSPENSE_LIST_TYPE: + return "SuspenseList"; + } + if (typeof type === "object") { + switch (type.$$typeof) { + case REACT_CONTEXT_TYPE: + var context = type; + return getContextName(context) + ".Consumer"; + case REACT_PROVIDER_TYPE: + var provider = type; + return getContextName(provider._context) + ".Provider"; + case REACT_FORWARD_REF_TYPE: + return getWrappedName(type, type.render, "ForwardRef"); + case REACT_MEMO_TYPE: + var outerName = type.displayName || null; + if (outerName !== null) { + return outerName; + } + return getComponentNameFromType(type.type) || "Memo"; + case REACT_LAZY_TYPE: { + var lazyComponent = type; + var payload = lazyComponent._payload; + var init = lazyComponent._init; + try { + return getComponentNameFromType(init(payload)); + } catch (x2) { + return null; + } + } + } + } + return null; + } + var assign = Object.assign; + var disabledDepth = 0; + var prevLog; + var prevInfo; + var prevWarn; + var prevError; + var prevGroup; + var prevGroupCollapsed; + var prevGroupEnd; + function disabledLog() { + } + disabledLog.__reactDisabledLog = true; + function disableLogs() { + { + if (disabledDepth === 0) { + prevLog = console.log; + prevInfo = console.info; + prevWarn = console.warn; + prevError = console.error; + prevGroup = console.group; + prevGroupCollapsed = console.groupCollapsed; + prevGroupEnd = console.groupEnd; + var props = { + configurable: true, + enumerable: true, + value: disabledLog, + writable: true + }; + Object.defineProperties(console, { + info: props, + log: props, + warn: props, + error: props, + group: props, + groupCollapsed: props, + groupEnd: props + }); + } + disabledDepth++; + } + } + function reenableLogs() { + { + disabledDepth--; + if (disabledDepth === 0) { + var props = { + configurable: true, + enumerable: true, + writable: true + }; + Object.defineProperties(console, { + log: assign({}, props, { + value: prevLog + }), + info: assign({}, props, { + value: prevInfo + }), + warn: assign({}, props, { + value: prevWarn + }), + error: assign({}, props, { + value: prevError + }), + group: assign({}, props, { + value: prevGroup + }), + groupCollapsed: assign({}, props, { + value: prevGroupCollapsed + }), + groupEnd: assign({}, props, { + value: prevGroupEnd + }) + }); + } + if (disabledDepth < 0) { + error("disabledDepth fell below zero. This is a bug in React. Please file an issue."); + } + } + } + var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; + var prefix; + function describeBuiltInComponentFrame(name, source, ownerFn) { + { + if (prefix === void 0) { + try { + throw Error(); + } catch (x2) { + var match2 = x2.stack.trim().match(/\n( *(at )?)/); + prefix = match2 && match2[1] || ""; + } + } + return "\n" + prefix + name; + } + } + var reentry = false; + var componentFrameCache; + { + var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; + componentFrameCache = new PossiblyWeakMap(); + } + function describeNativeComponentFrame(fn, construct2) { + if (!fn || reentry) { + return ""; + } + { + var frame2 = componentFrameCache.get(fn); + if (frame2 !== void 0) { + return frame2; + } + } + var control; + reentry = true; + var previousPrepareStackTrace = Error.prepareStackTrace; + Error.prepareStackTrace = void 0; + var previousDispatcher; + { + previousDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = null; + disableLogs(); + } + try { + if (construct2) { + var Fake = function() { + throw Error(); + }; + Object.defineProperty(Fake.prototype, "props", { + set: function() { + throw Error(); + } + }); + if (typeof Reflect === "object" && Reflect.construct) { + try { + Reflect.construct(Fake, []); + } catch (x2) { + control = x2; + } + Reflect.construct(fn, [], Fake); + } else { + try { + Fake.call(); + } catch (x2) { + control = x2; + } + fn.call(Fake.prototype); + } + } else { + try { + throw Error(); + } catch (x2) { + control = x2; + } + fn(); + } + } catch (sample) { + if (sample && control && typeof sample.stack === "string") { + var sampleLines = sample.stack.split("\n"); + var controlLines = control.stack.split("\n"); + var s2 = sampleLines.length - 1; + var c2 = controlLines.length - 1; + while (s2 >= 1 && c2 >= 0 && sampleLines[s2] !== controlLines[c2]) { + c2--; + } + for (; s2 >= 1 && c2 >= 0; s2--, c2--) { + if (sampleLines[s2] !== controlLines[c2]) { + if (s2 !== 1 || c2 !== 1) { + do { + s2--; + c2--; + if (c2 < 0 || sampleLines[s2] !== controlLines[c2]) { + var _frame = "\n" + sampleLines[s2].replace(" at new ", " at "); + if (fn.displayName && _frame.includes("")) { + _frame = _frame.replace("", fn.displayName); + } + { + if (typeof fn === "function") { + componentFrameCache.set(fn, _frame); + } + } + return _frame; + } + } while (s2 >= 1 && c2 >= 0); + } + break; + } + } + } + } finally { + reentry = false; + { + ReactCurrentDispatcher.current = previousDispatcher; + reenableLogs(); + } + Error.prepareStackTrace = previousPrepareStackTrace; + } + var name = fn ? fn.displayName || fn.name : ""; + var syntheticFrame = name ? describeBuiltInComponentFrame(name) : ""; + { + if (typeof fn === "function") { + componentFrameCache.set(fn, syntheticFrame); + } + } + return syntheticFrame; + } + function describeFunctionComponentFrame(fn, source, ownerFn) { + { + return describeNativeComponentFrame(fn, false); + } + } + function shouldConstruct(Component) { + var prototype = Component.prototype; + return !!(prototype && prototype.isReactComponent); + } + function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { + if (type == null) { + return ""; + } + if (typeof type === "function") { + { + return describeNativeComponentFrame(type, shouldConstruct(type)); + } + } + if (typeof type === "string") { + return describeBuiltInComponentFrame(type); + } + switch (type) { + case REACT_SUSPENSE_TYPE: + return describeBuiltInComponentFrame("Suspense"); + case REACT_SUSPENSE_LIST_TYPE: + return describeBuiltInComponentFrame("SuspenseList"); + } + if (typeof type === "object") { + switch (type.$$typeof) { + case REACT_FORWARD_REF_TYPE: + return describeFunctionComponentFrame(type.render); + case REACT_MEMO_TYPE: + return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); + case REACT_LAZY_TYPE: { + var lazyComponent = type; + var payload = lazyComponent._payload; + var init = lazyComponent._init; + try { + return describeUnknownElementTypeFrameInDEV(init(payload), source, ownerFn); + } catch (x2) { + } + } + } + } + return ""; + } + var hasOwnProperty2 = Object.prototype.hasOwnProperty; + var loggedTypeFailures = {}; + var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + function setCurrentlyValidatingElement(element) { + { + if (element) { + var owner = element._owner; + var stack2 = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null); + ReactDebugCurrentFrame.setExtraStackFrame(stack2); + } else { + ReactDebugCurrentFrame.setExtraStackFrame(null); + } + } + } + function checkPropTypes(typeSpecs, values, location, componentName, element) { + { + var has2 = Function.call.bind(hasOwnProperty2); + for (var typeSpecName in typeSpecs) { + if (has2(typeSpecs, typeSpecName)) { + var error$1 = void 0; + try { + if (typeof typeSpecs[typeSpecName] !== "function") { + var err = Error((componentName || "React class") + ": " + location + " type `" + typeSpecName + "` is invalid; it must be a function, usually from the `prop-types` package, but received `" + typeof typeSpecs[typeSpecName] + "`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`."); + err.name = "Invariant Violation"; + throw err; + } + error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"); + } catch (ex) { + error$1 = ex; + } + if (error$1 && !(error$1 instanceof Error)) { + setCurrentlyValidatingElement(element); + error("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).", componentName || "React class", location, typeSpecName, typeof error$1); + setCurrentlyValidatingElement(null); + } + if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) { + loggedTypeFailures[error$1.message] = true; + setCurrentlyValidatingElement(element); + error("Failed %s type: %s", location, error$1.message); + setCurrentlyValidatingElement(null); + } + } + } + } + } + var isArrayImpl = Array.isArray; + function isArray3(a2) { + return isArrayImpl(a2); + } + function typeName(value) { + { + var hasToStringTag = typeof Symbol === "function" && Symbol.toStringTag; + var type = hasToStringTag && value[Symbol.toStringTag] || value.constructor.name || "Object"; + return type; + } + } + function willCoercionThrow(value) { + { + try { + testStringCoercion(value); + return false; + } catch (e2) { + return true; + } + } + } + function testStringCoercion(value) { + return "" + value; + } + function checkKeyStringCoercion(value) { + { + if (willCoercionThrow(value)) { + error("The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.", typeName(value)); + return testStringCoercion(value); + } + } + } + var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; + var RESERVED_PROPS = { + key: true, + ref: true, + __self: true, + __source: true + }; + var specialPropKeyWarningShown; + var specialPropRefWarningShown; + var didWarnAboutStringRefs; + { + didWarnAboutStringRefs = {}; + } + function hasValidRef(config) { + { + if (hasOwnProperty2.call(config, "ref")) { + var getter = Object.getOwnPropertyDescriptor(config, "ref").get; + if (getter && getter.isReactWarning) { + return false; + } + } + } + return config.ref !== void 0; + } + function hasValidKey(config) { + { + if (hasOwnProperty2.call(config, "key")) { + var getter = Object.getOwnPropertyDescriptor(config, "key").get; + if (getter && getter.isReactWarning) { + return false; + } + } + } + return config.key !== void 0; + } + function warnIfStringRefCannotBeAutoConverted(config, self2) { + { + if (typeof config.ref === "string" && ReactCurrentOwner.current && self2 && ReactCurrentOwner.current.stateNode !== self2) { + var componentName = getComponentNameFromType(ReactCurrentOwner.current.type); + if (!didWarnAboutStringRefs[componentName]) { + error('Component "%s" contains the string ref "%s". Support for string refs will be removed in a future major release. This case cannot be automatically converted to an arrow function. We ask you to manually fix this case by using useRef() or createRef() instead. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref', getComponentNameFromType(ReactCurrentOwner.current.type), config.ref); + didWarnAboutStringRefs[componentName] = true; + } + } + } + } + function defineKeyPropWarningGetter(props, displayName) { + { + var warnAboutAccessingKey = function() { + if (!specialPropKeyWarningShown) { + specialPropKeyWarningShown = true; + error("%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://reactjs.org/link/special-props)", displayName); + } + }; + warnAboutAccessingKey.isReactWarning = true; + Object.defineProperty(props, "key", { + get: warnAboutAccessingKey, + configurable: true + }); + } + } + function defineRefPropWarningGetter(props, displayName) { + { + var warnAboutAccessingRef = function() { + if (!specialPropRefWarningShown) { + specialPropRefWarningShown = true; + error("%s: `ref` 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://reactjs.org/link/special-props)", displayName); + } + }; + warnAboutAccessingRef.isReactWarning = true; + Object.defineProperty(props, "ref", { + get: warnAboutAccessingRef, + configurable: true + }); + } + } + var ReactElement = function(type, key, ref, self2, source, owner, props) { + var element = { + // This tag allows us to uniquely identify this as a React Element + $$typeof: REACT_ELEMENT_TYPE, + // Built-in properties that belong on the element + type, + key, + ref, + props, + // Record the component responsible for creating this element. + _owner: owner + }; + { + element._store = {}; + Object.defineProperty(element._store, "validated", { + configurable: false, + enumerable: false, + writable: true, + value: false + }); + Object.defineProperty(element, "_self", { + configurable: false, + enumerable: false, + writable: false, + value: self2 + }); + Object.defineProperty(element, "_source", { + configurable: false, + enumerable: false, + writable: false, + value: source + }); + if (Object.freeze) { + Object.freeze(element.props); + Object.freeze(element); + } + } + return element; + }; + function jsxDEV(type, config, maybeKey, source, self2) { + { + var propName; + var props = {}; + var key = null; + var ref = null; + if (maybeKey !== void 0) { + { + checkKeyStringCoercion(maybeKey); + } + key = "" + maybeKey; + } + if (hasValidKey(config)) { + { + checkKeyStringCoercion(config.key); + } + key = "" + config.key; + } + if (hasValidRef(config)) { + ref = config.ref; + warnIfStringRefCannotBeAutoConverted(config, self2); + } + for (propName in config) { + if (hasOwnProperty2.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) { + props[propName] = config[propName]; + } + } + if (type && type.defaultProps) { + var defaultProps = type.defaultProps; + for (propName in defaultProps) { + if (props[propName] === void 0) { + props[propName] = defaultProps[propName]; + } + } + } + if (key || ref) { + var displayName = typeof type === "function" ? type.displayName || type.name || "Unknown" : type; + if (key) { + defineKeyPropWarningGetter(props, displayName); + } + if (ref) { + defineRefPropWarningGetter(props, displayName); + } + } + return ReactElement(type, key, ref, self2, source, ReactCurrentOwner.current, props); + } + } + var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; + var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame; + function setCurrentlyValidatingElement$1(element) { + { + if (element) { + var owner = element._owner; + var stack2 = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null); + ReactDebugCurrentFrame$1.setExtraStackFrame(stack2); + } else { + ReactDebugCurrentFrame$1.setExtraStackFrame(null); + } + } + } + var propTypesMisspellWarningShown; + { + propTypesMisspellWarningShown = false; + } + function isValidElement(object2) { + { + return typeof object2 === "object" && object2 !== null && object2.$$typeof === REACT_ELEMENT_TYPE; + } + } + function getDeclarationErrorAddendum() { + { + if (ReactCurrentOwner$1.current) { + var name = getComponentNameFromType(ReactCurrentOwner$1.current.type); + if (name) { + return "\n\nCheck the render method of `" + name + "`."; + } + } + return ""; + } + } + function getSourceInfoErrorAddendum(source) { + { + if (source !== void 0) { + var fileName = source.fileName.replace(/^.*[\\\/]/, ""); + var lineNumber = source.lineNumber; + return "\n\nCheck your code at " + fileName + ":" + lineNumber + "."; + } + return ""; + } + } + var ownerHasKeyUseWarning = {}; + function getCurrentComponentErrorInfo(parentType) { + { + var info = getDeclarationErrorAddendum(); + if (!info) { + var parentName = typeof parentType === "string" ? parentType : parentType.displayName || parentType.name; + if (parentName) { + info = "\n\nCheck the top-level render call using <" + parentName + ">."; + } + } + return info; + } + } + function validateExplicitKey(element, parentType) { + { + if (!element._store || element._store.validated || element.key != null) { + return; + } + element._store.validated = true; + var currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType); + if (ownerHasKeyUseWarning[currentComponentErrorInfo]) { + return; + } + ownerHasKeyUseWarning[currentComponentErrorInfo] = true; + var childOwner = ""; + if (element && element._owner && element._owner !== ReactCurrentOwner$1.current) { + childOwner = " It was passed a child from " + getComponentNameFromType(element._owner.type) + "."; + } + setCurrentlyValidatingElement$1(element); + error('Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.', currentComponentErrorInfo, childOwner); + setCurrentlyValidatingElement$1(null); + } + } + function validateChildKeys(node, parentType) { + { + if (typeof node !== "object") { + return; + } + if (isArray3(node)) { + for (var i2 = 0; i2 < node.length; i2++) { + var child = node[i2]; + if (isValidElement(child)) { + validateExplicitKey(child, parentType); + } + } + } else if (isValidElement(node)) { + if (node._store) { + node._store.validated = true; + } + } else if (node) { + var iteratorFn = getIteratorFn(node); + if (typeof iteratorFn === "function") { + if (iteratorFn !== node.entries) { + var iterator = iteratorFn.call(node); + var step; + while (!(step = iterator.next()).done) { + if (isValidElement(step.value)) { + validateExplicitKey(step.value, parentType); + } + } + } + } + } + } + } + function validatePropTypes(element) { + { + var type = element.type; + if (type === null || type === void 0 || typeof type === "string") { + return; + } + var propTypes; + if (typeof type === "function") { + propTypes = type.propTypes; + } else if (typeof type === "object" && (type.$$typeof === REACT_FORWARD_REF_TYPE || // Note: Memo only checks outer props here. + // Inner props are checked in the reconciler. + type.$$typeof === REACT_MEMO_TYPE)) { + propTypes = type.propTypes; + } else { + return; + } + if (propTypes) { + var name = getComponentNameFromType(type); + checkPropTypes(propTypes, element.props, "prop", name, element); + } else if (type.PropTypes !== void 0 && !propTypesMisspellWarningShown) { + propTypesMisspellWarningShown = true; + var _name = getComponentNameFromType(type); + error("Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?", _name || "Unknown"); + } + if (typeof type.getDefaultProps === "function" && !type.getDefaultProps.isReactClassApproved) { + error("getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead."); + } + } + } + function validateFragmentProps(fragment) { + { + var keys3 = Object.keys(fragment.props); + for (var i2 = 0; i2 < keys3.length; i2++) { + var key = keys3[i2]; + if (key !== "children" && key !== "key") { + setCurrentlyValidatingElement$1(fragment); + error("Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.", key); + setCurrentlyValidatingElement$1(null); + break; + } + } + if (fragment.ref !== null) { + setCurrentlyValidatingElement$1(fragment); + error("Invalid attribute `ref` supplied to `React.Fragment`."); + setCurrentlyValidatingElement$1(null); + } + } + } + var didWarnAboutKeySpread = {}; + function jsxWithValidation(type, props, key, isStaticChildren, source, self2) { + { + var validType = isValidElementType(type); + if (!validType) { + var info = ""; + if (type === void 0 || typeof type === "object" && type !== null && Object.keys(type).length === 0) { + info += " You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports."; + } + var sourceInfo = getSourceInfoErrorAddendum(source); + if (sourceInfo) { + info += sourceInfo; + } else { + info += getDeclarationErrorAddendum(); + } + var typeString; + if (type === null) { + typeString = "null"; + } else if (isArray3(type)) { + typeString = "array"; + } else if (type !== void 0 && type.$$typeof === REACT_ELEMENT_TYPE) { + typeString = "<" + (getComponentNameFromType(type.type) || "Unknown") + " />"; + info = " Did you accidentally export a JSX literal instead of a component?"; + } else { + typeString = typeof type; + } + error("React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s", typeString, info); + } + var element = jsxDEV(type, props, key, source, self2); + if (element == null) { + return element; + } + if (validType) { + var children = props.children; + if (children !== void 0) { + if (isStaticChildren) { + if (isArray3(children)) { + for (var i2 = 0; i2 < children.length; i2++) { + validateChildKeys(children[i2], type); + } + if (Object.freeze) { + Object.freeze(children); + } + } else { + error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."); + } + } else { + validateChildKeys(children, type); + } + } + } + { + if (hasOwnProperty2.call(props, "key")) { + var componentName = getComponentNameFromType(type); + var keys3 = Object.keys(props).filter(function(k) { + return k !== "key"; + }); + var beforeExample = keys3.length > 0 ? "{key: someKey, " + keys3.join(": ..., ") + ": ...}" : "{key: someKey}"; + if (!didWarnAboutKeySpread[componentName + beforeExample]) { + var afterExample = keys3.length > 0 ? "{" + keys3.join(": ..., ") + ": ...}" : "{}"; + error('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} />', beforeExample, componentName, afterExample, componentName); + didWarnAboutKeySpread[componentName + beforeExample] = true; + } + } + } + if (type === REACT_FRAGMENT_TYPE) { + validateFragmentProps(element); + } else { + validatePropTypes(element); + } + return element; + } + } + var jsxDEV$1 = jsxWithValidation; + reactJsxDevRuntime_development.Fragment = REACT_FRAGMENT_TYPE; + reactJsxDevRuntime_development.jsxDEV = jsxDEV$1; + })(); +} +{ + jsxDevRuntime.exports = reactJsxDevRuntime_development; +} +var jsxDevRuntimeExports = jsxDevRuntime.exports; +const TLDRAW_LIBRARY_VERSION_KEY = "__TLDRAW_LIBRARY_VERSIONS__"; +function getLibraryVersions() { + if (globalThis[TLDRAW_LIBRARY_VERSION_KEY]) { + return globalThis[TLDRAW_LIBRARY_VERSION_KEY]; + } + const info = { + versions: [], + didWarn: false, + scheduledNotice: null + }; + Object.defineProperty(globalThis, TLDRAW_LIBRARY_VERSION_KEY, { + value: info, + writable: false, + configurable: false, + enumerable: false + }); + return info; +} +function registerTldrawLibraryVersion(name, version2, modules) { + if (!name || !version2 || !modules) { + { + throw new Error("Missing name/version/module system in built version of tldraw library"); + } + } + const info = getLibraryVersions(); + info.versions.push({ name, version: version2, modules }); + if (!info.scheduledNotice) { + try { + info.scheduledNotice = setTimeout(() => { + info.scheduledNotice = null; + checkLibraryVersions(info); + }, 100); + } catch { + checkLibraryVersions(info); + } + } +} +function checkLibraryVersions(info) { + if (!info.versions.length) return; + if (info.didWarn) return; + const sorted = info.versions.sort((a2, b2) => compareVersions(a2.version, b2.version)); + const latestVersion = sorted[sorted.length - 1].version; + const matchingVersions = /* @__PURE__ */ new Set(); + const nonMatchingVersions = /* @__PURE__ */ new Map(); + for (const lib of sorted) { + if (nonMatchingVersions.has(lib.name)) { + matchingVersions.delete(lib.name); + entry(nonMatchingVersions, lib.name, /* @__PURE__ */ new Set()).add(lib.version); + continue; + } + if (lib.version === latestVersion) { + matchingVersions.add(lib.name); + } else { + matchingVersions.delete(lib.name); + entry(nonMatchingVersions, lib.name, /* @__PURE__ */ new Set()).add(lib.version); + } + } + if (nonMatchingVersions.size > 0) { + const message = [ + `${format("[tldraw]", ["bold", "bgRed", "textWhite"])} ${format("You have multiple versions of tldraw libraries installed. This can lead to bugs and unexpected behavior.", ["textRed", "bold"])}`, + "", + `The latest version you have installed is ${format(`v${latestVersion}`, ["bold", "textBlue"])}. The following libraries are on the latest version:`, + ...Array.from(matchingVersions, (name) => ` • ✅ ${format(name, ["bold"])}`), + "", + `The following libraries are not on the latest version, or have multiple versions installed:`, + ...Array.from(nonMatchingVersions, ([name, versions2]) => { + const sortedVersions = Array.from(versions2).sort(compareVersions).map((v2) => format(`v${v2}`, v2 === latestVersion ? ["textGreen"] : ["textRed"])); + return ` • ❌ ${format(name, ["bold"])} (${sortedVersions.join(", ")})`; + }) + ]; + console.log(message.join("\n")); + info.didWarn = true; + return; + } + const potentialDuplicates = /* @__PURE__ */ new Map(); + for (const lib of sorted) { + entry(potentialDuplicates, lib.name, { version: lib.version, modules: [] }).modules.push( + lib.modules + ); + } + const duplicates = /* @__PURE__ */ new Map(); + for (const [name, lib] of potentialDuplicates) { + if (lib.modules.length > 1) duplicates.set(name, lib); + } + if (duplicates.size > 0) { + const message = [ + `${format("[tldraw]", ["bold", "bgRed", "textWhite"])} ${format("You have multiple instances of some tldraw libraries active. This can lead to bugs and unexpected behavior. ", ["textRed", "bold"])}`, + "", + "This usually means that your bundler is misconfigured, and is importing the same library multiple times - usually once as an ES Module, and once as a CommonJS module.", + "", + "The following libraries have been imported multiple times:", + ...Array.from(duplicates, ([name, lib]) => { + const modules = lib.modules.map((m2, i2) => m2 === "esm" ? ` ${i2 + 1}. ES Modules` : ` ${i2 + 1}. CommonJS`).join("\n"); + return ` • ❌ ${format(name, ["bold"])} v${lib.version}: +${modules}`; + }), + "", + "You should configure your bundler to only import one version of each library." + ]; + console.log(message.join("\n")); + info.didWarn = true; + return; + } +} +function compareVersions(a2, b2) { + const aMatch = a2.match(/^(\d+)\.(\d+)\.(\d+)(?:-(\w+))?$/); + const bMatch = b2.match(/^(\d+)\.(\d+)\.(\d+)(?:-(\w+))?$/); + if (!aMatch || !bMatch) return a2.localeCompare(b2); + if (aMatch[1] !== bMatch[1]) return Number(aMatch[1]) - Number(bMatch[1]); + if (aMatch[2] !== bMatch[2]) return Number(aMatch[2]) - Number(bMatch[2]); + if (aMatch[3] !== bMatch[3]) return Number(aMatch[3]) - Number(bMatch[3]); + if (aMatch[4] && bMatch[4]) return aMatch[4].localeCompare(bMatch[4]); + if (aMatch[4]) return 1; + if (bMatch[4]) return -1; + return 0; +} +const formats = { + bold: "1", + textBlue: "94", + textRed: "31", + textGreen: "32", + bgRed: "41", + textWhite: "97" +}; +function format(value, formatters = []) { + return `\x1B[${formatters.map((f2) => formats[f2]).join(";")}m${value}\x1B[m`; +} +function entry(map, key, defaultValue) { + if (map.has(key)) { + return map.get(key); + } + map.set(key, defaultValue); + return defaultValue; +} +var FUNC_ERROR_TEXT = "Expected a function"; +var NAN = 0 / 0; +var symbolTag = "[object Symbol]"; +var reTrim = /^\s+|\s+$/g; +var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; +var reIsBinary = /^0b[01]+$/i; +var reIsOctal = /^0o[0-7]+$/i; +var freeParseInt = parseInt; +var freeGlobal$1 = typeof commonjsGlobal == "object" && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; +var freeSelf$1 = typeof self == "object" && self && self.Object === Object && self; +var root$1 = freeGlobal$1 || freeSelf$1 || Function("return this")(); +var objectProto$1 = Object.prototype; +var objectToString$1 = objectProto$1.toString; +var nativeMax = Math.max, nativeMin = Math.min; +var now = function() { + return root$1.Date.now(); +}; +function debounce$1(func, wait, options) { + var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true; + if (typeof func != "function") { + throw new TypeError(FUNC_ERROR_TEXT); + } + wait = toNumber(wait) || 0; + if (isObject$9(options)) { + leading = !!options.leading; + maxing = "maxWait" in options; + maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; + trailing = "trailing" in options ? !!options.trailing : trailing; + } + function invokeFunc(time2) { + var args = lastArgs, thisArg = lastThis; + lastArgs = lastThis = void 0; + lastInvokeTime = time2; + result = func.apply(thisArg, args); + return result; + } + function leadingEdge(time2) { + lastInvokeTime = time2; + timerId = setTimeout(timerExpired, wait); + return leading ? invokeFunc(time2) : result; + } + function remainingWait(time2) { + var timeSinceLastCall = time2 - lastCallTime, timeSinceLastInvoke = time2 - lastInvokeTime, result2 = wait - timeSinceLastCall; + return maxing ? nativeMin(result2, maxWait - timeSinceLastInvoke) : result2; + } + function shouldInvoke(time2) { + var timeSinceLastCall = time2 - lastCallTime, timeSinceLastInvoke = time2 - lastInvokeTime; + return lastCallTime === void 0 || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait; + } + function timerExpired() { + var time2 = now(); + if (shouldInvoke(time2)) { + return trailingEdge(time2); + } + timerId = setTimeout(timerExpired, remainingWait(time2)); + } + function trailingEdge(time2) { + timerId = void 0; + if (trailing && lastArgs) { + return invokeFunc(time2); + } + lastArgs = lastThis = void 0; + return result; + } + function cancel() { + if (timerId !== void 0) { + clearTimeout(timerId); + } + lastInvokeTime = 0; + lastArgs = lastCallTime = lastThis = timerId = void 0; + } + function flush2() { + return timerId === void 0 ? result : trailingEdge(now()); + } + function debounced() { + var time2 = now(), isInvoking = shouldInvoke(time2); + lastArgs = arguments; + lastThis = this; + lastCallTime = time2; + if (isInvoking) { + if (timerId === void 0) { + return leadingEdge(lastCallTime); + } + if (maxing) { + timerId = setTimeout(timerExpired, wait); + return invokeFunc(lastCallTime); + } + } + if (timerId === void 0) { + timerId = setTimeout(timerExpired, wait); + } + return result; + } + debounced.cancel = cancel; + debounced.flush = flush2; + return debounced; +} +function throttle(func, wait, options) { + var leading = true, trailing = true; + if (typeof func != "function") { + throw new TypeError(FUNC_ERROR_TEXT); + } + if (isObject$9(options)) { + leading = "leading" in options ? !!options.leading : leading; + trailing = "trailing" in options ? !!options.trailing : trailing; + } + return debounce$1(func, wait, { + "leading": leading, + "maxWait": wait, + "trailing": trailing + }); +} +function isObject$9(value) { + var type = typeof value; + return !!value && (type == "object" || type == "function"); +} +function isObjectLike(value) { + return !!value && typeof value == "object"; +} +function isSymbol$3(value) { + return typeof value == "symbol" || isObjectLike(value) && objectToString$1.call(value) == symbolTag; +} +function toNumber(value) { + if (typeof value == "number") { + return value; + } + if (isSymbol$3(value)) { + return NAN; + } + if (isObject$9(value)) { + var other = typeof value.valueOf == "function" ? value.valueOf() : value; + value = isObject$9(other) ? other + "" : other; + } + if (typeof value != "string") { + return value === 0 ? value : +value; + } + value = value.replace(reTrim, ""); + var isBinary = reIsBinary.test(value); + return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value; +} +var lodash_throttle = throttle; +const throttle$1 = /* @__PURE__ */ getDefaultExportFromCjs(lodash_throttle); +var LARGE_ARRAY_SIZE = 200; +var HASH_UNDEFINED = "__lodash_hash_undefined__"; +var INFINITY = 1 / 0; +var funcTag = "[object Function]", genTag = "[object GeneratorFunction]"; +var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; +var reIsHostCtor = /^\[object .+?Constructor\]$/; +var freeGlobal = typeof commonjsGlobal == "object" && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; +var freeSelf = typeof self == "object" && self && self.Object === Object && self; +var root = freeGlobal || freeSelf || Function("return this")(); +function arrayIncludes$1(array2, value) { + var length = array2 ? array2.length : 0; + return !!length && baseIndexOf(array2, value, 0) > -1; +} +function baseFindIndex(array2, predicate, fromIndex, fromRight) { + var length = array2.length, index2 = fromIndex + -1; + while (++index2 < length) { + if (predicate(array2[index2], index2, array2)) { + return index2; + } + } + return -1; +} +function baseIndexOf(array2, value, fromIndex) { + if (value !== value) { + return baseFindIndex(array2, baseIsNaN, fromIndex); + } + var index2 = fromIndex - 1, length = array2.length; + while (++index2 < length) { + if (array2[index2] === value) { + return index2; + } + } + return -1; +} +function baseIsNaN(value) { + return value !== value; +} +function cacheHas(cache, key) { + return cache.has(key); +} +function getValue(object2, key) { + return object2 == null ? void 0 : object2[key]; +} +function isHostObject(value) { + var result = false; + if (value != null && typeof value.toString != "function") { + try { + result = !!(value + ""); + } catch (e2) { + } + } + return result; +} +function setToArray(set2) { + var index2 = -1, result = Array(set2.size); + set2.forEach(function(value) { + result[++index2] = value; + }); + return result; +} +var arrayProto = Array.prototype, funcProto = Function.prototype, objectProto = Object.prototype; +var coreJsData = root["__core-js_shared__"]; +var maskSrcKey = function() { + var uid2 = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ""); + return uid2 ? "Symbol(src)_1." + uid2 : ""; +}(); +var funcToString = funcProto.toString; +var hasOwnProperty$2 = objectProto.hasOwnProperty; +var objectToString = objectProto.toString; +var reIsNative = RegExp( + "^" + funcToString.call(hasOwnProperty$2).replace(reRegExpChar, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$" +); +var splice = arrayProto.splice; +var Map$1 = getNative(root, "Map"), Set$1 = getNative(root, "Set"), nativeCreate = getNative(Object, "create"); +function Hash(entries) { + var index2 = -1, length = entries ? entries.length : 0; + this.clear(); + while (++index2 < length) { + var entry2 = entries[index2]; + this.set(entry2[0], entry2[1]); + } +} +function hashClear() { + this.__data__ = nativeCreate ? nativeCreate(null) : {}; +} +function hashDelete(key) { + return this.has(key) && delete this.__data__[key]; +} +function hashGet(key) { + var data2 = this.__data__; + if (nativeCreate) { + var result = data2[key]; + return result === HASH_UNDEFINED ? void 0 : result; + } + return hasOwnProperty$2.call(data2, key) ? data2[key] : void 0; +} +function hashHas(key) { + var data2 = this.__data__; + return nativeCreate ? data2[key] !== void 0 : hasOwnProperty$2.call(data2, key); +} +function hashSet(key, value) { + var data2 = this.__data__; + data2[key] = nativeCreate && value === void 0 ? HASH_UNDEFINED : value; + return this; +} +Hash.prototype.clear = hashClear; +Hash.prototype["delete"] = hashDelete; +Hash.prototype.get = hashGet; +Hash.prototype.has = hashHas; +Hash.prototype.set = hashSet; +function ListCache(entries) { + var index2 = -1, length = entries ? entries.length : 0; + this.clear(); + while (++index2 < length) { + var entry2 = entries[index2]; + this.set(entry2[0], entry2[1]); + } +} +function listCacheClear() { + this.__data__ = []; +} +function listCacheDelete(key) { + var data2 = this.__data__, index2 = assocIndexOf(data2, key); + if (index2 < 0) { + return false; + } + var lastIndex = data2.length - 1; + if (index2 == lastIndex) { + data2.pop(); + } else { + splice.call(data2, index2, 1); + } + return true; +} +function listCacheGet(key) { + var data2 = this.__data__, index2 = assocIndexOf(data2, key); + return index2 < 0 ? void 0 : data2[index2][1]; +} +function listCacheHas(key) { + return assocIndexOf(this.__data__, key) > -1; +} +function listCacheSet(key, value) { + var data2 = this.__data__, index2 = assocIndexOf(data2, key); + if (index2 < 0) { + data2.push([key, value]); + } else { + data2[index2][1] = value; + } + return this; +} +ListCache.prototype.clear = listCacheClear; +ListCache.prototype["delete"] = listCacheDelete; +ListCache.prototype.get = listCacheGet; +ListCache.prototype.has = listCacheHas; +ListCache.prototype.set = listCacheSet; +function MapCache(entries) { + var index2 = -1, length = entries ? entries.length : 0; + this.clear(); + while (++index2 < length) { + var entry2 = entries[index2]; + this.set(entry2[0], entry2[1]); + } +} +function mapCacheClear() { + this.__data__ = { + "hash": new Hash(), + "map": new (Map$1 || ListCache)(), + "string": new Hash() + }; +} +function mapCacheDelete(key) { + return getMapData(this, key)["delete"](key); +} +function mapCacheGet(key) { + return getMapData(this, key).get(key); +} +function mapCacheHas(key) { + return getMapData(this, key).has(key); +} +function mapCacheSet(key, value) { + getMapData(this, key).set(key, value); + return this; +} +MapCache.prototype.clear = mapCacheClear; +MapCache.prototype["delete"] = mapCacheDelete; +MapCache.prototype.get = mapCacheGet; +MapCache.prototype.has = mapCacheHas; +MapCache.prototype.set = mapCacheSet; +function SetCache(values) { + var index2 = -1, length = values ? values.length : 0; + this.__data__ = new MapCache(); + while (++index2 < length) { + this.add(values[index2]); + } +} +function setCacheAdd(value) { + this.__data__.set(value, HASH_UNDEFINED); + return this; +} +function setCacheHas(value) { + return this.__data__.has(value); +} +SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; +SetCache.prototype.has = setCacheHas; +function assocIndexOf(array2, key) { + var length = array2.length; + while (length--) { + if (eq(array2[length][0], key)) { + return length; + } + } + return -1; +} +function baseIsNative(value) { + if (!isObject$8(value) || isMasked(value)) { + return false; + } + var pattern = isFunction(value) || isHostObject(value) ? reIsNative : reIsHostCtor; + return pattern.test(toSource(value)); +} +function baseUniq(array2, iteratee, comparator) { + var index2 = -1, includes = arrayIncludes$1, length = array2.length, isCommon = true, result = [], seen = result; + if (length >= LARGE_ARRAY_SIZE) { + var set2 = createSet(array2); + if (set2) { + return setToArray(set2); + } + isCommon = false; + includes = cacheHas; + seen = new SetCache(); + } else { + seen = result; + } + outer: + while (++index2 < length) { + var value = array2[index2], computed2 = value; + value = value !== 0 ? value : 0; + if (isCommon && computed2 === computed2) { + var seenIndex = seen.length; + while (seenIndex--) { + if (seen[seenIndex] === computed2) { + continue outer; + } + } + result.push(value); + } else if (!includes(seen, computed2, comparator)) { + if (seen !== result) { + seen.push(computed2); + } + result.push(value); + } + } + return result; +} +var createSet = !(Set$1 && 1 / setToArray(new Set$1([, -0]))[1] == INFINITY) ? noop$3 : function(values) { + return new Set$1(values); +}; +function getMapData(map, key) { + var data2 = map.__data__; + return isKeyable(key) ? data2[typeof key == "string" ? "string" : "hash"] : data2.map; +} +function getNative(object2, key) { + var value = getValue(object2, key); + return baseIsNative(value) ? value : void 0; +} +function isKeyable(value) { + var type = typeof value; + return type == "string" || type == "number" || type == "symbol" || type == "boolean" ? value !== "__proto__" : value === null; +} +function isMasked(func) { + return !!maskSrcKey && maskSrcKey in func; +} +function toSource(func) { + if (func != null) { + try { + return funcToString.call(func); + } catch (e2) { + } + try { + return func + ""; + } catch (e2) { + } + } + return ""; +} +function uniq$1(array2) { + return array2 && array2.length ? baseUniq(array2) : []; +} +function eq(value, other) { + return value === other || value !== value && other !== other; +} +function isFunction(value) { + var tag = isObject$8(value) ? objectToString.call(value) : ""; + return tag == funcTag || tag == genTag; +} +function isObject$8(value) { + var type = typeof value; + return !!value && (type == "object" || type == "function"); +} +function noop$3() { +} +var lodash_uniq = uniq$1; +const _uniq = /* @__PURE__ */ getDefaultExportFromCjs(lodash_uniq); +const PERFORMANCE_COLORS = { + Good: "#40C057", + Mid: "#FFC078", + Poor: "#E03131" +}; +const PERFORMANCE_PREFIX_COLOR = PERFORMANCE_COLORS.Good; +class PerformanceTracker { + constructor() { + __publicField(this, "startTime", 0); + __publicField(this, "name", ""); + __publicField(this, "frames", 0); + __publicField(this, "started", false); + __publicField(this, "frame", null); + // eslint-disable-next-line local/prefer-class-methods + __publicField(this, "recordFrame", () => { + this.frames++; + if (!this.started) return; + this.frame = requestAnimationFrame(this.recordFrame); + }); + } + start(name) { + this.name = name; + this.frames = 0; + this.started = true; + if (this.frame !== null) cancelAnimationFrame(this.frame); + this.frame = requestAnimationFrame(this.recordFrame); + this.startTime = performance.now(); + } + stop() { + this.started = false; + if (this.frame !== null) cancelAnimationFrame(this.frame); + const duration = (performance.now() - this.startTime) / 1e3; + const fps = duration === 0 ? 0 : Math.floor(this.frames / duration); + const background = fps > 55 ? PERFORMANCE_COLORS.Good : fps > 30 ? PERFORMANCE_COLORS.Mid : PERFORMANCE_COLORS.Poor; + const color = background === PERFORMANCE_COLORS.Mid ? "black" : "white"; + const capitalized = this.name[0].toUpperCase() + this.name.slice(1); + console.debug( + `%cPerf%c ${capitalized} %c${fps}%c fps`, + `color: white; background: ${PERFORMANCE_PREFIX_COLOR};padding: 2px;border-radius: 3px;`, + "font-weight: normal", + `font-weight: bold; padding: 2px; background: ${background};color: ${color};`, + "font-weight: normal" + ); + } + isStarted() { + return this.started; + } +} +function dedupe(input, equals2) { + const result = []; + mainLoop: for (const item of input) { + for (const existing of result) { + if (equals2 ? equals2(item, existing) : item === existing) { + continue mainLoop; + } + } + result.push(item); + } + return result; +} +function compact(arr) { + return arr.filter((i2) => i2 !== void 0 && i2 !== null); +} +function last$1(arr) { + return arr[arr.length - 1]; +} +function minBy(arr, fn) { + let min2; + let minVal = Infinity; + for (const item of arr) { + const val = fn(item); + if (val < minVal) { + min2 = item; + minVal = val; + } + } + return min2; +} +function areArraysShallowEqual(arr1, arr2) { + if (arr1 === arr2) return true; + if (arr1.length !== arr2.length) return false; + for (let i2 = 0; i2 < arr1.length; i2++) { + if (!Object.is(arr1[i2], arr2[i2])) { + return false; + } + } + return true; +} +function omitFromStackTrace(fn) { + const wrappedFn = (...args) => { + try { + return fn(...args); + } catch (error) { + if (error instanceof Error && Error.captureStackTrace) { + Error.captureStackTrace(error, wrappedFn); + } + throw error; + } + }; + return wrappedFn; +} +const noop$2 = () => { +}; +const Result = { + ok(value) { + return { ok: true, value }; + }, + err(error) { + return { ok: false, error }; + } +}; +function exhaustiveSwitchError(value, property) { + const debugValue = property && value && typeof value === "object" && property in value ? value[property] : value; + throw new Error(`Unknown switch case ${debugValue}`); +} +const assert = omitFromStackTrace( + (value, message) => { + if (!value) { + throw new Error(message || "Assertion Error"); + } + } +); +const assertExists = omitFromStackTrace((value, message) => { + if (value == null) { + throw new Error(message ?? "value must be defined"); + } + return value; +}); +function promiseWithResolve() { + let resolve; + let reject; + const promise = new Promise((res, rej) => { + resolve = res; + reject = rej; + }); + return Object.assign(promise, { + resolve, + reject + }); +} +function sleep(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} +function bind$2(...args) { + if (args.length === 2) { + const [originalMethod, context] = args; + context.addInitializer(function initializeMethod() { + assert(Reflect.isExtensible(this), "Cannot bind to a non-extensible class."); + const value = originalMethod.bind(this); + const ok = Reflect.defineProperty(this, context.name, { + value, + writable: true, + configurable: true + }); + assert(ok, "Cannot bind a non-configurable class method."); + }); + } else { + const [_target, propertyKey, descriptor] = args; + if (!descriptor || typeof descriptor.value !== "function") { + throw new TypeError( + `Only methods can be decorated with @bind. <${propertyKey}> is not a method!` + ); + } + return { + configurable: true, + get() { + const bound = descriptor.value.bind(this); + Object.defineProperty(this, propertyKey, { + value: bound, + configurable: true, + writable: true + }); + return bound; + } + }; + } +} +class WeakCache { + constructor() { + /** The map of items to their cached values. */ + __publicField(this, "items", /* @__PURE__ */ new WeakMap()); + } + /** + * Get the cached value for a given record. If the record is not present in the map, the callback + * will be used to create the value (with the result being stored in the cache for next time). + * + * @param item - The item to get. + * @param cb - The callback to use to create the value when a cached value is not found. + */ + get(item, cb) { + if (!this.items.has(item)) { + this.items.set(item, cb(item)); + } + return this.items.get(item); + } +} +function debounce(callback, wait) { + let state = void 0; + const fn = (...args) => { + if (!state) { + state = {}; + state.promise = new Promise((resolve, reject) => { + state.resolve = resolve; + state.reject = reject; + }); + } + clearTimeout(state.timeout); + state.latestArgs = args; + state.timeout = setTimeout(() => { + const s2 = state; + state = void 0; + try { + s2.resolve(callback(...s2.latestArgs)); + } catch (e2) { + s2.reject(e2); + } + }, wait); + return state.promise; + }; + fn.cancel = () => { + if (!state) return; + clearTimeout(state.timeout); + }; + return fn; +} +const annotationsByError = /* @__PURE__ */ new WeakMap(); +function annotateError(error, annotations) { + if (typeof error !== "object" || error === null) return; + let currentAnnotations = annotationsByError.get(error); + if (!currentAnnotations) { + currentAnnotations = { tags: {}, extras: {} }; + annotationsByError.set(error, currentAnnotations); + } + if (annotations.tags) { + currentAnnotations.tags = { + ...currentAnnotations.tags, + ...annotations.tags + }; + } + if (annotations.extras) { + currentAnnotations.extras = { + ...currentAnnotations.extras, + ...annotations.extras + }; + } +} +async function fetch$1(input, init) { + return window.fetch(input, { + // We want to make sure that the referrer is not sent to other domains. + referrerPolicy: "strict-origin-when-cross-origin", + ...init + }); +} +const Image = (width, height) => { + const img = new window.Image(width, height); + img.referrerPolicy = "strict-origin-when-cross-origin"; + return img; +}; +class FileHelpers { + /** + * @param dataURL - The file as a string. + * + * from https://stackoverflow.com/a/53817185 + */ + static async dataUrlToArrayBuffer(dataURL) { + return fetch$1(dataURL).then(function(result) { + return result.arrayBuffer(); + }); + } + /** + * Convert a file to a base64 encoded data url. + * + * @example + * + * ```ts + * const A = FileHelpers.toDataUrl(myImageFile) + * ``` + * + * @param file - The file as a blob. + */ + static async blobToDataUrl(file) { + return await new Promise((resolve, reject) => { + if (file) { + const reader = new FileReader(); + reader.onload = () => resolve(reader.result); + reader.onerror = (error) => reject(error); + reader.onabort = (error) => reject(error); + reader.readAsDataURL(file); + } + }); + } + /** + * Convert a file to a unicode text string. + * + * @example + * + * ```ts + * const A = FileHelpers.fileToDataUrl(myTextFile) + * ``` + * + * @param file - The file as a blob. + */ + static async blobToText(file) { + return await new Promise((resolve, reject) => { + if (file) { + const reader = new FileReader(); + reader.onload = () => resolve(reader.result); + reader.onerror = (error) => reject(error); + reader.onabort = (error) => reject(error); + reader.readAsText(file); + } + }); + } +} +function getHashForString(string2) { + let hash = 0; + for (let i2 = 0; i2 < string2.length; i2++) { + hash = (hash << 5) - hash + string2.charCodeAt(i2); + hash |= 0; + } + return hash + ""; +} +function getHashForBuffer(buffer) { + const view = new DataView(buffer); + let hash = 0; + for (let i2 = 0; i2 < view.byteLength; i2++) { + hash = (hash << 5) - hash + view.getUint8(i2); + hash |= 0; + } + return hash + ""; +} +/*! + * MIT License: https://github.com/ai/nanoid/blob/main/LICENSE + * Modified code originally from + * Copyright 2017 Andrey Sitnik + * + * `nanoid` is currently only distributed as an ES module. Some tools (jest, playwright) don't + * properly support ESM-only code yet, and tldraw itself is distributed as both an ES module and a + * CommonJS module. By including nanoid here, we can make sure it works well in every environment + * where tldraw is used. We can also remove some unused features like custom alphabets. + */ +const crypto$1 = globalThis.crypto; +const urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"; +const POOL_SIZE_MULTIPLIER = 128; +let pool, poolOffset; +function fillPool(bytes) { + if (!pool || pool.length < bytes) { + pool = new Uint8Array(bytes * POOL_SIZE_MULTIPLIER); + crypto$1.getRandomValues(pool); + poolOffset = 0; + } else if (poolOffset + bytes > pool.length) { + crypto$1.getRandomValues(pool); + poolOffset = 0; + } + poolOffset += bytes; +} +function nanoid(size2 = 21) { + fillPool(size2 -= 0); + let id2 = ""; + for (let i2 = poolOffset - size2; i2 < poolOffset; i2++) { + id2 += urlAlphabet[pool[i2] & 63]; + } + return id2; +} +let impl = nanoid; +function uniqueId(size2) { + return impl(size2); +} +/*! + * MIT License: https://github.com/vHeemstra/is-apng/blob/main/license + * Copyright (c) Philip van Heemstra + */ +function isApngAnimated(buffer) { + const view = new Uint8Array(buffer); + if (!view || !(typeof Buffer !== "undefined" && Buffer.isBuffer(view) || view instanceof Uint8Array) || view.length < 16) { + return false; + } + const isPNG = view[0] === 137 && view[1] === 80 && view[2] === 78 && view[3] === 71 && view[4] === 13 && view[5] === 10 && view[6] === 26 && view[7] === 10; + if (!isPNG) { + return false; + } + function indexOfSubstring(haystack, needle, fromIndex, upToIndex, chunksize = 1024) { + if (!needle) { + return -1; + } + needle = new RegExp(needle, "g"); + const needle_length = needle.source.length; + const decoder = new TextDecoder(); + const full_haystack_length = haystack.length; + if (typeof upToIndex === "undefined") { + upToIndex = full_haystack_length; + } + if (fromIndex >= full_haystack_length || upToIndex <= 0 || fromIndex >= upToIndex) { + return -1; + } + haystack = haystack.subarray(fromIndex, upToIndex); + let position = -1; + let current_index = 0; + let full_length = 0; + let needle_buffer = ""; + outer: while (current_index < haystack.length) { + const next_index = current_index + chunksize; + const chunk = haystack.subarray(current_index, next_index); + const decoded = decoder.decode(chunk, { stream: true }); + const text = needle_buffer + decoded; + let match2; + let last_index = -1; + while ((match2 = needle.exec(text)) !== null) { + last_index = match2.index - needle_buffer.length; + position = full_length + last_index; + break outer; + } + current_index = next_index; + full_length += decoded.length; + const needle_index = last_index > -1 ? last_index + needle_length : decoded.length - needle_length; + needle_buffer = decoded.slice(needle_index); + } + if (position >= 0) { + position += fromIndex >= 0 ? fromIndex : full_haystack_length + fromIndex; + } + return position; + } + const idatIdx = indexOfSubstring(view, "IDAT", 12); + if (idatIdx >= 12) { + const actlIdx = indexOfSubstring(view, "acTL", 8, idatIdx); + return actlIdx >= 8; + } + return false; +} +const isAvifAnimated = (buffer) => { + const view = new Uint8Array(buffer); + return view[3] === 44; +}; +/*! + * MIT License + * Modified code originally from + * Copyright (c) 2016 Józef Sokołowski + */ +function getDataBlocksLength(buffer, offset2) { + let length = 0; + while (buffer[offset2 + length]) { + length += buffer[offset2 + length] + 1; + } + return length + 1; +} +function isGIF(buffer) { + const enc = new TextDecoder("ascii"); + const header = enc.decode(buffer.slice(0, 3)); + return header === "GIF"; +} +function isGifAnimated(buffer) { + const view = new Uint8Array(buffer); + let hasColorTable, colorTableSize; + let offset2 = 0; + let imagesCount = 0; + if (!isGIF(buffer)) { + return false; + } + hasColorTable = view[10] & 128; + colorTableSize = view[10] & 7; + offset2 += 6; + offset2 += 7; + offset2 += hasColorTable ? 3 * Math.pow(2, colorTableSize + 1) : 0; + while (imagesCount < 2 && offset2 < view.length) { + switch (view[offset2]) { + case 44: + imagesCount += 1; + hasColorTable = view[offset2 + 9] & 128; + colorTableSize = view[offset2 + 9] & 7; + offset2 += 10; + offset2 += hasColorTable ? 3 * Math.pow(2, colorTableSize + 1) : 0; + offset2 += getDataBlocksLength(view, offset2 + 1) + 1; + break; + case 33: + offset2 += 2; + offset2 += getDataBlocksLength(view, offset2); + break; + case 59: + offset2 = view.length; + break; + default: + offset2 = view.length; + break; + } + } + return imagesCount > 1; +} +/*! + * MIT License: https://github.com/alexgorbatchev/crc/blob/master/LICENSE + * Copyright: 2014 Alex Gorbatchev + * Code: crc32, https://github.com/alexgorbatchev/crc/blob/master/src/calculators/crc32.ts + */ +let TABLE = [ + 0, + 1996959894, + 3993919788, + 2567524794, + 124634137, + 1886057615, + 3915621685, + 2657392035, + 249268274, + 2044508324, + 3772115230, + 2547177864, + 162941995, + 2125561021, + 3887607047, + 2428444049, + 498536548, + 1789927666, + 4089016648, + 2227061214, + 450548861, + 1843258603, + 4107580753, + 2211677639, + 325883990, + 1684777152, + 4251122042, + 2321926636, + 335633487, + 1661365465, + 4195302755, + 2366115317, + 997073096, + 1281953886, + 3579855332, + 2724688242, + 1006888145, + 1258607687, + 3524101629, + 2768942443, + 901097722, + 1119000684, + 3686517206, + 2898065728, + 853044451, + 1172266101, + 3705015759, + 2882616665, + 651767980, + 1373503546, + 3369554304, + 3218104598, + 565507253, + 1454621731, + 3485111705, + 3099436303, + 671266974, + 1594198024, + 3322730930, + 2970347812, + 795835527, + 1483230225, + 3244367275, + 3060149565, + 1994146192, + 31158534, + 2563907772, + 4023717930, + 1907459465, + 112637215, + 2680153253, + 3904427059, + 2013776290, + 251722036, + 2517215374, + 3775830040, + 2137656763, + 141376813, + 2439277719, + 3865271297, + 1802195444, + 476864866, + 2238001368, + 4066508878, + 1812370925, + 453092731, + 2181625025, + 4111451223, + 1706088902, + 314042704, + 2344532202, + 4240017532, + 1658658271, + 366619977, + 2362670323, + 4224994405, + 1303535960, + 984961486, + 2747007092, + 3569037538, + 1256170817, + 1037604311, + 2765210733, + 3554079995, + 1131014506, + 879679996, + 2909243462, + 3663771856, + 1141124467, + 855842277, + 2852801631, + 3708648649, + 1342533948, + 654459306, + 3188396048, + 3373015174, + 1466479909, + 544179635, + 3110523913, + 3462522015, + 1591671054, + 702138776, + 2966460450, + 3352799412, + 1504918807, + 783551873, + 3082640443, + 3233442989, + 3988292384, + 2596254646, + 62317068, + 1957810842, + 3939845945, + 2647816111, + 81470997, + 1943803523, + 3814918930, + 2489596804, + 225274430, + 2053790376, + 3826175755, + 2466906013, + 167816743, + 2097651377, + 4027552580, + 2265490386, + 503444072, + 1762050814, + 4150417245, + 2154129355, + 426522225, + 1852507879, + 4275313526, + 2312317920, + 282753626, + 1742555852, + 4189708143, + 2394877945, + 397917763, + 1622183637, + 3604390888, + 2714866558, + 953729732, + 1340076626, + 3518719985, + 2797360999, + 1068828381, + 1219638859, + 3624741850, + 2936675148, + 906185462, + 1090812512, + 3747672003, + 2825379669, + 829329135, + 1181335161, + 3412177804, + 3160834842, + 628085408, + 1382605366, + 3423369109, + 3138078467, + 570562233, + 1426400815, + 3317316542, + 2998733608, + 733239954, + 1555261956, + 3268935591, + 3050360625, + 752459403, + 1541320221, + 2607071920, + 3965973030, + 1969922972, + 40735498, + 2617837225, + 3943577151, + 1913087877, + 83908371, + 2512341634, + 3803740692, + 2075208622, + 213261112, + 2463272603, + 3855990285, + 2094854071, + 198958881, + 2262029012, + 4057260610, + 1759359992, + 534414190, + 2176718541, + 4139329115, + 1873836001, + 414664567, + 2282248934, + 4279200368, + 1711684554, + 285281116, + 2405801727, + 4167216745, + 1634467795, + 376229701, + 2685067896, + 3608007406, + 1308918612, + 956543938, + 2808555105, + 3495958263, + 1231636301, + 1047427035, + 2932959818, + 3654703836, + 1088359270, + 936918e3, + 2847714899, + 3736837829, + 1202900863, + 817233897, + 3183342108, + 3401237130, + 1404277552, + 615818150, + 3134207493, + 3453421203, + 1423857449, + 601450431, + 3009837614, + 3294710456, + 1567103746, + 711928724, + 3020668471, + 3272380065, + 1510334235, + 755167117 +]; +if (typeof Int32Array !== "undefined") { + TABLE = new Int32Array(TABLE); +} +const crc = (current, previous) => { + let crc2 = ~~previous ^ -1; + for (let index2 = 0; index2 < current.length; index2++) { + crc2 = TABLE[(crc2 ^ current[index2]) & 255] ^ crc2 >>> 8; + } + return crc2 ^ -1; +}; +const LEN_SIZE = 4; +const CRC_SIZE = 4; +class PngHelpers { + static isPng(view, offset2) { + if (view.getUint8(offset2 + 0) === 137 && view.getUint8(offset2 + 1) === 80 && view.getUint8(offset2 + 2) === 78 && view.getUint8(offset2 + 3) === 71 && view.getUint8(offset2 + 4) === 13 && view.getUint8(offset2 + 5) === 10 && view.getUint8(offset2 + 6) === 26 && view.getUint8(offset2 + 7) === 10) { + return true; + } + return false; + } + static getChunkType(view, offset2) { + return [ + String.fromCharCode(view.getUint8(offset2)), + String.fromCharCode(view.getUint8(offset2 + 1)), + String.fromCharCode(view.getUint8(offset2 + 2)), + String.fromCharCode(view.getUint8(offset2 + 3)) + ].join(""); + } + static readChunks(view, offset2 = 0) { + const chunks = {}; + if (!PngHelpers.isPng(view, offset2)) { + throw new Error("Not a PNG"); + } + offset2 += 8; + while (offset2 <= view.buffer.byteLength) { + const start = offset2; + const len = view.getInt32(offset2); + offset2 += 4; + const chunkType = PngHelpers.getChunkType(view, offset2); + if (chunkType === "IDAT" && chunks[chunkType]) { + offset2 += len + LEN_SIZE + CRC_SIZE; + continue; + } + if (chunkType === "IEND") { + break; + } + chunks[chunkType] = { + start, + dataOffset: offset2 + 4, + size: len + }; + offset2 += len + LEN_SIZE + CRC_SIZE; + } + return chunks; + } + static parsePhys(view, offset2) { + return { + ppux: view.getUint32(offset2), + ppuy: view.getUint32(offset2 + 4), + unit: view.getUint8(offset2 + 4) + }; + } + static findChunk(view, type) { + const chunks = PngHelpers.readChunks(view); + return chunks[type]; + } + static setPhysChunk(view, dpr = 1, options) { + let offset2 = 46; + let size2 = 0; + const res1 = PngHelpers.findChunk(view, "pHYs"); + if (res1) { + offset2 = res1.start; + size2 = res1.size; + } + const res2 = PngHelpers.findChunk(view, "IDAT"); + if (res2) { + offset2 = res2.start; + size2 = 0; + } + const pHYsData = new ArrayBuffer(21); + const pHYsDataView = new DataView(pHYsData); + pHYsDataView.setUint32(0, 9); + pHYsDataView.setUint8(4, "p".charCodeAt(0)); + pHYsDataView.setUint8(5, "H".charCodeAt(0)); + pHYsDataView.setUint8(6, "Y".charCodeAt(0)); + pHYsDataView.setUint8(7, "s".charCodeAt(0)); + const DPI_96 = 2835.5; + pHYsDataView.setInt32(8, DPI_96 * dpr); + pHYsDataView.setInt32(12, DPI_96 * dpr); + pHYsDataView.setInt8(16, 1); + const crcBit = new Uint8Array(pHYsData.slice(4, 17)); + pHYsDataView.setInt32(17, crc(crcBit)); + const startBuf = view.buffer.slice(0, offset2); + const endBuf = view.buffer.slice(offset2 + size2); + return new Blob([startBuf, pHYsData, endBuf], options); + } +} +/*! + * MIT License: https://github.com/sindresorhus/is-webp/blob/main/license + * Copyright (c) Sindre Sorhus (https://sindresorhus.com) + */ +function isWebp(view) { + if (!view || view.length < 12) { + return false; + } + return view[8] === 87 && view[9] === 69 && view[10] === 66 && view[11] === 80; +} +function isWebpAnimated(buffer) { + const view = new Uint8Array(buffer); + if (!isWebp(view)) { + return false; + } + if (!view || view.length < 21) { + return false; + } + return (view[20] >> 1 & 1) === 1; +} +const DEFAULT_SUPPORTED_VECTOR_IMAGE_TYPES = Object.freeze(["image/svg+xml"]); +const DEFAULT_SUPPORTED_STATIC_IMAGE_TYPES = Object.freeze([ + "image/jpeg", + "image/png", + "image/webp" +]); +const DEFAULT_SUPPORTED_ANIMATED_IMAGE_TYPES = Object.freeze([ + "image/gif", + "image/apng", + "image/avif" +]); +const DEFAULT_SUPPORTED_IMAGE_TYPES = Object.freeze([ + ...DEFAULT_SUPPORTED_STATIC_IMAGE_TYPES, + ...DEFAULT_SUPPORTED_VECTOR_IMAGE_TYPES, + ...DEFAULT_SUPPORTED_ANIMATED_IMAGE_TYPES +]); +const DEFAULT_SUPPORT_VIDEO_TYPES = Object.freeze([ + "video/mp4", + "video/webm", + "video/quicktime" +]); +const DEFAULT_SUPPORTED_MEDIA_TYPE_LIST = [ + ...DEFAULT_SUPPORTED_IMAGE_TYPES, + ...DEFAULT_SUPPORT_VIDEO_TYPES +].join(","); +class MediaHelpers { + /** + * Load a video from a url. + * @public + */ + static loadVideo(src) { + return new Promise((resolve, reject) => { + const video = document.createElement("video"); + video.onloadeddata = () => resolve(video); + video.onerror = (e2) => { + console.error(e2); + reject(new Error("Could not load video")); + }; + video.crossOrigin = "anonymous"; + video.src = src; + }); + } + static async getVideoFrameAsDataUrl(video, time2 = 0) { + const promise = promiseWithResolve(); + let didSetTime = false; + const onReadyStateChanged = () => { + if (!didSetTime) { + if (video.readyState >= video.HAVE_METADATA) { + didSetTime = true; + video.currentTime = time2; + } else { + return; + } + } + if (video.readyState >= video.HAVE_CURRENT_DATA) { + const canvas = document.createElement("canvas"); + canvas.width = video.videoWidth; + canvas.height = video.videoHeight; + const ctx = canvas.getContext("2d"); + if (!ctx) { + throw new Error("Could not get 2d context"); + } + ctx.drawImage(video, 0, 0); + promise.resolve(canvas.toDataURL()); + } + }; + const onError = (e2) => { + console.error(e2); + promise.reject(new Error("Could not get video frame")); + }; + video.addEventListener("loadedmetadata", onReadyStateChanged); + video.addEventListener("loadeddata", onReadyStateChanged); + video.addEventListener("canplay", onReadyStateChanged); + video.addEventListener("seeked", onReadyStateChanged); + video.addEventListener("error", onError); + video.addEventListener("stalled", onError); + onReadyStateChanged(); + try { + return await promise; + } finally { + video.removeEventListener("loadedmetadata", onReadyStateChanged); + video.removeEventListener("loadeddata", onReadyStateChanged); + video.removeEventListener("canplay", onReadyStateChanged); + video.removeEventListener("seeked", onReadyStateChanged); + video.removeEventListener("error", onError); + video.removeEventListener("stalled", onError); + } + } + /** + * Load an image from a url. + * @public + */ + static loadImage(src) { + return new Promise((resolve, reject) => { + const img = Image(); + img.onload = () => resolve(img); + img.onerror = (e2) => { + console.error(e2); + reject(new Error("Could not load image")); + }; + img.crossOrigin = "anonymous"; + img.referrerPolicy = "strict-origin-when-cross-origin"; + img.src = src; + }); + } + /** + * Get the size of a video blob + * + * @param blob - A SharedBlob containing the video + * @public + */ + static async getVideoSize(blob) { + return MediaHelpers.usingObjectURL(blob, async (url) => { + const video = await MediaHelpers.loadVideo(url); + return { w: video.videoWidth, h: video.videoHeight }; + }); + } + /** + * Get the size of an image blob + * + * @param blob - A Blob containing the image. + * @public + */ + static async getImageSize(blob) { + const image = await MediaHelpers.usingObjectURL(blob, MediaHelpers.loadImage); + try { + if (blob.type === "image/png") { + const view = new DataView(await blob.arrayBuffer()); + if (PngHelpers.isPng(view, 0)) { + const physChunk = PngHelpers.findChunk(view, "pHYs"); + if (physChunk) { + const physData = PngHelpers.parsePhys(view, physChunk.dataOffset); + if (physData.unit === 0 && physData.ppux === physData.ppuy) { + const pixelRatio = Math.max(physData.ppux / 2834.5, 1); + return { + w: Math.round(image.naturalWidth / pixelRatio), + h: Math.round(image.naturalHeight / pixelRatio) + }; + } + } + } + } + } catch (err) { + console.error(err); + return { w: image.naturalWidth, h: image.naturalHeight }; + } + return { w: image.naturalWidth, h: image.naturalHeight }; + } + static async isAnimated(file) { + if (file.type === "image/gif") { + return isGifAnimated(await file.arrayBuffer()); + } + if (file.type === "image/avif") { + return isAvifAnimated(await file.arrayBuffer()); + } + if (file.type === "image/webp") { + return isWebpAnimated(await file.arrayBuffer()); + } + if (file.type === "image/apng") { + return isApngAnimated(await file.arrayBuffer()); + } + return false; + } + static isAnimatedImageType(mimeType) { + return DEFAULT_SUPPORTED_ANIMATED_IMAGE_TYPES.includes(mimeType || ""); + } + static isStaticImageType(mimeType) { + return DEFAULT_SUPPORTED_STATIC_IMAGE_TYPES.includes(mimeType || ""); + } + static isVectorImageType(mimeType) { + return DEFAULT_SUPPORTED_VECTOR_IMAGE_TYPES.includes(mimeType || ""); + } + static isImageType(mimeType) { + return DEFAULT_SUPPORTED_IMAGE_TYPES.includes(mimeType); + } + static async usingObjectURL(blob, fn) { + const url = URL.createObjectURL(blob); + try { + return await fn(url); + } finally { + URL.revokeObjectURL(url); + } + } +} +function lerp(a2, b2, t2) { + return a2 + (b2 - a2) * t2; +} +function rng(seed = "") { + let x2 = 0; + let y2 = 0; + let z = 0; + let w2 = 0; + function next() { + const t2 = x2 ^ x2 << 11; + x2 = y2; + y2 = z; + z = w2; + w2 ^= (w2 >>> 19 ^ t2 ^ t2 >>> 8) >>> 0; + return w2 / 4294967296 * 2; + } + for (let k = 0; k < seed.length + 64; k++) { + x2 ^= seed.charCodeAt(k) | 0; + next(); + } + return next; +} +function modulate(value, rangeA, rangeB, clamp2 = false) { + const [fromLow, fromHigh] = rangeA; + const [v0, v1] = rangeB; + const result = v0 + (value - fromLow) / (fromHigh - fromLow) * (v1 - v0); + return clamp2 ? v0 < v1 ? Math.max(Math.min(result, v1), v0) : Math.max(Math.min(result, v0), v1) : result; +} +function hasOwnProperty$1(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); +} +function getOwnProperty(obj, key) { + if (!hasOwnProperty$1(obj, key)) { + return void 0; + } + return obj[key]; +} +function objectMapKeys(object2) { + return Object.keys(object2); +} +function objectMapValues(object2) { + return Object.values(object2); +} +function objectMapEntries(object2) { + return Object.entries(object2); +} +function objectMapFromEntries(entries) { + return Object.fromEntries(entries); +} +function filterEntries(object2, predicate) { + const result = {}; + let didChange = false; + for (const [key, value] of objectMapEntries(object2)) { + if (predicate(key, value)) { + result[key] = value; + } else { + didChange = true; + } + } + return didChange ? result : object2; +} +function mapObjectMapValues(object2, mapper) { + const result = {}; + for (const [key, value] of objectMapEntries(object2)) { + const newValue = mapper(key, value); + result[key] = newValue; + } + return result; +} +function areObjectsShallowEqual(obj1, obj2) { + if (obj1 === obj2) return true; + const keys1 = new Set(Object.keys(obj1)); + const keys22 = new Set(Object.keys(obj2)); + if (keys1.size !== keys22.size) return false; + for (const key of keys1) { + if (!keys22.has(key)) return false; + if (!Object.is(obj1[key], obj2[key])) return false; + } + return true; +} +function indexCharacterSet(options) { + const dicts = createCharSetDicts(options.chars); + const limits = integerLimits( + dicts, + options.firstPositive, + options.mostPositive, + options.mostNegative + ); + const jitterRange = options.jitterRange ?? Math.floor(Math.pow(dicts.length, 3) / 5); + const paddingRange = paddingDict(jitterRange, dicts.length); + return { + chars: options.chars, + byChar: dicts.byChar, + byCode: dicts.byCode, + length: dicts.length, + first: dicts.byCode[0], + last: dicts.byCode[dicts.length - 1], + firstPositive: limits.firstPositive, + mostPositive: limits.mostPositive, + firstNegative: limits.firstNegative, + mostNegative: limits.mostNegative, + jitterRange, + paddingDict: paddingRange + }; +} +function createCharSetDicts(charSet) { + const byCode = {}; + const byChar = {}; + const length = charSet.length; + for (let i2 = 0; i2 < length; i2++) { + const char = charSet[i2]; + byCode[i2] = char; + byChar[char] = i2; + } + return { + byCode, + byChar, + length + }; +} +function integerLimits(dicts, firstPositive, mostPositive, mostNegative) { + const firstPositiveIndex = firstPositive ? dicts.byChar[firstPositive] : Math.ceil(dicts.length / 2); + const mostPositiveIndex = mostPositive ? dicts.byChar[mostPositive] : dicts.length - 1; + const mostNegativeIndex = mostNegative ? dicts.byChar[mostNegative] : 0; + if (firstPositiveIndex === void 0 || mostPositiveIndex === void 0 || mostNegativeIndex === void 0) { + throw new Error("invalid charSet"); + } + if (mostPositiveIndex - firstPositiveIndex < 3) { + throw new Error( + "mostPositive must be at least 3 characters away from neutral" + ); + } + if (firstPositiveIndex - mostNegativeIndex < 3) { + throw new Error( + "mostNegative must be at least 3 characters away from neutral" + ); + } + return { + firstPositive: dicts.byCode[firstPositiveIndex], + mostPositive: dicts.byCode[mostPositiveIndex], + firstNegative: dicts.byCode[firstPositiveIndex - 1], + mostNegative: dicts.byCode[mostNegativeIndex] + }; +} +function paddingDict(jitterRange, charSetLength) { + const paddingDict2 = {}; + for (let i2 = 0; i2 < 100; i2++) { + paddingDict2[i2] = Math.pow(charSetLength, i2); + if (paddingDict2[i2] > jitterRange) { + break; + } + } + return paddingDict2; +} +var _base62CharSet = null; +function base62CharSet() { + if (_base62CharSet) + return _base62CharSet; + return _base62CharSet = indexCharacterSet({ + // Base62 are all the alphanumeric characters, database and user friendly + // For shorter strings and more room you could opt for more characters + chars: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", + // This gives us nice human readable keys to start with a0 a1 etc + firstPositive: "a", + mostPositive: "z", + mostNegative: "A" + }); +} +function distanceBetween(a2, b2, charSet) { + const indexA = charSet.byChar[a2]; + const indexB = charSet.byChar[b2]; + return Math.abs(indexA - indexB); +} +function integerLength(head, charSet) { + const firstChar = head[0]; + if (firstChar > charSet.mostPositive || firstChar < charSet.mostNegative) { + throw new Error("invalid firstChar on key"); + } + if (firstChar === charSet.mostPositive) { + const firstLevel = distanceBetween(firstChar, charSet.firstPositive, charSet) + 1; + return firstLevel + integerLengthFromSecondLevel(head.slice(1), "positive", charSet); + } + if (firstChar === charSet.mostNegative) { + const firstLevel = distanceBetween(firstChar, charSet.firstNegative, charSet) + 1; + return firstLevel + integerLengthFromSecondLevel(head.slice(1), "negative", charSet); + } + const isPositiveRange = firstChar >= charSet.firstPositive; + if (isPositiveRange) { + return distanceBetween(firstChar, charSet.firstPositive, charSet) + 2; + } else { + return distanceBetween(firstChar, charSet.firstNegative, charSet) + 2; + } +} +function integerLengthFromSecondLevel(key, direction, charSet) { + const firstChar = key[0]; + if (firstChar > charSet.mostPositive || firstChar < charSet.mostNegative) { + throw new Error("invalid firstChar on key"); + } + if (firstChar === charSet.mostPositive && direction === "positive") { + const totalPositiveRoom = distanceBetween(firstChar, charSet.mostNegative, charSet) + 1; + return totalPositiveRoom + integerLengthFromSecondLevel(key.slice(1), direction, charSet); + } + if (firstChar === charSet.mostNegative && direction === "negative") { + const totalNegativeRoom = distanceBetween(firstChar, charSet.mostPositive, charSet) + 1; + return totalNegativeRoom + integerLengthFromSecondLevel(key.slice(1), direction, charSet); + } + if (direction === "positive") { + return distanceBetween(firstChar, charSet.mostNegative, charSet) + 2; + } else { + return distanceBetween(firstChar, charSet.mostPositive, charSet) + 2; + } +} +function makeSameLength(a2, b2, pad, fillChar, forceLength) { + const max2 = Math.max(a2.length, b2.length); + if (pad === "start") { + return [a2.padStart(max2, fillChar), b2.padStart(max2, fillChar)]; + } + return [a2.padEnd(max2, fillChar), b2.padEnd(max2, fillChar)]; +} +function midPoint(lower, upper, charSet) { + let [paddedLower, paddedUpper] = makeSameLength( + lower, + upper, + "end", + charSet.first + ); + let distance = lexicalDistance(paddedLower, paddedUpper, charSet); + if (distance === 1) { + paddedLower = paddedLower.padEnd(paddedLower.length + 1, charSet.first); + distance = charSet.length; + } + const mid = encodeToCharSet(Math.floor(distance / 2), charSet); + return addCharSetKeys(paddedLower, mid, charSet); +} +function lexicalDistance(a2, b2, charSet) { + const [lower, upper] = makeSameLength(a2, b2, "end", charSet.first).sort(); + const distance = subtractCharSetKeys(upper, lower, charSet); + return decodeCharSetToNumber(distance, charSet); +} +function addCharSetKeys(a2, b2, charSet) { + const base = charSet.length; + const [paddedA, paddedB] = makeSameLength(a2, b2, "start", charSet.first); + const result = []; + let carry = 0; + for (let i2 = paddedA.length - 1; i2 >= 0; i2--) { + const digitA = charSet.byChar[paddedA[i2]]; + const digitB = charSet.byChar[paddedB[i2]]; + const sum = digitA + digitB + carry; + carry = Math.floor(sum / base); + const remainder = sum % base; + result.unshift(charSet.byCode[remainder]); + } + if (carry > 0) { + result.unshift(charSet.byCode[carry]); + } + return result.join(""); +} +function subtractCharSetKeys(a2, b2, charSet) { + const base = charSet.length; + const [paddedA, paddedB] = makeSameLength(a2, b2, "start", charSet.first); + const result = []; + let borrow = 0; + for (let i2 = paddedA.length - 1; i2 >= 0; i2--) { + let digitA = charSet.byChar[paddedA[i2]]; + const digitB = charSet.byChar[paddedB[i2]] + borrow; + if (digitA < digitB) { + borrow = 1; + digitA += base; + } else { + borrow = 0; + } + const difference = digitA - digitB; + result.unshift(charSet.byCode[difference]); + } + if (borrow > 0) { + throw new Error( + "Subtraction result is negative. Ensure a is greater than or equal to b." + ); + } + while (result.length > 1 && result[0] === charSet.byCode[0]) { + result.shift(); + } + return result.join(""); +} +function incrementKey(key, charSet) { + return addCharSetKeys(key, charSet.byCode[1], charSet); +} +function decrementKey(key, charSet) { + return subtractCharSetKeys(key, charSet.byCode[1], charSet); +} +function encodeToCharSet(int, charSet) { + if (int === 0) { + return charSet.byCode[0]; + } + let res = ""; + const max2 = charSet.length; + while (int > 0) { + res = charSet.byCode[int % max2] + res; + int = Math.floor(int / max2); + } + return res; +} +function decodeCharSetToNumber(key, charSet) { + let res = 0; + const length = key.length; + const max2 = charSet.length; + for (let i2 = 0; i2 < length; i2++) { + res += charSet.byChar[key[i2]] * Math.pow(max2, length - i2 - 1); + } + return res; +} +function startKey(charSet) { + return charSet.firstPositive + charSet.byCode[0]; +} +function validInteger(integer2, charSet) { + const length = integerLength(integer2, charSet); + return length === integer2.length; +} +function validateOrderKey(orderKey, charSet) { + getIntegerPart(orderKey, charSet); +} +function getIntegerPart(orderKey, charSet) { + const head = integerHead(orderKey, charSet); + const integerPartLength = integerLength(head, charSet); + if (integerPartLength > orderKey.length) { + throw new Error("invalid order key length: " + orderKey); + } + return orderKey.slice(0, integerPartLength); +} +function validateInteger(integer2, charSet) { + if (!validInteger(integer2, charSet)) { + throw new Error("invalid integer length: " + integer2); + } +} +function incrementInteger(integer2, charSet) { + validateInteger(integer2, charSet); + const [head, digs] = splitInteger(integer2, charSet); + const anyNonMaxedDigit = digs.split("").some((d2) => d2 !== charSet.byCode[charSet.length - 1]); + if (anyNonMaxedDigit) { + const newDigits = incrementKey(digs, charSet); + return head + newDigits; + } + const nextHead = incrementIntegerHead(head, charSet); + return startOnNewHead(nextHead, "lower", charSet); +} +function decrementInteger(integer2, charSet) { + validateInteger(integer2, charSet); + const [head, digs] = splitInteger(integer2, charSet); + const anyNonLimitDigit = digs.split("").some((d2) => d2 !== charSet.byCode[0]); + if (anyNonLimitDigit) { + const newDigits = decrementKey(digs, charSet); + return head + newDigits; + } + const nextHead = decrementIntegerHead(head, charSet); + return startOnNewHead(nextHead, "upper", charSet); +} +function integerHead(integer2, charSet) { + let i2 = 0; + if (integer2[0] === charSet.mostPositive) { + while (integer2[i2] === charSet.mostPositive) { + i2 = i2 + 1; + } + } + if (integer2[0] === charSet.mostNegative) { + while (integer2[i2] === charSet.mostNegative) { + i2 = i2 + 1; + } + } + return integer2.slice(0, i2 + 1); +} +function splitInteger(integer2, charSet) { + const head = integerHead(integer2, charSet); + const tail = integer2.slice(head.length); + return [head, tail]; +} +function incrementIntegerHead(head, charSet) { + const inPositiveRange = head >= charSet.firstPositive; + const nextHead = incrementKey(head, charSet); + const headIsLimitMax = head[head.length - 1] === charSet.mostPositive; + const nextHeadIsLimitMax = nextHead[nextHead.length - 1] === charSet.mostPositive; + if (inPositiveRange && nextHeadIsLimitMax) { + return nextHead + charSet.mostNegative; + } + if (!inPositiveRange && headIsLimitMax) { + return head.slice(0, head.length - 1); + } + return nextHead; +} +function decrementIntegerHead(head, charSet) { + const inPositiveRange = head >= charSet.firstPositive; + const headIsLimitMin = head[head.length - 1] === charSet.mostNegative; + if (inPositiveRange && headIsLimitMin) { + const nextLevel = head.slice(0, head.length - 1); + return decrementKey(nextLevel, charSet); + } + if (!inPositiveRange && headIsLimitMin) { + return head + charSet.mostPositive; + } + return decrementKey(head, charSet); +} +function startOnNewHead(head, limit, charSet) { + const newLength = integerLength(head, charSet); + const fillChar = limit === "upper" ? charSet.byCode[charSet.length - 1] : charSet.byCode[0]; + return head + fillChar.repeat(newLength - head.length); +} +function jitterString(orderKey, charSet) { + const shift2 = encodeToCharSet( + Math.floor(Math.random() * charSet.jitterRange), + charSet + ); + return addCharSetKeys(orderKey, shift2, charSet); +} +function padAndJitterString(orderKey, numberOfChars, charSet) { + const paddedKey = orderKey.padEnd( + orderKey.length + numberOfChars, + charSet.first + ); + return jitterString(paddedKey, charSet); +} +function paddingNeededForJitter(orderKey, b2, charSet) { + const integer2 = getIntegerPart(orderKey, charSet); + const nextInteger = incrementInteger(integer2, charSet); + let needed = 0; + if (b2 !== null) { + const distanceToB = lexicalDistance(orderKey, b2, charSet); + if (distanceToB < charSet.jitterRange + 1) { + needed = Math.max(needed, paddingNeededForDistance(distanceToB, charSet)); + } + } + const distanceToNextInteger = lexicalDistance(orderKey, nextInteger, charSet); + if (distanceToNextInteger < charSet.jitterRange + 1) { + needed = Math.max( + needed, + paddingNeededForDistance(distanceToNextInteger, charSet) + ); + } + return needed; +} +function paddingNeededForDistance(distance, charSet) { + const gap = charSet.jitterRange - distance; + const firstBigger = Object.entries(charSet.paddingDict).find( + ([_key, value]) => { + return value > gap; + } + ); + return firstBigger ? parseInt(firstBigger[0]) : 0; +} +function generateKeyBetween(lower, upper, charSet = base62CharSet()) { + if (lower !== null) { + validateOrderKey(lower, charSet); + } + if (upper !== null) { + validateOrderKey(upper, charSet); + } + if (lower === null && upper === null) { + return startKey(charSet); + } + if (lower === null) { + const integer2 = getIntegerPart(upper, charSet); + return decrementInteger(integer2, charSet); + } + if (upper === null) { + const integer2 = getIntegerPart(lower, charSet); + return incrementInteger(integer2, charSet); + } + if (lower >= upper) { + throw new Error(lower + " >= " + upper); + } + return midPoint(lower, upper, charSet); +} +function generateJitteredKeyBetween(lower, upper, charSet = base62CharSet()) { + const key = generateKeyBetween(lower, upper, charSet); + const paddingNeeded = paddingNeededForJitter(key, upper, charSet); + if (paddingNeeded) { + return padAndJitterString(key, paddingNeeded, charSet); + } + return jitterString(key, charSet); +} +function generateNJitteredKeysBetween(lower, upper, n, charSet = base62CharSet()) { + return spreadGeneratorResults( + lower, + upper, + n, + charSet, + generateJitteredKeyBetween, + generateNJitteredKeysBetween + ); +} +function spreadGeneratorResults(lower, upper, n, charSet, generateKey, generateNKeys) { + if (n === 0) { + return []; + } + if (n === 1) { + return [generateKey(lower, upper, charSet)]; + } + if (upper == null) { + let newUpper = generateKey(lower, upper, charSet); + const result = [newUpper]; + for (let i2 = 0; i2 < n - 1; i2++) { + newUpper = generateKey(newUpper, upper, charSet); + result.push(newUpper); + } + return result; + } + if (lower == null) { + let newLower = generateKey(lower, upper, charSet); + const result = [newLower]; + for (let i2 = 0; i2 < n - 1; i2++) { + newLower = generateKey(lower, newLower, charSet); + result.push(newLower); + } + result.reverse(); + return result; + } + const mid = Math.floor(n / 2); + const midOrderKey = generateKey(lower, upper, charSet); + return [ + ...generateNKeys(lower, midOrderKey, mid, charSet), + midOrderKey, + ...generateNKeys(midOrderKey, upper, n - mid - 1, charSet) + ]; +} +const generateKeysFn = generateNJitteredKeysBetween; +const ZERO_INDEX_KEY = "a0"; +function validateIndexKey(index2) { + try { + generateJitteredKeyBetween(index2, null); + } catch { + throw new Error("invalid index: " + index2); + } +} +function getIndicesBetween(below, above, n) { + return generateKeysFn(below ?? null, above ?? null, n); +} +function getIndicesAbove(below, n) { + return generateKeysFn(below ?? null, null, n); +} +function getIndexBetween(below, above) { + return generateKeysFn(below ?? null, above ?? null, 1)[0]; +} +function getIndexAbove(below = null) { + return generateKeysFn(below, null, 1)[0]; +} +function getIndexBelow(above = null) { + return generateKeysFn(null, above, 1)[0]; +} +function getIndices(n, start = "a1") { + return [start, ...generateKeysFn(start, null, n)]; +} +function sortByIndex$1(a2, b2) { + if (a2.index < b2.index) { + return -1; + } else if (a2.index > b2.index) { + return 1; + } + return 0; +} +function sortById(a2, b2) { + return a2.id > b2.id ? 1 : -1; +} +function getFromLocalStorage(key) { + try { + return localStorage.getItem(key); + } catch { + return null; + } +} +function setInLocalStorage(key, value) { + try { + localStorage.setItem(key, value); + } catch { + } +} +function clearLocalStorage() { + try { + localStorage.clear(); + } catch { + } +} +function getFromSessionStorage(key) { + try { + return sessionStorage.getItem(key); + } catch { + return null; + } +} +function setInSessionStorage(key, value) { + try { + sessionStorage.setItem(key, value); + } catch { + } +} +function deleteFromSessionStorage(key) { + try { + sessionStorage.removeItem(key); + } catch { + } +} +function clearSessionStorage() { + try { + sessionStorage.clear(); + } catch { + } +} +const isTest$1 = () => typeof process !== "undefined" && false; +const fpsQueue = []; +const targetFps = 60; +const targetTimePerFrame = Math.ceil(1e3 / targetFps); +let frame; +let time = 0; +let last = 0; +const flush = () => { + const queue = fpsQueue.splice(0, fpsQueue.length); + for (const fn of queue) { + fn(); + } +}; +function tick() { + if (frame) { + return; + } + const now2 = Date.now(); + const elapsed = now2 - last; + if (time + elapsed < targetTimePerFrame) { + frame = requestAnimationFrame(() => { + frame = void 0; + tick(); + }); + return; + } + frame = requestAnimationFrame(() => { + frame = void 0; + last = now2; + time = Math.min(time + elapsed - targetTimePerFrame, targetTimePerFrame * 10); + flush(); + }); +} +let started = false; +function throttleToNextFrame$1(fn) { + if (isTest$1()) { + fn(); + return () => { + }; + } + if (!fpsQueue.includes(fn)) { + fpsQueue.push(fn); + if (!started) { + started = true; + last = Date.now() - targetTimePerFrame - 1; + } + tick(); + } + return () => { + const index2 = fpsQueue.indexOf(fn); + if (index2 > -1) { + fpsQueue.splice(index2, 1); + } + }; +} +class Timers { + constructor() { + __publicField(this, "timeouts", /* @__PURE__ */ new Map()); + __publicField(this, "intervals", /* @__PURE__ */ new Map()); + __publicField(this, "rafs", /* @__PURE__ */ new Map()); + this.setTimeout = this.setTimeout.bind(this); + this.setInterval = this.setInterval.bind(this); + this.requestAnimationFrame = this.requestAnimationFrame.bind(this); + this.dispose = this.dispose.bind(this); + } + /** @public */ + setTimeout(contextId, handler, timeout, ...args) { + const id2 = window.setTimeout(handler, timeout, args); + const current = this.timeouts.get(contextId) ?? []; + this.timeouts.set(contextId, [...current, id2]); + return id2; + } + /** @public */ + setInterval(contextId, handler, timeout, ...args) { + const id2 = window.setInterval(handler, timeout, args); + const current = this.intervals.get(contextId) ?? []; + this.intervals.set(contextId, [...current, id2]); + return id2; + } + /** @public */ + requestAnimationFrame(contextId, callback) { + const id2 = window.requestAnimationFrame(callback); + const current = this.rafs.get(contextId) ?? []; + this.rafs.set(contextId, [...current, id2]); + return id2; + } + /** @public */ + dispose(contextId) { + var _a3, _b2, _c2; + (_a3 = this.timeouts.get(contextId)) == null ? void 0 : _a3.forEach((id2) => clearTimeout(id2)); + (_b2 = this.intervals.get(contextId)) == null ? void 0 : _b2.forEach((id2) => clearInterval(id2)); + (_c2 = this.rafs.get(contextId)) == null ? void 0 : _c2.forEach((id2) => cancelAnimationFrame(id2)); + this.timeouts.delete(contextId); + this.intervals.delete(contextId); + this.rafs.delete(contextId); + } + disposeAll() { + for (const contextId of this.timeouts.keys()) { + this.dispose(contextId); + } + } + forContext(contextId) { + return { + setTimeout: (handler, timeout, ...args) => this.setTimeout(contextId, handler, timeout, args), + setInterval: (handler, timeout, ...args) => this.setInterval(contextId, handler, timeout, args), + requestAnimationFrame: (callback) => this.requestAnimationFrame(contextId, callback), + dispose: () => this.dispose(contextId) + }; + } +} +const safeParseUrl = (url, baseUrl) => { + try { + return new URL(url, baseUrl); + } catch { + return; + } +}; +function isDefined(value) { + return value !== void 0; +} +function getStructuredClone() { + if (typeof globalThis !== "undefined" && globalThis.structuredClone) { + return [globalThis.structuredClone, true]; + } + if (typeof global !== "undefined" && global.structuredClone) { + return [global.structuredClone, true]; + } + if (typeof window !== "undefined" && window.structuredClone) { + return [window.structuredClone, true]; + } + return [(i2) => i2 ? JSON.parse(JSON.stringify(i2)) : i2, false]; +} +const _structuredClone = getStructuredClone(); +const structuredClone = _structuredClone[0]; +_structuredClone[1]; +const STRUCTURED_CLONE_OBJECT_PROTOTYPE = Object.getPrototypeOf(structuredClone({})); +registerTldrawLibraryVersion( + "@tldraw/utils", + "3.4.1", + "esm" +); +var check = function(it) { + return it && it.Math === Math && it; +}; +var globalThis_1 = ( + // eslint-disable-next-line es/no-global-this -- safe + check(typeof globalThis == "object" && globalThis) || check(typeof window == "object" && window) || // eslint-disable-next-line no-restricted-globals -- safe + check(typeof self == "object" && self) || check(typeof commonjsGlobal == "object" && commonjsGlobal) || check(typeof commonjsGlobal == "object" && commonjsGlobal) || // eslint-disable-next-line no-new-func -- fallback + /* @__PURE__ */ function() { + return this; + }() || Function("return this")() +); +var objectGetOwnPropertyDescriptor = {}; +var fails$f = function(exec2) { + try { + return !!exec2(); + } catch (error) { + return true; + } +}; +var fails$e = fails$f; +var descriptors = !fails$e(function() { + return Object.defineProperty({}, 1, { get: function() { + return 7; + } })[1] !== 7; +}); +var fails$d = fails$f; +var functionBindNative = !fails$d(function() { + var test3 = (function() { + }).bind(); + return typeof test3 != "function" || test3.hasOwnProperty("prototype"); +}); +var NATIVE_BIND$3 = functionBindNative; +var call$c = Function.prototype.call; +var functionCall = NATIVE_BIND$3 ? call$c.bind(call$c) : function() { + return call$c.apply(call$c, arguments); +}; +var objectPropertyIsEnumerable = {}; +var $propertyIsEnumerable = {}.propertyIsEnumerable; +var getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor; +var NASHORN_BUG = getOwnPropertyDescriptor$1 && !$propertyIsEnumerable.call({ 1: 2 }, 1); +objectPropertyIsEnumerable.f = NASHORN_BUG ? function propertyIsEnumerable(V2) { + var descriptor = getOwnPropertyDescriptor$1(this, V2); + return !!descriptor && descriptor.enumerable; +} : $propertyIsEnumerable; +var createPropertyDescriptor$2 = function(bitmap, value) { + return { + enumerable: !(bitmap & 1), + configurable: !(bitmap & 2), + writable: !(bitmap & 4), + value + }; +}; +var NATIVE_BIND$2 = functionBindNative; +var FunctionPrototype$2 = Function.prototype; +var call$b = FunctionPrototype$2.call; +var uncurryThisWithBind = NATIVE_BIND$2 && FunctionPrototype$2.bind.bind(call$b, call$b); +var functionUncurryThis = NATIVE_BIND$2 ? uncurryThisWithBind : function(fn) { + return function() { + return call$b.apply(fn, arguments); + }; +}; +var uncurryThis$i = functionUncurryThis; +var toString$7 = uncurryThis$i({}.toString); +var stringSlice$6 = uncurryThis$i("".slice); +var classofRaw$2 = function(it) { + return stringSlice$6(toString$7(it), 8, -1); +}; +var uncurryThis$h = functionUncurryThis; +var fails$c = fails$f; +var classof$6 = classofRaw$2; +var $Object$3 = Object; +var split = uncurryThis$h("".split); +var indexedObject = fails$c(function() { + return !$Object$3("z").propertyIsEnumerable(0); +}) ? function(it) { + return classof$6(it) === "String" ? split(it, "") : $Object$3(it); +} : $Object$3; +var isNullOrUndefined$4 = function(it) { + return it === null || it === void 0; +}; +var isNullOrUndefined$3 = isNullOrUndefined$4; +var $TypeError$8 = TypeError; +var requireObjectCoercible$6 = function(it) { + if (isNullOrUndefined$3(it)) throw new $TypeError$8("Can't call method on " + it); + return it; +}; +var IndexedObject = indexedObject; +var requireObjectCoercible$5 = requireObjectCoercible$6; +var toIndexedObject$4 = function(it) { + return IndexedObject(requireObjectCoercible$5(it)); +}; +var documentAll = typeof document == "object" && document.all; +var isCallable$f = typeof documentAll == "undefined" && documentAll !== void 0 ? function(argument) { + return typeof argument == "function" || argument === documentAll; +} : function(argument) { + return typeof argument == "function"; +}; +var isCallable$e = isCallable$f; +var isObject$7 = function(it) { + return typeof it == "object" ? it !== null : isCallable$e(it); +}; +var globalThis$f = globalThis_1; +var isCallable$d = isCallable$f; +var aFunction = function(argument) { + return isCallable$d(argument) ? argument : void 0; +}; +var getBuiltIn$4 = function(namespace, method) { + return arguments.length < 2 ? aFunction(globalThis$f[namespace]) : globalThis$f[namespace] && globalThis$f[namespace][method]; +}; +var uncurryThis$g = functionUncurryThis; +var objectIsPrototypeOf = uncurryThis$g({}.isPrototypeOf); +var globalThis$e = globalThis_1; +var navigator$1 = globalThis$e.navigator; +var userAgent$1 = navigator$1 && navigator$1.userAgent; +var environmentUserAgent = userAgent$1 ? String(userAgent$1) : ""; +var globalThis$d = globalThis_1; +var userAgent = environmentUserAgent; +var process$1 = globalThis$d.process; +var Deno = globalThis$d.Deno; +var versions = process$1 && process$1.versions || Deno && Deno.version; +var v8 = versions && versions.v8; +var match, version$1; +if (v8) { + match = v8.split("."); + version$1 = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]); +} +if (!version$1 && userAgent) { + match = userAgent.match(/Edge\/(\d+)/); + if (!match || match[1] >= 74) { + match = userAgent.match(/Chrome\/(\d+)/); + if (match) version$1 = +match[1]; + } +} +var environmentV8Version = version$1; +var V8_VERSION = environmentV8Version; +var fails$b = fails$f; +var globalThis$c = globalThis_1; +var $String$4 = globalThis$c.String; +var symbolConstructorDetection = !!Object.getOwnPropertySymbols && !fails$b(function() { + var symbol = Symbol("symbol detection"); + return !$String$4(symbol) || !(Object(symbol) instanceof Symbol) || // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances + !Symbol.sham && V8_VERSION && V8_VERSION < 41; +}); +var NATIVE_SYMBOL$1 = symbolConstructorDetection; +var useSymbolAsUid = NATIVE_SYMBOL$1 && !Symbol.sham && typeof Symbol.iterator == "symbol"; +var getBuiltIn$3 = getBuiltIn$4; +var isCallable$c = isCallable$f; +var isPrototypeOf$1 = objectIsPrototypeOf; +var USE_SYMBOL_AS_UID$1 = useSymbolAsUid; +var $Object$2 = Object; +var isSymbol$2 = USE_SYMBOL_AS_UID$1 ? function(it) { + return typeof it == "symbol"; +} : function(it) { + var $Symbol = getBuiltIn$3("Symbol"); + return isCallable$c($Symbol) && isPrototypeOf$1($Symbol.prototype, $Object$2(it)); +}; +var $String$3 = String; +var tryToString$1 = function(argument) { + try { + return $String$3(argument); + } catch (error) { + return "Object"; + } +}; +var isCallable$b = isCallable$f; +var tryToString = tryToString$1; +var $TypeError$7 = TypeError; +var aCallable$3 = function(argument) { + if (isCallable$b(argument)) return argument; + throw new $TypeError$7(tryToString(argument) + " is not a function"); +}; +var aCallable$2 = aCallable$3; +var isNullOrUndefined$2 = isNullOrUndefined$4; +var getMethod$4 = function(V2, P2) { + var func = V2[P2]; + return isNullOrUndefined$2(func) ? void 0 : aCallable$2(func); +}; +var call$a = functionCall; +var isCallable$a = isCallable$f; +var isObject$6 = isObject$7; +var $TypeError$6 = TypeError; +var ordinaryToPrimitive$1 = function(input, pref) { + var fn, val; + if (pref === "string" && isCallable$a(fn = input.toString) && !isObject$6(val = call$a(fn, input))) return val; + if (isCallable$a(fn = input.valueOf) && !isObject$6(val = call$a(fn, input))) return val; + if (pref !== "string" && isCallable$a(fn = input.toString) && !isObject$6(val = call$a(fn, input))) return val; + throw new $TypeError$6("Can't convert object to primitive value"); +}; +var sharedStore = { exports: {} }; +var globalThis$b = globalThis_1; +var defineProperty$2 = Object.defineProperty; +var defineGlobalProperty$3 = function(key, value) { + try { + defineProperty$2(globalThis$b, key, { value, configurable: true, writable: true }); + } catch (error) { + globalThis$b[key] = value; + } + return value; +}; +var globalThis$a = globalThis_1; +var defineGlobalProperty$2 = defineGlobalProperty$3; +var SHARED = "__core-js_shared__"; +var store$3 = sharedStore.exports = globalThis$a[SHARED] || defineGlobalProperty$2(SHARED, {}); +(store$3.versions || (store$3.versions = [])).push({ + version: "3.39.0", + mode: "global", + copyright: "© 2014-2024 Denis Pushkarev (zloirock.ru)", + license: "https://github.com/zloirock/core-js/blob/v3.39.0/LICENSE", + source: "https://github.com/zloirock/core-js" +}); +var sharedStoreExports = sharedStore.exports; +var store$2 = sharedStoreExports; +var shared$4 = function(key, value) { + return store$2[key] || (store$2[key] = value || {}); +}; +var requireObjectCoercible$4 = requireObjectCoercible$6; +var $Object$1 = Object; +var toObject$5 = function(argument) { + return $Object$1(requireObjectCoercible$4(argument)); +}; +var uncurryThis$f = functionUncurryThis; +var toObject$4 = toObject$5; +var hasOwnProperty = uncurryThis$f({}.hasOwnProperty); +var hasOwnProperty_1 = Object.hasOwn || function hasOwn(it, key) { + return hasOwnProperty(toObject$4(it), key); +}; +var uncurryThis$e = functionUncurryThis; +var id = 0; +var postfix = Math.random(); +var toString$6 = uncurryThis$e(1 .toString); +var uid$2 = function(key) { + return "Symbol(" + (key === void 0 ? "" : key) + ")_" + toString$6(++id + postfix, 36); +}; +var globalThis$9 = globalThis_1; +var shared$3 = shared$4; +var hasOwn$7 = hasOwnProperty_1; +var uid$1 = uid$2; +var NATIVE_SYMBOL = symbolConstructorDetection; +var USE_SYMBOL_AS_UID = useSymbolAsUid; +var Symbol$1 = globalThis$9.Symbol; +var WellKnownSymbolsStore = shared$3("wks"); +var createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol$1["for"] || Symbol$1 : Symbol$1 && Symbol$1.withoutSetter || uid$1; +var wellKnownSymbol$9 = function(name) { + if (!hasOwn$7(WellKnownSymbolsStore, name)) { + WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn$7(Symbol$1, name) ? Symbol$1[name] : createWellKnownSymbol("Symbol." + name); + } + return WellKnownSymbolsStore[name]; +}; +var call$9 = functionCall; +var isObject$5 = isObject$7; +var isSymbol$1 = isSymbol$2; +var getMethod$3 = getMethod$4; +var ordinaryToPrimitive = ordinaryToPrimitive$1; +var wellKnownSymbol$8 = wellKnownSymbol$9; +var $TypeError$5 = TypeError; +var TO_PRIMITIVE = wellKnownSymbol$8("toPrimitive"); +var toPrimitive$1 = function(input, pref) { + if (!isObject$5(input) || isSymbol$1(input)) return input; + var exoticToPrim = getMethod$3(input, TO_PRIMITIVE); + var result; + if (exoticToPrim) { + if (pref === void 0) pref = "default"; + result = call$9(exoticToPrim, input, pref); + if (!isObject$5(result) || isSymbol$1(result)) return result; + throw new $TypeError$5("Can't convert object to primitive value"); + } + if (pref === void 0) pref = "number"; + return ordinaryToPrimitive(input, pref); +}; +var toPrimitive = toPrimitive$1; +var isSymbol = isSymbol$2; +var toPropertyKey$2 = function(argument) { + var key = toPrimitive(argument, "string"); + return isSymbol(key) ? key : key + ""; +}; +var globalThis$8 = globalThis_1; +var isObject$4 = isObject$7; +var document$1 = globalThis$8.document; +var EXISTS$1 = isObject$4(document$1) && isObject$4(document$1.createElement); +var documentCreateElement$1 = function(it) { + return EXISTS$1 ? document$1.createElement(it) : {}; +}; +var DESCRIPTORS$7 = descriptors; +var fails$a = fails$f; +var createElement = documentCreateElement$1; +var ie8DomDefine = !DESCRIPTORS$7 && !fails$a(function() { + return Object.defineProperty(createElement("div"), "a", { + get: function() { + return 7; + } + }).a !== 7; +}); +var DESCRIPTORS$6 = descriptors; +var call$8 = functionCall; +var propertyIsEnumerableModule = objectPropertyIsEnumerable; +var createPropertyDescriptor$1 = createPropertyDescriptor$2; +var toIndexedObject$3 = toIndexedObject$4; +var toPropertyKey$1 = toPropertyKey$2; +var hasOwn$6 = hasOwnProperty_1; +var IE8_DOM_DEFINE$1 = ie8DomDefine; +var $getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor; +objectGetOwnPropertyDescriptor.f = DESCRIPTORS$6 ? $getOwnPropertyDescriptor$1 : function getOwnPropertyDescriptor(O2, P2) { + O2 = toIndexedObject$3(O2); + P2 = toPropertyKey$1(P2); + if (IE8_DOM_DEFINE$1) try { + return $getOwnPropertyDescriptor$1(O2, P2); + } catch (error) { + } + if (hasOwn$6(O2, P2)) return createPropertyDescriptor$1(!call$8(propertyIsEnumerableModule.f, O2, P2), O2[P2]); +}; +var objectDefineProperty = {}; +var DESCRIPTORS$5 = descriptors; +var fails$9 = fails$f; +var v8PrototypeDefineBug = DESCRIPTORS$5 && fails$9(function() { + return Object.defineProperty(function() { + }, "prototype", { + value: 42, + writable: false + }).prototype !== 42; +}); +var isObject$3 = isObject$7; +var $String$2 = String; +var $TypeError$4 = TypeError; +var anObject$7 = function(argument) { + if (isObject$3(argument)) return argument; + throw new $TypeError$4($String$2(argument) + " is not an object"); +}; +var DESCRIPTORS$4 = descriptors; +var IE8_DOM_DEFINE = ie8DomDefine; +var V8_PROTOTYPE_DEFINE_BUG$1 = v8PrototypeDefineBug; +var anObject$6 = anObject$7; +var toPropertyKey = toPropertyKey$2; +var $TypeError$3 = TypeError; +var $defineProperty = Object.defineProperty; +var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; +var ENUMERABLE = "enumerable"; +var CONFIGURABLE$1 = "configurable"; +var WRITABLE = "writable"; +objectDefineProperty.f = DESCRIPTORS$4 ? V8_PROTOTYPE_DEFINE_BUG$1 ? function defineProperty(O2, P2, Attributes) { + anObject$6(O2); + P2 = toPropertyKey(P2); + anObject$6(Attributes); + if (typeof O2 === "function" && P2 === "prototype" && "value" in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) { + var current = $getOwnPropertyDescriptor(O2, P2); + if (current && current[WRITABLE]) { + O2[P2] = Attributes.value; + Attributes = { + configurable: CONFIGURABLE$1 in Attributes ? Attributes[CONFIGURABLE$1] : current[CONFIGURABLE$1], + enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE], + writable: false + }; + } + } + return $defineProperty(O2, P2, Attributes); +} : $defineProperty : function defineProperty2(O2, P2, Attributes) { + anObject$6(O2); + P2 = toPropertyKey(P2); + anObject$6(Attributes); + if (IE8_DOM_DEFINE) try { + return $defineProperty(O2, P2, Attributes); + } catch (error) { + } + if ("get" in Attributes || "set" in Attributes) throw new $TypeError$3("Accessors not supported"); + if ("value" in Attributes) O2[P2] = Attributes.value; + return O2; +}; +var DESCRIPTORS$3 = descriptors; +var definePropertyModule$3 = objectDefineProperty; +var createPropertyDescriptor = createPropertyDescriptor$2; +var createNonEnumerableProperty$3 = DESCRIPTORS$3 ? function(object2, key, value) { + return definePropertyModule$3.f(object2, key, createPropertyDescriptor(1, value)); +} : function(object2, key, value) { + object2[key] = value; + return object2; +}; +var makeBuiltIn$2 = { exports: {} }; +var DESCRIPTORS$2 = descriptors; +var hasOwn$5 = hasOwnProperty_1; +var FunctionPrototype$1 = Function.prototype; +var getDescriptor = DESCRIPTORS$2 && Object.getOwnPropertyDescriptor; +var EXISTS = hasOwn$5(FunctionPrototype$1, "name"); +var PROPER = EXISTS && (function something() { +}).name === "something"; +var CONFIGURABLE = EXISTS && (!DESCRIPTORS$2 || DESCRIPTORS$2 && getDescriptor(FunctionPrototype$1, "name").configurable); +var functionName = { + EXISTS, + PROPER, + CONFIGURABLE +}; +var uncurryThis$d = functionUncurryThis; +var isCallable$9 = isCallable$f; +var store$1 = sharedStoreExports; +var functionToString = uncurryThis$d(Function.toString); +if (!isCallable$9(store$1.inspectSource)) { + store$1.inspectSource = function(it) { + return functionToString(it); + }; +} +var inspectSource$2 = store$1.inspectSource; +var globalThis$7 = globalThis_1; +var isCallable$8 = isCallable$f; +var WeakMap$2 = globalThis$7.WeakMap; +var weakMapBasicDetection = isCallable$8(WeakMap$2) && /native code/.test(String(WeakMap$2)); +var shared$2 = shared$4; +var uid = uid$2; +var keys = shared$2("keys"); +var sharedKey$2 = function(key) { + return keys[key] || (keys[key] = uid(key)); +}; +var hiddenKeys$4 = {}; +var NATIVE_WEAK_MAP = weakMapBasicDetection; +var globalThis$6 = globalThis_1; +var isObject$2 = isObject$7; +var createNonEnumerableProperty$2 = createNonEnumerableProperty$3; +var hasOwn$4 = hasOwnProperty_1; +var shared$1 = sharedStoreExports; +var sharedKey$1 = sharedKey$2; +var hiddenKeys$3 = hiddenKeys$4; +var OBJECT_ALREADY_INITIALIZED = "Object already initialized"; +var TypeError$1 = globalThis$6.TypeError; +var WeakMap$1 = globalThis$6.WeakMap; +var set, get, has; +var enforce = function(it) { + return has(it) ? get(it) : set(it, {}); +}; +var getterFor = function(TYPE) { + return function(it) { + var state; + if (!isObject$2(it) || (state = get(it)).type !== TYPE) { + throw new TypeError$1("Incompatible receiver, " + TYPE + " required"); + } + return state; + }; +}; +if (NATIVE_WEAK_MAP || shared$1.state) { + var store = shared$1.state || (shared$1.state = new WeakMap$1()); + store.get = store.get; + store.has = store.has; + store.set = store.set; + set = function(it, metadata) { + if (store.has(it)) throw new TypeError$1(OBJECT_ALREADY_INITIALIZED); + metadata.facade = it; + store.set(it, metadata); + return metadata; + }; + get = function(it) { + return store.get(it) || {}; + }; + has = function(it) { + return store.has(it); + }; +} else { + var STATE = sharedKey$1("state"); + hiddenKeys$3[STATE] = true; + set = function(it, metadata) { + if (hasOwn$4(it, STATE)) throw new TypeError$1(OBJECT_ALREADY_INITIALIZED); + metadata.facade = it; + createNonEnumerableProperty$2(it, STATE, metadata); + return metadata; + }; + get = function(it) { + return hasOwn$4(it, STATE) ? it[STATE] : {}; + }; + has = function(it) { + return hasOwn$4(it, STATE); + }; +} +var internalState = { + set, + get, + has, + enforce, + getterFor +}; +var uncurryThis$c = functionUncurryThis; +var fails$8 = fails$f; +var isCallable$7 = isCallable$f; +var hasOwn$3 = hasOwnProperty_1; +var DESCRIPTORS$1 = descriptors; +var CONFIGURABLE_FUNCTION_NAME = functionName.CONFIGURABLE; +var inspectSource$1 = inspectSource$2; +var InternalStateModule = internalState; +var enforceInternalState = InternalStateModule.enforce; +var getInternalState$1 = InternalStateModule.get; +var $String$1 = String; +var defineProperty$1 = Object.defineProperty; +var stringSlice$5 = uncurryThis$c("".slice); +var replace$3 = uncurryThis$c("".replace); +var join = uncurryThis$c([].join); +var CONFIGURABLE_LENGTH = DESCRIPTORS$1 && !fails$8(function() { + return defineProperty$1(function() { + }, "length", { value: 8 }).length !== 8; +}); +var TEMPLATE = String(String).split("String"); +var makeBuiltIn$1 = makeBuiltIn$2.exports = function(value, name, options) { + if (stringSlice$5($String$1(name), 0, 7) === "Symbol(") { + name = "[" + replace$3($String$1(name), /^Symbol\(([^)]*)\).*$/, "$1") + "]"; + } + if (options && options.getter) name = "get " + name; + if (options && options.setter) name = "set " + name; + if (!hasOwn$3(value, "name") || CONFIGURABLE_FUNCTION_NAME && value.name !== name) { + if (DESCRIPTORS$1) defineProperty$1(value, "name", { value: name, configurable: true }); + else value.name = name; + } + if (CONFIGURABLE_LENGTH && options && hasOwn$3(options, "arity") && value.length !== options.arity) { + defineProperty$1(value, "length", { value: options.arity }); + } + try { + if (options && hasOwn$3(options, "constructor") && options.constructor) { + if (DESCRIPTORS$1) defineProperty$1(value, "prototype", { writable: false }); + } else if (value.prototype) value.prototype = void 0; + } catch (error) { + } + var state = enforceInternalState(value); + if (!hasOwn$3(state, "source")) { + state.source = join(TEMPLATE, typeof name == "string" ? name : ""); + } + return value; +}; +Function.prototype.toString = makeBuiltIn$1(function toString() { + return isCallable$7(this) && getInternalState$1(this).source || inspectSource$1(this); +}, "toString"); +var makeBuiltInExports = makeBuiltIn$2.exports; +var isCallable$6 = isCallable$f; +var definePropertyModule$2 = objectDefineProperty; +var makeBuiltIn = makeBuiltInExports; +var defineGlobalProperty$1 = defineGlobalProperty$3; +var defineBuiltIn$2 = function(O2, key, value, options) { + if (!options) options = {}; + var simple = options.enumerable; + var name = options.name !== void 0 ? options.name : key; + if (isCallable$6(value)) makeBuiltIn(value, name, options); + if (options.global) { + if (simple) O2[key] = value; + else defineGlobalProperty$1(key, value); + } else { + try { + if (!options.unsafe) delete O2[key]; + else if (O2[key]) simple = true; + } catch (error) { + } + if (simple) O2[key] = value; + else definePropertyModule$2.f(O2, key, { + value, + enumerable: false, + configurable: !options.nonConfigurable, + writable: !options.nonWritable + }); + } + return O2; +}; +var objectGetOwnPropertyNames = {}; +var ceil = Math.ceil; +var floor$2 = Math.floor; +var mathTrunc = Math.trunc || function trunc(x2) { + var n = +x2; + return (n > 0 ? floor$2 : ceil)(n); +}; +var trunc2 = mathTrunc; +var toIntegerOrInfinity$7 = function(argument) { + var number2 = +argument; + return number2 !== number2 || number2 === 0 ? 0 : trunc2(number2); +}; +var toIntegerOrInfinity$6 = toIntegerOrInfinity$7; +var max$3 = Math.max; +var min$4 = Math.min; +var toAbsoluteIndex$1 = function(index2, length) { + var integer2 = toIntegerOrInfinity$6(index2); + return integer2 < 0 ? max$3(integer2 + length, 0) : min$4(integer2, length); +}; +var toIntegerOrInfinity$5 = toIntegerOrInfinity$7; +var min$3 = Math.min; +var toLength$2 = function(argument) { + var len = toIntegerOrInfinity$5(argument); + return len > 0 ? min$3(len, 9007199254740991) : 0; +}; +var toLength$1 = toLength$2; +var lengthOfArrayLike$5 = function(obj) { + return toLength$1(obj.length); +}; +var toIndexedObject$2 = toIndexedObject$4; +var toAbsoluteIndex = toAbsoluteIndex$1; +var lengthOfArrayLike$4 = lengthOfArrayLike$5; +var createMethod$1 = function(IS_INCLUDES) { + return function($this, el, fromIndex) { + var O2 = toIndexedObject$2($this); + var length = lengthOfArrayLike$4(O2); + if (length === 0) return !IS_INCLUDES && -1; + var index2 = toAbsoluteIndex(fromIndex, length); + var value; + if (IS_INCLUDES && el !== el) while (length > index2) { + value = O2[index2++]; + if (value !== value) return true; + } + else for (; length > index2; index2++) { + if ((IS_INCLUDES || index2 in O2) && O2[index2] === el) return IS_INCLUDES || index2 || 0; + } + return !IS_INCLUDES && -1; + }; +}; +var arrayIncludes = { + // `Array.prototype.includes` method + // https://tc39.es/ecma262/#sec-array.prototype.includes + includes: createMethod$1(true), + // `Array.prototype.indexOf` method + // https://tc39.es/ecma262/#sec-array.prototype.indexof + indexOf: createMethod$1(false) +}; +var uncurryThis$b = functionUncurryThis; +var hasOwn$2 = hasOwnProperty_1; +var toIndexedObject$1 = toIndexedObject$4; +var indexOf$2 = arrayIncludes.indexOf; +var hiddenKeys$2 = hiddenKeys$4; +var push$1 = uncurryThis$b([].push); +var objectKeysInternal = function(object2, names) { + var O2 = toIndexedObject$1(object2); + var i2 = 0; + var result = []; + var key; + for (key in O2) !hasOwn$2(hiddenKeys$2, key) && hasOwn$2(O2, key) && push$1(result, key); + while (names.length > i2) if (hasOwn$2(O2, key = names[i2++])) { + ~indexOf$2(result, key) || push$1(result, key); + } + return result; +}; +var enumBugKeys$3 = [ + "constructor", + "hasOwnProperty", + "isPrototypeOf", + "propertyIsEnumerable", + "toLocaleString", + "toString", + "valueOf" +]; +var internalObjectKeys$1 = objectKeysInternal; +var enumBugKeys$2 = enumBugKeys$3; +var hiddenKeys$1 = enumBugKeys$2.concat("length", "prototype"); +objectGetOwnPropertyNames.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O2) { + return internalObjectKeys$1(O2, hiddenKeys$1); +}; +var objectGetOwnPropertySymbols = {}; +objectGetOwnPropertySymbols.f = Object.getOwnPropertySymbols; +var getBuiltIn$2 = getBuiltIn$4; +var uncurryThis$a = functionUncurryThis; +var getOwnPropertyNamesModule = objectGetOwnPropertyNames; +var getOwnPropertySymbolsModule = objectGetOwnPropertySymbols; +var anObject$5 = anObject$7; +var concat$1 = uncurryThis$a([].concat); +var ownKeys$3 = getBuiltIn$2("Reflect", "ownKeys") || function ownKeys(it) { + var keys3 = getOwnPropertyNamesModule.f(anObject$5(it)); + var getOwnPropertySymbols = getOwnPropertySymbolsModule.f; + return getOwnPropertySymbols ? concat$1(keys3, getOwnPropertySymbols(it)) : keys3; +}; +var hasOwn$1 = hasOwnProperty_1; +var ownKeys$2 = ownKeys$3; +var getOwnPropertyDescriptorModule = objectGetOwnPropertyDescriptor; +var definePropertyModule$1 = objectDefineProperty; +var copyConstructorProperties$1 = function(target, source, exceptions) { + var keys3 = ownKeys$2(source); + var defineProperty4 = definePropertyModule$1.f; + var getOwnPropertyDescriptor3 = getOwnPropertyDescriptorModule.f; + for (var i2 = 0; i2 < keys3.length; i2++) { + var key = keys3[i2]; + if (!hasOwn$1(target, key) && !(exceptions && hasOwn$1(exceptions, key))) { + defineProperty4(target, key, getOwnPropertyDescriptor3(source, key)); + } + } +}; +var fails$7 = fails$f; +var isCallable$5 = isCallable$f; +var replacement = /#|\.prototype\./; +var isForced$1 = function(feature, detection) { + var value = data[normalize(feature)]; + return value === POLYFILL ? true : value === NATIVE ? false : isCallable$5(detection) ? fails$7(detection) : !!detection; +}; +var normalize = isForced$1.normalize = function(string2) { + return String(string2).replace(replacement, ".").toLowerCase(); +}; +var data = isForced$1.data = {}; +var NATIVE = isForced$1.NATIVE = "N"; +var POLYFILL = isForced$1.POLYFILL = "P"; +var isForced_1 = isForced$1; +var globalThis$5 = globalThis_1; +var getOwnPropertyDescriptor2 = objectGetOwnPropertyDescriptor.f; +var createNonEnumerableProperty$1 = createNonEnumerableProperty$3; +var defineBuiltIn$1 = defineBuiltIn$2; +var defineGlobalProperty = defineGlobalProperty$3; +var copyConstructorProperties = copyConstructorProperties$1; +var isForced = isForced_1; +var _export = function(options, source) { + var TARGET = options.target; + var GLOBAL = options.global; + var STATIC = options.stat; + var FORCED2, target, key, targetProperty, sourceProperty, descriptor; + if (GLOBAL) { + target = globalThis$5; + } else if (STATIC) { + target = globalThis$5[TARGET] || defineGlobalProperty(TARGET, {}); + } else { + target = globalThis$5[TARGET] && globalThis$5[TARGET].prototype; + } + if (target) for (key in source) { + sourceProperty = source[key]; + if (options.dontCallGetSet) { + descriptor = getOwnPropertyDescriptor2(target, key); + targetProperty = descriptor && descriptor.value; + } else targetProperty = target[key]; + FORCED2 = isForced(GLOBAL ? key : TARGET + (STATIC ? "." : "#") + key, options.forced); + if (!FORCED2 && targetProperty !== void 0) { + if (typeof sourceProperty == typeof targetProperty) continue; + copyConstructorProperties(sourceProperty, targetProperty); + } + if (options.sham || targetProperty && targetProperty.sham) { + createNonEnumerableProperty$1(sourceProperty, "sham", true); + } + defineBuiltIn$1(target, key, sourceProperty, options); + } +}; +var objectDefineProperties = {}; +var internalObjectKeys = objectKeysInternal; +var enumBugKeys$1 = enumBugKeys$3; +var objectKeys$1 = Object.keys || function keys2(O2) { + return internalObjectKeys(O2, enumBugKeys$1); +}; +var DESCRIPTORS = descriptors; +var V8_PROTOTYPE_DEFINE_BUG = v8PrototypeDefineBug; +var definePropertyModule = objectDefineProperty; +var anObject$4 = anObject$7; +var toIndexedObject = toIndexedObject$4; +var objectKeys = objectKeys$1; +objectDefineProperties.f = DESCRIPTORS && !V8_PROTOTYPE_DEFINE_BUG ? Object.defineProperties : function defineProperties(O2, Properties) { + anObject$4(O2); + var props = toIndexedObject(Properties); + var keys3 = objectKeys(Properties); + var length = keys3.length; + var index2 = 0; + var key; + while (length > index2) definePropertyModule.f(O2, key = keys3[index2++], props[key]); + return O2; +}; +var getBuiltIn$1 = getBuiltIn$4; +var html$1 = getBuiltIn$1("document", "documentElement"); +var anObject$3 = anObject$7; +var definePropertiesModule = objectDefineProperties; +var enumBugKeys = enumBugKeys$3; +var hiddenKeys = hiddenKeys$4; +var html = html$1; +var documentCreateElement = documentCreateElement$1; +var sharedKey = sharedKey$2; +var GT = ">"; +var LT = "<"; +var PROTOTYPE = "prototype"; +var SCRIPT = "script"; +var IE_PROTO = sharedKey("IE_PROTO"); +var EmptyConstructor = function() { +}; +var scriptTag = function(content) { + return LT + SCRIPT + GT + content + LT + "/" + SCRIPT + GT; +}; +var NullProtoObjectViaActiveX = function(activeXDocument2) { + activeXDocument2.write(scriptTag("")); + activeXDocument2.close(); + var temp = activeXDocument2.parentWindow.Object; + activeXDocument2 = null; + return temp; +}; +var NullProtoObjectViaIFrame = function() { + var iframe = documentCreateElement("iframe"); + var JS = "java" + SCRIPT + ":"; + var iframeDocument; + iframe.style.display = "none"; + html.appendChild(iframe); + iframe.src = String(JS); + iframeDocument = iframe.contentWindow.document; + iframeDocument.open(); + iframeDocument.write(scriptTag("document.F=Object")); + iframeDocument.close(); + return iframeDocument.F; +}; +var activeXDocument; +var NullProtoObject = function() { + try { + activeXDocument = new ActiveXObject("htmlfile"); + } catch (error) { + } + NullProtoObject = typeof document != "undefined" ? document.domain && activeXDocument ? NullProtoObjectViaActiveX(activeXDocument) : NullProtoObjectViaIFrame() : NullProtoObjectViaActiveX(activeXDocument); + var length = enumBugKeys.length; + while (length--) delete NullProtoObject[PROTOTYPE][enumBugKeys[length]]; + return NullProtoObject(); +}; +hiddenKeys[IE_PROTO] = true; +var objectCreate = Object.create || function create(O2, Properties) { + var result; + if (O2 !== null) { + EmptyConstructor[PROTOTYPE] = anObject$3(O2); + result = new EmptyConstructor(); + EmptyConstructor[PROTOTYPE] = null; + result[IE_PROTO] = O2; + } else result = NullProtoObject(); + return Properties === void 0 ? result : definePropertiesModule.f(result, Properties); +}; +var wellKnownSymbol$7 = wellKnownSymbol$9; +var create$1 = objectCreate; +var defineProperty3 = objectDefineProperty.f; +var UNSCOPABLES = wellKnownSymbol$7("unscopables"); +var ArrayPrototype = Array.prototype; +if (ArrayPrototype[UNSCOPABLES] === void 0) { + defineProperty3(ArrayPrototype, UNSCOPABLES, { + configurable: true, + value: create$1(null) + }); +} +var addToUnscopables$3 = function(key) { + ArrayPrototype[UNSCOPABLES][key] = true; +}; +var $$6 = _export; +var toObject$3 = toObject$5; +var lengthOfArrayLike$3 = lengthOfArrayLike$5; +var toIntegerOrInfinity$4 = toIntegerOrInfinity$7; +var addToUnscopables$2 = addToUnscopables$3; +$$6({ target: "Array", proto: true }, { + at: function at(index2) { + var O2 = toObject$3(this); + var len = lengthOfArrayLike$3(O2); + var relativeIndex = toIntegerOrInfinity$4(index2); + var k = relativeIndex >= 0 ? relativeIndex : len + relativeIndex; + return k < 0 || k >= len ? void 0 : O2[k]; + } +}); +addToUnscopables$2("at"); +var globalThis$4 = globalThis_1; +var uncurryThis$9 = functionUncurryThis; +var entryUnbind$5 = function(CONSTRUCTOR, METHOD) { + return uncurryThis$9(globalThis$4[CONSTRUCTOR].prototype[METHOD]); +}; +var entryUnbind$4 = entryUnbind$5; +entryUnbind$4("Array", "at"); +var classof$5 = classofRaw$2; +var isArray$2 = Array.isArray || function isArray(argument) { + return classof$5(argument) === "Array"; +}; +var $TypeError$2 = TypeError; +var MAX_SAFE_INTEGER = 9007199254740991; +var doesNotExceedSafeInteger$1 = function(it) { + if (it > MAX_SAFE_INTEGER) throw $TypeError$2("Maximum allowed index exceeded"); + return it; +}; +var classofRaw$1 = classofRaw$2; +var uncurryThis$8 = functionUncurryThis; +var functionUncurryThisClause = function(fn) { + if (classofRaw$1(fn) === "Function") return uncurryThis$8(fn); +}; +var uncurryThis$7 = functionUncurryThisClause; +var aCallable$1 = aCallable$3; +var NATIVE_BIND$1 = functionBindNative; +var bind$1 = uncurryThis$7(uncurryThis$7.bind); +var functionBindContext = function(fn, that) { + aCallable$1(fn); + return that === void 0 ? fn : NATIVE_BIND$1 ? bind$1(fn, that) : function() { + return fn.apply(that, arguments); + }; +}; +var isArray$1 = isArray$2; +var lengthOfArrayLike$2 = lengthOfArrayLike$5; +var doesNotExceedSafeInteger = doesNotExceedSafeInteger$1; +var bind = functionBindContext; +var flattenIntoArray$2 = function(target, original, source, sourceLen, start, depth, mapper, thisArg) { + var targetIndex = start; + var sourceIndex = 0; + var mapFn = mapper ? bind(mapper, thisArg) : false; + var element, elementLen; + while (sourceIndex < sourceLen) { + if (sourceIndex in source) { + element = mapFn ? mapFn(source[sourceIndex], sourceIndex, original) : source[sourceIndex]; + if (depth > 0 && isArray$1(element)) { + elementLen = lengthOfArrayLike$2(element); + targetIndex = flattenIntoArray$2(target, original, element, elementLen, targetIndex, depth - 1) - 1; + } else { + doesNotExceedSafeInteger(targetIndex + 1); + target[targetIndex] = element; + } + targetIndex++; + } + sourceIndex++; + } + return targetIndex; +}; +var flattenIntoArray_1 = flattenIntoArray$2; +var wellKnownSymbol$6 = wellKnownSymbol$9; +var TO_STRING_TAG$1 = wellKnownSymbol$6("toStringTag"); +var test = {}; +test[TO_STRING_TAG$1] = "z"; +var toStringTagSupport = String(test) === "[object z]"; +var TO_STRING_TAG_SUPPORT = toStringTagSupport; +var isCallable$4 = isCallable$f; +var classofRaw = classofRaw$2; +var wellKnownSymbol$5 = wellKnownSymbol$9; +var TO_STRING_TAG = wellKnownSymbol$5("toStringTag"); +var $Object = Object; +var CORRECT_ARGUMENTS = classofRaw(/* @__PURE__ */ function() { + return arguments; +}()) === "Arguments"; +var tryGet = function(it, key) { + try { + return it[key]; + } catch (error) { + } +}; +var classof$4 = TO_STRING_TAG_SUPPORT ? classofRaw : function(it) { + var O2, tag, result; + return it === void 0 ? "Undefined" : it === null ? "Null" : typeof (tag = tryGet(O2 = $Object(it), TO_STRING_TAG)) == "string" ? tag : CORRECT_ARGUMENTS ? classofRaw(O2) : (result = classofRaw(O2)) === "Object" && isCallable$4(O2.callee) ? "Arguments" : result; +}; +var uncurryThis$6 = functionUncurryThis; +var fails$6 = fails$f; +var isCallable$3 = isCallable$f; +var classof$3 = classof$4; +var getBuiltIn = getBuiltIn$4; +var inspectSource = inspectSource$2; +var noop$1 = function() { +}; +var construct = getBuiltIn("Reflect", "construct"); +var constructorRegExp = /^\s*(?:class|function)\b/; +var exec$1 = uncurryThis$6(constructorRegExp.exec); +var INCORRECT_TO_STRING = !constructorRegExp.test(noop$1); +var isConstructorModern = function isConstructor(argument) { + if (!isCallable$3(argument)) return false; + try { + construct(noop$1, [], argument); + return true; + } catch (error) { + return false; + } +}; +var isConstructorLegacy = function isConstructor2(argument) { + if (!isCallable$3(argument)) return false; + switch (classof$3(argument)) { + case "AsyncFunction": + case "GeneratorFunction": + case "AsyncGeneratorFunction": + return false; + } + try { + return INCORRECT_TO_STRING || !!exec$1(constructorRegExp, inspectSource(argument)); + } catch (error) { + return true; + } +}; +isConstructorLegacy.sham = true; +var isConstructor$1 = !construct || fails$6(function() { + var called; + return isConstructorModern(isConstructorModern.call) || !isConstructorModern(Object) || !isConstructorModern(function() { + called = true; + }) || called; +}) ? isConstructorLegacy : isConstructorModern; +var isArray2 = isArray$2; +var isConstructor3 = isConstructor$1; +var isObject$1 = isObject$7; +var wellKnownSymbol$4 = wellKnownSymbol$9; +var SPECIES$1 = wellKnownSymbol$4("species"); +var $Array = Array; +var arraySpeciesConstructor$1 = function(originalArray) { + var C2; + if (isArray2(originalArray)) { + C2 = originalArray.constructor; + if (isConstructor3(C2) && (C2 === $Array || isArray2(C2.prototype))) C2 = void 0; + else if (isObject$1(C2)) { + C2 = C2[SPECIES$1]; + if (C2 === null) C2 = void 0; + } + } + return C2 === void 0 ? $Array : C2; +}; +var arraySpeciesConstructor = arraySpeciesConstructor$1; +var arraySpeciesCreate$2 = function(originalArray, length) { + return new (arraySpeciesConstructor(originalArray))(length === 0 ? 0 : length); +}; +var $$5 = _export; +var flattenIntoArray$1 = flattenIntoArray_1; +var aCallable = aCallable$3; +var toObject$2 = toObject$5; +var lengthOfArrayLike$1 = lengthOfArrayLike$5; +var arraySpeciesCreate$1 = arraySpeciesCreate$2; +$$5({ target: "Array", proto: true }, { + flatMap: function flatMap(callbackfn) { + var O2 = toObject$2(this); + var sourceLen = lengthOfArrayLike$1(O2); + var A; + aCallable(callbackfn); + A = arraySpeciesCreate$1(O2, 0); + A.length = flattenIntoArray$1(A, O2, O2, sourceLen, 0, 1, callbackfn, arguments.length > 1 ? arguments[1] : void 0); + return A; + } +}); +var addToUnscopables$1 = addToUnscopables$3; +addToUnscopables$1("flatMap"); +var entryUnbind$3 = entryUnbind$5; +entryUnbind$3("Array", "flatMap"); +var $$4 = _export; +var flattenIntoArray = flattenIntoArray_1; +var toObject$1 = toObject$5; +var lengthOfArrayLike = lengthOfArrayLike$5; +var toIntegerOrInfinity$3 = toIntegerOrInfinity$7; +var arraySpeciesCreate = arraySpeciesCreate$2; +$$4({ target: "Array", proto: true }, { + flat: function flat() { + var depthArg = arguments.length ? arguments[0] : void 0; + var O2 = toObject$1(this); + var sourceLen = lengthOfArrayLike(O2); + var A = arraySpeciesCreate(O2, 0); + A.length = flattenIntoArray(A, O2, O2, sourceLen, 0, depthArg === void 0 ? 1 : toIntegerOrInfinity$3(depthArg)); + return A; + } +}); +var addToUnscopables = addToUnscopables$3; +addToUnscopables("flat"); +var entryUnbind$2 = entryUnbind$5; +entryUnbind$2("Array", "flat"); +var classof$2 = classof$4; +var $String = String; +var toString$5 = function(argument) { + if (classof$2(argument) === "Symbol") throw new TypeError("Cannot convert a Symbol value to a string"); + return $String(argument); +}; +var $$3 = _export; +var uncurryThis$5 = functionUncurryThis; +var requireObjectCoercible$3 = requireObjectCoercible$6; +var toIntegerOrInfinity$2 = toIntegerOrInfinity$7; +var toString$4 = toString$5; +var fails$5 = fails$f; +var charAt$4 = uncurryThis$5("".charAt); +var FORCED = fails$5(function() { + return "𠮷".at(-2) !== "\uD842"; +}); +$$3({ target: "String", proto: true, forced: FORCED }, { + at: function at2(index2) { + var S2 = toString$4(requireObjectCoercible$3(this)); + var len = S2.length; + var relativeIndex = toIntegerOrInfinity$2(index2); + var k = relativeIndex >= 0 ? relativeIndex : len + relativeIndex; + return k < 0 || k >= len ? void 0 : charAt$4(S2, k); + } +}); +var entryUnbind$1 = entryUnbind$5; +entryUnbind$1("String", "at"); +var anObject$2 = anObject$7; +var regexpFlags$1 = function() { + var that = anObject$2(this); + var result = ""; + if (that.hasIndices) result += "d"; + if (that.global) result += "g"; + if (that.ignoreCase) result += "i"; + if (that.multiline) result += "m"; + if (that.dotAll) result += "s"; + if (that.unicode) result += "u"; + if (that.unicodeSets) result += "v"; + if (that.sticky) result += "y"; + return result; +}; +var fails$4 = fails$f; +var globalThis$3 = globalThis_1; +var $RegExp$2 = globalThis$3.RegExp; +var UNSUPPORTED_Y$1 = fails$4(function() { + var re = $RegExp$2("a", "y"); + re.lastIndex = 2; + return re.exec("abcd") !== null; +}); +var MISSED_STICKY = UNSUPPORTED_Y$1 || fails$4(function() { + return !$RegExp$2("a", "y").sticky; +}); +var BROKEN_CARET = UNSUPPORTED_Y$1 || fails$4(function() { + var re = $RegExp$2("^r", "gy"); + re.lastIndex = 2; + return re.exec("str") !== null; +}); +var regexpStickyHelpers = { + BROKEN_CARET, + MISSED_STICKY, + UNSUPPORTED_Y: UNSUPPORTED_Y$1 +}; +var fails$3 = fails$f; +var globalThis$2 = globalThis_1; +var $RegExp$1 = globalThis$2.RegExp; +var regexpUnsupportedDotAll = fails$3(function() { + var re = $RegExp$1(".", "s"); + return !(re.dotAll && re.test("\n") && re.flags === "s"); +}); +var fails$2 = fails$f; +var globalThis$1 = globalThis_1; +var $RegExp = globalThis$1.RegExp; +var regexpUnsupportedNcg = fails$2(function() { + var re = $RegExp("(?b)", "g"); + return re.exec("b").groups.a !== "b" || "b".replace(re, "$c") !== "bc"; +}); +var call$7 = functionCall; +var uncurryThis$4 = functionUncurryThis; +var toString$3 = toString$5; +var regexpFlags = regexpFlags$1; +var stickyHelpers = regexpStickyHelpers; +var shared = shared$4; +var create2 = objectCreate; +var getInternalState = internalState.get; +var UNSUPPORTED_DOT_ALL = regexpUnsupportedDotAll; +var UNSUPPORTED_NCG = regexpUnsupportedNcg; +var nativeReplace = shared("native-string-replace", String.prototype.replace); +var nativeExec = RegExp.prototype.exec; +var patchedExec = nativeExec; +var charAt$3 = uncurryThis$4("".charAt); +var indexOf$1 = uncurryThis$4("".indexOf); +var replace$2 = uncurryThis$4("".replace); +var stringSlice$4 = uncurryThis$4("".slice); +var UPDATES_LAST_INDEX_WRONG = function() { + var re1 = /a/; + var re2 = /b*/g; + call$7(nativeExec, re1, "a"); + call$7(nativeExec, re2, "a"); + return re1.lastIndex !== 0 || re2.lastIndex !== 0; +}(); +var UNSUPPORTED_Y = stickyHelpers.BROKEN_CARET; +var NPCG_INCLUDED = /()??/.exec("")[1] !== void 0; +var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED || UNSUPPORTED_Y || UNSUPPORTED_DOT_ALL || UNSUPPORTED_NCG; +if (PATCH) { + patchedExec = function exec2(string2) { + var re = this; + var state = getInternalState(re); + var str = toString$3(string2); + var raw = state.raw; + var result, reCopy, lastIndex, match2, i2, object2, group; + if (raw) { + raw.lastIndex = re.lastIndex; + result = call$7(patchedExec, raw, str); + re.lastIndex = raw.lastIndex; + return result; + } + var groups = state.groups; + var sticky = UNSUPPORTED_Y && re.sticky; + var flags = call$7(regexpFlags, re); + var source = re.source; + var charsAdded = 0; + var strCopy = str; + if (sticky) { + flags = replace$2(flags, "y", ""); + if (indexOf$1(flags, "g") === -1) { + flags += "g"; + } + strCopy = stringSlice$4(str, re.lastIndex); + if (re.lastIndex > 0 && (!re.multiline || re.multiline && charAt$3(str, re.lastIndex - 1) !== "\n")) { + source = "(?: " + source + ")"; + strCopy = " " + strCopy; + charsAdded++; + } + reCopy = new RegExp("^(?:" + source + ")", flags); + } + if (NPCG_INCLUDED) { + reCopy = new RegExp("^" + source + "$(?!\\s)", flags); + } + if (UPDATES_LAST_INDEX_WRONG) lastIndex = re.lastIndex; + match2 = call$7(nativeExec, sticky ? reCopy : re, strCopy); + if (sticky) { + if (match2) { + match2.input = stringSlice$4(match2.input, charsAdded); + match2[0] = stringSlice$4(match2[0], charsAdded); + match2.index = re.lastIndex; + re.lastIndex += match2[0].length; + } else re.lastIndex = 0; + } else if (UPDATES_LAST_INDEX_WRONG && match2) { + re.lastIndex = re.global ? match2.index + match2[0].length : lastIndex; + } + if (NPCG_INCLUDED && match2 && match2.length > 1) { + call$7(nativeReplace, match2[0], reCopy, function() { + for (i2 = 1; i2 < arguments.length - 2; i2++) { + if (arguments[i2] === void 0) match2[i2] = void 0; + } + }); + } + if (match2 && groups) { + match2.groups = object2 = create2(null); + for (i2 = 0; i2 < groups.length; i2++) { + group = groups[i2]; + object2[group[0]] = match2[group[1]]; + } + } + return match2; + }; +} +var regexpExec$2 = patchedExec; +var $$2 = _export; +var exec = regexpExec$2; +$$2({ target: "RegExp", proto: true, forced: /./.exec !== exec }, { + exec +}); +var NATIVE_BIND = functionBindNative; +var FunctionPrototype = Function.prototype; +var apply$1 = FunctionPrototype.apply; +var call$6 = FunctionPrototype.call; +var functionApply = typeof Reflect == "object" && Reflect.apply || (NATIVE_BIND ? call$6.bind(apply$1) : function() { + return call$6.apply(apply$1, arguments); +}); +var call$5 = functionCall; +var defineBuiltIn = defineBuiltIn$2; +var regexpExec$1 = regexpExec$2; +var fails$1 = fails$f; +var wellKnownSymbol$3 = wellKnownSymbol$9; +var createNonEnumerableProperty = createNonEnumerableProperty$3; +var SPECIES = wellKnownSymbol$3("species"); +var RegExpPrototype$1 = RegExp.prototype; +var fixRegexpWellKnownSymbolLogic = function(KEY, exec2, FORCED2, SHAM) { + var SYMBOL = wellKnownSymbol$3(KEY); + var DELEGATES_TO_SYMBOL = !fails$1(function() { + var O2 = {}; + O2[SYMBOL] = function() { + return 7; + }; + return ""[KEY](O2) !== 7; + }); + var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL && !fails$1(function() { + var execCalled = false; + var re = /a/; + if (KEY === "split") { + re = {}; + re.constructor = {}; + re.constructor[SPECIES] = function() { + return re; + }; + re.flags = ""; + re[SYMBOL] = /./[SYMBOL]; + } + re.exec = function() { + execCalled = true; + return null; + }; + re[SYMBOL](""); + return !execCalled; + }); + if (!DELEGATES_TO_SYMBOL || !DELEGATES_TO_EXEC || FORCED2) { + var nativeRegExpMethod = /./[SYMBOL]; + var methods = exec2(SYMBOL, ""[KEY], function(nativeMethod, regexp, str, arg2, forceStringMethod) { + var $exec = regexp.exec; + if ($exec === regexpExec$1 || $exec === RegExpPrototype$1.exec) { + if (DELEGATES_TO_SYMBOL && !forceStringMethod) { + return { done: true, value: call$5(nativeRegExpMethod, regexp, str, arg2) }; + } + return { done: true, value: call$5(nativeMethod, str, regexp, arg2) }; + } + return { done: false }; + }); + defineBuiltIn(String.prototype, KEY, methods[0]); + defineBuiltIn(RegExpPrototype$1, SYMBOL, methods[1]); + } + if (SHAM) createNonEnumerableProperty(RegExpPrototype$1[SYMBOL], "sham", true); +}; +var uncurryThis$3 = functionUncurryThis; +var toIntegerOrInfinity$1 = toIntegerOrInfinity$7; +var toString$2 = toString$5; +var requireObjectCoercible$2 = requireObjectCoercible$6; +var charAt$2 = uncurryThis$3("".charAt); +var charCodeAt = uncurryThis$3("".charCodeAt); +var stringSlice$3 = uncurryThis$3("".slice); +var createMethod = function(CONVERT_TO_STRING) { + return function($this, pos) { + var S2 = toString$2(requireObjectCoercible$2($this)); + var position = toIntegerOrInfinity$1(pos); + var size2 = S2.length; + var first, second; + if (position < 0 || position >= size2) return CONVERT_TO_STRING ? "" : void 0; + first = charCodeAt(S2, position); + return first < 55296 || first > 56319 || position + 1 === size2 || (second = charCodeAt(S2, position + 1)) < 56320 || second > 57343 ? CONVERT_TO_STRING ? charAt$2(S2, position) : first : CONVERT_TO_STRING ? stringSlice$3(S2, position, position + 2) : (first - 55296 << 10) + (second - 56320) + 65536; + }; +}; +var stringMultibyte = { + // `String.prototype.codePointAt` method + // https://tc39.es/ecma262/#sec-string.prototype.codepointat + codeAt: createMethod(false), + // `String.prototype.at` method + // https://github.com/mathiasbynens/String.prototype.at + charAt: createMethod(true) +}; +var charAt$1 = stringMultibyte.charAt; +var advanceStringIndex$1 = function(S2, index2, unicode) { + return index2 + (unicode ? charAt$1(S2, index2).length : 1); +}; +var uncurryThis$2 = functionUncurryThis; +var toObject = toObject$5; +var floor$1 = Math.floor; +var charAt = uncurryThis$2("".charAt); +var replace$1 = uncurryThis$2("".replace); +var stringSlice$2 = uncurryThis$2("".slice); +var SUBSTITUTION_SYMBOLS = /\$([$&'`]|\d{1,2}|<[^>]*>)/g; +var SUBSTITUTION_SYMBOLS_NO_NAMED = /\$([$&'`]|\d{1,2})/g; +var getSubstitution$2 = function(matched, str, position, captures, namedCaptures, replacement2) { + var tailPos = position + matched.length; + var m2 = captures.length; + var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED; + if (namedCaptures !== void 0) { + namedCaptures = toObject(namedCaptures); + symbols = SUBSTITUTION_SYMBOLS; + } + return replace$1(replacement2, symbols, function(match2, ch) { + var capture; + switch (charAt(ch, 0)) { + case "$": + return "$"; + case "&": + return matched; + case "`": + return stringSlice$2(str, 0, position); + case "'": + return stringSlice$2(str, tailPos); + case "<": + capture = namedCaptures[stringSlice$2(ch, 1, -1)]; + break; + default: + var n = +ch; + if (n === 0) return match2; + if (n > m2) { + var f2 = floor$1(n / 10); + if (f2 === 0) return match2; + if (f2 <= m2) return captures[f2 - 1] === void 0 ? charAt(ch, 1) : captures[f2 - 1] + charAt(ch, 1); + return match2; + } + capture = captures[n - 1]; + } + return capture === void 0 ? "" : capture; + }); +}; +var call$4 = functionCall; +var anObject$1 = anObject$7; +var isCallable$2 = isCallable$f; +var classof$1 = classofRaw$2; +var regexpExec = regexpExec$2; +var $TypeError$1 = TypeError; +var regexpExecAbstract = function(R2, S2) { + var exec2 = R2.exec; + if (isCallable$2(exec2)) { + var result = call$4(exec2, R2, S2); + if (result !== null) anObject$1(result); + return result; + } + if (classof$1(R2) === "RegExp") return call$4(regexpExec, R2, S2); + throw new $TypeError$1("RegExp#exec called on incompatible receiver"); +}; +var apply = functionApply; +var call$3 = functionCall; +var uncurryThis$1 = functionUncurryThis; +var fixRegExpWellKnownSymbolLogic = fixRegexpWellKnownSymbolLogic; +var fails = fails$f; +var anObject = anObject$7; +var isCallable$1 = isCallable$f; +var isNullOrUndefined$1 = isNullOrUndefined$4; +var toIntegerOrInfinity = toIntegerOrInfinity$7; +var toLength = toLength$2; +var toString$1 = toString$5; +var requireObjectCoercible$1 = requireObjectCoercible$6; +var advanceStringIndex = advanceStringIndex$1; +var getMethod$2 = getMethod$4; +var getSubstitution$1 = getSubstitution$2; +var regExpExec = regexpExecAbstract; +var wellKnownSymbol$2 = wellKnownSymbol$9; +var REPLACE$1 = wellKnownSymbol$2("replace"); +var max$2 = Math.max; +var min$2 = Math.min; +var concat = uncurryThis$1([].concat); +var push = uncurryThis$1([].push); +var stringIndexOf = uncurryThis$1("".indexOf); +var stringSlice$1 = uncurryThis$1("".slice); +var maybeToString = function(it) { + return it === void 0 ? it : String(it); +}; +var REPLACE_KEEPS_$0 = function() { + return "a".replace(/./, "$0") === "$0"; +}(); +var REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE = function() { + if (/./[REPLACE$1]) { + return /./[REPLACE$1]("a", "$0") === ""; + } + return false; +}(); +var REPLACE_SUPPORTS_NAMED_GROUPS = !fails(function() { + var re = /./; + re.exec = function() { + var result = []; + result.groups = { a: "7" }; + return result; + }; + return "".replace(re, "$") !== "7"; +}); +fixRegExpWellKnownSymbolLogic("replace", function(_2, nativeReplace2, maybeCallNative) { + var UNSAFE_SUBSTITUTE = REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE ? "$" : "$0"; + return [ + // `String.prototype.replace` method + // https://tc39.es/ecma262/#sec-string.prototype.replace + function replace2(searchValue, replaceValue) { + var O2 = requireObjectCoercible$1(this); + var replacer = isNullOrUndefined$1(searchValue) ? void 0 : getMethod$2(searchValue, REPLACE$1); + return replacer ? call$3(replacer, searchValue, O2, replaceValue) : call$3(nativeReplace2, toString$1(O2), searchValue, replaceValue); + }, + // `RegExp.prototype[@@replace]` method + // https://tc39.es/ecma262/#sec-regexp.prototype-@@replace + function(string2, replaceValue) { + var rx = anObject(this); + var S2 = toString$1(string2); + if (typeof replaceValue == "string" && stringIndexOf(replaceValue, UNSAFE_SUBSTITUTE) === -1 && stringIndexOf(replaceValue, "$<") === -1) { + var res = maybeCallNative(nativeReplace2, rx, S2, replaceValue); + if (res.done) return res.value; + } + var functionalReplace = isCallable$1(replaceValue); + if (!functionalReplace) replaceValue = toString$1(replaceValue); + var global2 = rx.global; + var fullUnicode; + if (global2) { + fullUnicode = rx.unicode; + rx.lastIndex = 0; + } + var results = []; + var result; + while (true) { + result = regExpExec(rx, S2); + if (result === null) break; + push(results, result); + if (!global2) break; + var matchStr = toString$1(result[0]); + if (matchStr === "") rx.lastIndex = advanceStringIndex(S2, toLength(rx.lastIndex), fullUnicode); + } + var accumulatedResult = ""; + var nextSourcePosition = 0; + for (var i2 = 0; i2 < results.length; i2++) { + result = results[i2]; + var matched = toString$1(result[0]); + var position = max$2(min$2(toIntegerOrInfinity(result.index), S2.length), 0); + var captures = []; + var replacement2; + for (var j2 = 1; j2 < result.length; j2++) push(captures, maybeToString(result[j2])); + var namedCaptures = result.groups; + if (functionalReplace) { + var replacerArgs = concat([matched], captures, position, S2); + if (namedCaptures !== void 0) push(replacerArgs, namedCaptures); + replacement2 = toString$1(apply(replaceValue, void 0, replacerArgs)); + } else { + replacement2 = getSubstitution$1(matched, S2, position, captures, namedCaptures, replaceValue); + } + if (position >= nextSourcePosition) { + accumulatedResult += stringSlice$1(S2, nextSourcePosition, position) + replacement2; + nextSourcePosition = position + matched.length; + } + } + return accumulatedResult + stringSlice$1(S2, nextSourcePosition); + } + ]; +}, !REPLACE_SUPPORTS_NAMED_GROUPS || !REPLACE_KEEPS_$0 || REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE); +var isObject = isObject$7; +var classof = classofRaw$2; +var wellKnownSymbol$1 = wellKnownSymbol$9; +var MATCH = wellKnownSymbol$1("match"); +var isRegexp = function(it) { + var isRegExp2; + return isObject(it) && ((isRegExp2 = it[MATCH]) !== void 0 ? !!isRegExp2 : classof(it) === "RegExp"); +}; +var call$2 = functionCall; +var hasOwn2 = hasOwnProperty_1; +var isPrototypeOf = objectIsPrototypeOf; +var regExpFlags = regexpFlags$1; +var RegExpPrototype = RegExp.prototype; +var regexpGetFlags = function(R2) { + var flags = R2.flags; + return flags === void 0 && !("flags" in RegExpPrototype) && !hasOwn2(R2, "flags") && isPrototypeOf(RegExpPrototype, R2) ? call$2(regExpFlags, R2) : flags; +}; +var $$1 = _export; +var call$1 = functionCall; +var uncurryThis = functionUncurryThis; +var requireObjectCoercible = requireObjectCoercible$6; +var isCallable = isCallable$f; +var isNullOrUndefined = isNullOrUndefined$4; +var isRegExp = isRegexp; +var toString2 = toString$5; +var getMethod$1 = getMethod$4; +var getRegExpFlags = regexpGetFlags; +var getSubstitution = getSubstitution$2; +var wellKnownSymbol = wellKnownSymbol$9; +var REPLACE = wellKnownSymbol("replace"); +var $TypeError = TypeError; +var indexOf = uncurryThis("".indexOf); +uncurryThis("".replace); +var stringSlice = uncurryThis("".slice); +var max$1 = Math.max; +$$1({ target: "String", proto: true }, { + replaceAll: function replaceAll(searchValue, replaceValue) { + var O2 = requireObjectCoercible(this); + var IS_REG_EXP, flags, replacer, string2, searchString, functionalReplace, searchLength, advanceBy, position, replacement2; + var endOfLastMatch = 0; + var result = ""; + if (!isNullOrUndefined(searchValue)) { + IS_REG_EXP = isRegExp(searchValue); + if (IS_REG_EXP) { + flags = toString2(requireObjectCoercible(getRegExpFlags(searchValue))); + if (!~indexOf(flags, "g")) throw new $TypeError("`.replaceAll` does not allow non-global regexes"); + } + replacer = getMethod$1(searchValue, REPLACE); + if (replacer) return call$1(replacer, searchValue, O2, replaceValue); + } + string2 = toString2(O2); + searchString = toString2(searchValue); + functionalReplace = isCallable(replaceValue); + if (!functionalReplace) replaceValue = toString2(replaceValue); + searchLength = searchString.length; + advanceBy = max$1(1, searchLength); + position = indexOf(string2, searchString); + while (position !== -1) { + replacement2 = functionalReplace ? toString2(replaceValue(searchString, position, string2)) : getSubstitution(searchString, string2, position, [], void 0, replaceValue); + result += stringSlice(string2, endOfLastMatch, position) + replacement2; + endOfLastMatch = position + searchLength; + position = position + advanceBy > string2.length ? -1 : indexOf(string2, searchString, position + advanceBy); + } + if (endOfLastMatch < string2.length) { + result += stringSlice(string2, endOfLastMatch); + } + return result; + } +}); +var entryUnbind = entryUnbind$5; +entryUnbind("String", "replaceAll"); +function isChild(x2) { + return x2 && typeof x2 === "object" && "parents" in x2; +} +function haveParentsChanged(child) { + for (let i2 = 0, n = child.parents.length; i2 < n; i2++) { + child.parents[i2].__unsafe__getWithoutCapture(true); + if (child.parents[i2].lastChangedEpoch !== child.parentEpochs[i2]) { + return true; + } + } + return false; +} +function detach(parent, child) { + if (!parent.children.remove(child)) { + return; + } + if (parent.children.isEmpty && isChild(parent)) { + for (let i2 = 0, n = parent.parents.length; i2 < n; i2++) { + detach(parent.parents[i2], parent); + } + } +} +function attach(parent, child) { + if (!parent.children.add(child)) { + return; + } + if (isChild(parent)) { + for (let i2 = 0, n = parent.parents.length; i2 < n; i2++) { + attach(parent.parents[i2], parent); + } + } +} +function equals(a2, b2) { + const shallowEquals = a2 === b2 || Object.is(a2, b2) || Boolean(a2 && b2 && typeof a2.equals === "function" && a2.equals(b2)); + return shallowEquals; +} +function singleton(key, init) { + const symbol = Symbol.for(`com.tldraw.state/${key}`); + const global2 = globalThis; + global2[symbol] ?? (global2[symbol] = init()); + return global2[symbol]; +} +const EMPTY_ARRAY = singleton("empty_array", () => Object.freeze([])); +const ARRAY_SIZE_THRESHOLD = 8; +class ArraySet { + constructor() { + __publicField(this, "arraySize", 0); + __publicField(this, "array", Array(ARRAY_SIZE_THRESHOLD)); + __publicField(this, "set", null); + } + /** + * Get whether this ArraySet has any elements. + * + * @returns True if this ArraySet has any elements, false otherwise. + */ + // eslint-disable-next-line no-restricted-syntax + get isEmpty() { + if (this.array) { + return this.arraySize === 0; + } + if (this.set) { + return this.set.size === 0; + } + throw new Error("no set or array"); + } + /** + * Add an item to the ArraySet if it is not already present. + * + * @param elem - The element to add. + */ + add(elem) { + if (this.array) { + const idx = this.array.indexOf(elem); + if (idx !== -1) { + return false; + } + if (this.arraySize < ARRAY_SIZE_THRESHOLD) { + this.array[this.arraySize] = elem; + this.arraySize++; + return true; + } else { + this.set = new Set(this.array); + this.array = null; + this.set.add(elem); + return true; + } + } + if (this.set) { + if (this.set.has(elem)) { + return false; + } + this.set.add(elem); + return true; + } + throw new Error("no set or array"); + } + /** + * Remove an item from the ArraySet if it is present. + * + * @param elem - The element to remove + */ + remove(elem) { + if (this.array) { + const idx = this.array.indexOf(elem); + if (idx === -1) { + return false; + } + this.array[idx] = void 0; + this.arraySize--; + if (idx !== this.arraySize) { + this.array[idx] = this.array[this.arraySize]; + this.array[this.arraySize] = void 0; + } + return true; + } + if (this.set) { + if (!this.set.has(elem)) { + return false; + } + this.set.delete(elem); + return true; + } + throw new Error("no set or array"); + } + /** + * Run a callback for each element in the ArraySet. + * + * @param visitor - The callback to run for each element. + */ + visit(visitor) { + if (this.array) { + for (let i2 = 0; i2 < this.arraySize; i2++) { + const elem = this.array[i2]; + if (typeof elem !== "undefined") { + visitor(elem); + } + } + return; + } + if (this.set) { + this.set.forEach(visitor); + return; + } + throw new Error("no set or array"); + } + has(elem) { + if (this.array) { + return this.array.indexOf(elem) !== -1; + } else { + return this.set.has(elem); + } + } + clear() { + if (this.set) { + this.set.clear(); + } else { + this.arraySize = 0; + this.array = []; + } + } + size() { + if (this.set) { + return this.set.size; + } else { + return this.arraySize; + } + } +} +const RESET_VALUE = Symbol.for("com.tldraw.state/RESET_VALUE"); +class HistoryBuffer { + constructor(capacity) { + __publicField(this, "index", 0); + // use a wrap around buffer to store the last N values + __publicField(this, "buffer"); + this.capacity = capacity; + this.buffer = new Array(capacity); + } + /** + * Add a diff to the history buffer. + * + * @param lastComputedEpoch - The epoch when the diff was computed. + * @param currentEpoch - The current epoch. + * @param diff - The diff to add, or else a reset value. + */ + pushEntry(lastComputedEpoch, currentEpoch, diff) { + if (diff === void 0) { + return; + } + if (diff === RESET_VALUE) { + this.clear(); + return; + } + this.buffer[this.index] = [lastComputedEpoch, currentEpoch, diff]; + this.index = (this.index + 1) % this.capacity; + } + /** + * Clear the history buffer. + */ + clear() { + this.index = 0; + this.buffer.fill(void 0); + } + /** + * Get the diffs since the given epoch. + * + * @param sinceEpoch - The epoch to get diffs since. + * @returns An array of diffs or a flag to reset the history buffer. + */ + getChangesSince(sinceEpoch) { + const { index: index2, capacity, buffer } = this; + for (let i2 = 0; i2 < capacity; i2++) { + const offset2 = (index2 - 1 + capacity - i2) % capacity; + const elem = buffer[offset2]; + if (!elem) { + return RESET_VALUE; + } + const [fromEpoch, toEpoch] = elem; + if (i2 === 0 && sinceEpoch >= toEpoch) { + return []; + } + if (fromEpoch <= sinceEpoch && sinceEpoch < toEpoch) { + const len = i2 + 1; + const result = new Array(len); + for (let j2 = 0; j2 < len; j2++) { + result[j2] = buffer[(offset2 + j2) % capacity][2]; + } + return result; + } + } + return RESET_VALUE; + } +} +class CaptureStackFrame { + constructor(below, child) { + __publicField(this, "offset", 0); + __publicField(this, "maybeRemoved"); + this.below = below; + this.child = child; + } +} +const inst$1 = singleton("capture", () => ({ stack: null })); +function unsafe__withoutCapture(fn) { + const oldStack = inst$1.stack; + inst$1.stack = null; + try { + return fn(); + } finally { + inst$1.stack = oldStack; + } +} +function startCapturingParents(child) { + inst$1.stack = new CaptureStackFrame(inst$1.stack, child); + child.parentSet.clear(); +} +function stopCapturingParents() { + const frame2 = inst$1.stack; + inst$1.stack = frame2.below; + if (frame2.offset < frame2.child.parents.length) { + for (let i2 = frame2.offset; i2 < frame2.child.parents.length; i2++) { + const maybeRemovedParent = frame2.child.parents[i2]; + if (!frame2.child.parentSet.has(maybeRemovedParent)) { + detach(maybeRemovedParent, frame2.child); + } + } + frame2.child.parents.length = frame2.offset; + frame2.child.parentEpochs.length = frame2.offset; + } + if (frame2.maybeRemoved) { + for (let i2 = 0; i2 < frame2.maybeRemoved.length; i2++) { + const maybeRemovedParent = frame2.maybeRemoved[i2]; + if (!frame2.child.parentSet.has(maybeRemovedParent)) { + detach(maybeRemovedParent, frame2.child); + } + } + } +} +function maybeCaptureParent(p2) { + if (inst$1.stack) { + const wasCapturedAlready = inst$1.stack.child.parentSet.has(p2); + if (wasCapturedAlready) { + return; + } + inst$1.stack.child.parentSet.add(p2); + if (inst$1.stack.child.isActivelyListening) { + attach(p2, inst$1.stack.child); + } + if (inst$1.stack.offset < inst$1.stack.child.parents.length) { + const maybeRemovedParent = inst$1.stack.child.parents[inst$1.stack.offset]; + if (maybeRemovedParent !== p2) { + if (!inst$1.stack.maybeRemoved) { + inst$1.stack.maybeRemoved = [maybeRemovedParent]; + } else { + inst$1.stack.maybeRemoved.push(maybeRemovedParent); + } + } + } + inst$1.stack.child.parents[inst$1.stack.offset] = p2; + inst$1.stack.child.parentEpochs[inst$1.stack.offset] = p2.lastChangedEpoch; + inst$1.stack.offset++; + } +} +const GLOBAL_START_EPOCH = -1; +class __EffectScheduler__ { + constructor(name, runEffect, options) { + __publicField(this, "_isActivelyListening", false); + /** @internal */ + __publicField(this, "lastTraversedEpoch", GLOBAL_START_EPOCH); + __publicField(this, "lastReactedEpoch", GLOBAL_START_EPOCH); + __publicField(this, "_scheduleCount", 0); + /** @internal */ + __publicField(this, "parentSet", new ArraySet()); + /** @internal */ + __publicField(this, "parentEpochs", []); + /** @internal */ + __publicField(this, "parents", []); + __publicField(this, "_scheduleEffect"); + /** @internal */ + // eslint-disable-next-line local/prefer-class-methods + __publicField(this, "maybeExecute", () => { + if (!this._isActivelyListening) return; + this.execute(); + }); + this.name = name; + this.runEffect = runEffect; + this._scheduleEffect = options == null ? void 0 : options.scheduleEffect; + } + /** + * Whether this scheduler is attached and actively listening to its parents. + * @public + */ + // eslint-disable-next-line no-restricted-syntax + get isActivelyListening() { + return this._isActivelyListening; + } + /** + * The number of times this effect has been scheduled. + * @public + */ + // eslint-disable-next-line no-restricted-syntax + get scheduleCount() { + return this._scheduleCount; + } + /** @internal */ + maybeScheduleEffect() { + if (!this._isActivelyListening) return; + if (this.lastReactedEpoch === getGlobalEpoch()) return; + if (this.parents.length && !haveParentsChanged(this)) { + this.lastReactedEpoch = getGlobalEpoch(); + return; + } + this.scheduleEffect(); + } + /** @internal */ + scheduleEffect() { + this._scheduleCount++; + if (this._scheduleEffect) { + this._scheduleEffect(this.maybeExecute); + } else { + this.execute(); + } + } + /** + * Makes this scheduler become 'actively listening' to its parents. + * If it has been executed before it will immediately become eligible to receive 'maybeScheduleEffect' calls. + * If it has not executed before it will need to be manually executed once to become eligible for scheduling, i.e. by calling [[EffectScheduler.execute]]. + * @public + */ + attach() { + this._isActivelyListening = true; + for (let i2 = 0, n = this.parents.length; i2 < n; i2++) { + attach(this.parents[i2], this); + } + } + /** + * Makes this scheduler stop 'actively listening' to its parents. + * It will no longer be eligible to receive 'maybeScheduleEffect' calls until [[EffectScheduler.attach]] is called again. + */ + detach() { + this._isActivelyListening = false; + for (let i2 = 0, n = this.parents.length; i2 < n; i2++) { + detach(this.parents[i2], this); + } + } + /** + * Executes the effect immediately and returns the result. + * @returns The result of the effect. + */ + execute() { + try { + startCapturingParents(this); + const currentEpoch = getGlobalEpoch(); + const result = this.runEffect(this.lastReactedEpoch); + this.lastReactedEpoch = currentEpoch; + return result; + } finally { + stopCapturingParents(); + } + } +} +const EffectScheduler = singleton( + "EffectScheduler", + () => __EffectScheduler__ +); +function react(name, fn, options) { + const scheduler2 = new EffectScheduler(name, fn, options); + scheduler2.attach(); + scheduler2.scheduleEffect(); + return () => { + scheduler2.detach(); + }; +} +function reactor(name, fn, options) { + const scheduler2 = new EffectScheduler(name, fn, options); + return { + scheduler: scheduler2, + start: (options2) => { + const force = (options2 == null ? void 0 : options2.force) ?? false; + scheduler2.attach(); + if (force) { + scheduler2.scheduleEffect(); + } else { + scheduler2.maybeScheduleEffect(); + } + }, + stop: () => { + scheduler2.detach(); + } + }; +} +class Transaction { + constructor(parent) { + __publicField(this, "initialAtomValues", /* @__PURE__ */ new Map()); + this.parent = parent; + } + /** + * Get whether this transaction is a root (no parents). + * + * @public + */ + // eslint-disable-next-line no-restricted-syntax + get isRoot() { + return this.parent === null; + } + /** + * Commit the transaction's changes. + * + * @public + */ + commit() { + if (inst.globalIsReacting) { + for (const atom2 of this.initialAtomValues.keys()) { + traverseAtomForCleanup(atom2); + } + } else if (this.isRoot) { + flushChanges(this.initialAtomValues.keys()); + } else { + this.initialAtomValues.forEach((value, atom2) => { + if (!this.parent.initialAtomValues.has(atom2)) { + this.parent.initialAtomValues.set(atom2, value); + } + }); + } + } + /** + * Abort the transaction. + * + * @public + */ + abort() { + inst.globalEpoch++; + this.initialAtomValues.forEach((value, atom2) => { + var _a3; + atom2.set(value); + (_a3 = atom2.historyBuffer) == null ? void 0 : _a3.clear(); + }); + this.commit(); + } +} +const inst = singleton("transactions", () => ({ + // The current epoch (global to all atoms). + globalEpoch: GLOBAL_START_EPOCH + 1, + // Whether any transaction is reacting. + globalIsReacting: false, + currentTransaction: null, + cleanupReactors: null, + reactionEpoch: GLOBAL_START_EPOCH + 1 +})); +function getReactionEpoch() { + return inst.reactionEpoch; +} +function getGlobalEpoch() { + return inst.globalEpoch; +} +function getIsReacting() { + return inst.globalIsReacting; +} +function traverse(reactors, child) { + if (child.lastTraversedEpoch === inst.globalEpoch) { + return; + } + child.lastTraversedEpoch = inst.globalEpoch; + if (child instanceof EffectScheduler) { + reactors.add(child); + } else { + child.children.visit((c2) => traverse(reactors, c2)); + } +} +function flushChanges(atoms) { + var _a3; + if (inst.globalIsReacting) { + throw new Error("flushChanges cannot be called during a reaction"); + } + const outerTxn = inst.currentTransaction; + try { + inst.currentTransaction = null; + inst.globalIsReacting = true; + inst.reactionEpoch = inst.globalEpoch; + const reactors = /* @__PURE__ */ new Set(); + for (const atom2 of atoms) { + atom2.children.visit((child) => traverse(reactors, child)); + } + for (const r of reactors) { + r.maybeScheduleEffect(); + } + let updateDepth = 0; + while ((_a3 = inst.cleanupReactors) == null ? void 0 : _a3.size) { + if (updateDepth++ > 1e3) { + throw new Error("Reaction update depth limit exceeded"); + } + const reactors2 = inst.cleanupReactors; + inst.cleanupReactors = null; + for (const r of reactors2) { + r.maybeScheduleEffect(); + } + } + } finally { + inst.cleanupReactors = null; + inst.globalIsReacting = false; + inst.currentTransaction = outerTxn; + } +} +function atomDidChange(atom2, previousValue) { + if (inst.currentTransaction) { + if (!inst.currentTransaction.initialAtomValues.has(atom2)) { + inst.currentTransaction.initialAtomValues.set(atom2, previousValue); + } + } else if (inst.globalIsReacting) { + traverseAtomForCleanup(atom2); + } else { + flushChanges([atom2]); + } +} +function traverseAtomForCleanup(atom2) { + const rs = inst.cleanupReactors ?? (inst.cleanupReactors = /* @__PURE__ */ new Set()); + atom2.children.visit((child) => traverse(rs, child)); +} +function advanceGlobalEpoch() { + inst.globalEpoch++; +} +function transaction(fn) { + const txn = new Transaction(inst.currentTransaction); + inst.currentTransaction = txn; + try { + let result = void 0; + let rollback = false; + try { + result = fn(() => rollback = true); + } catch (e2) { + txn.abort(); + throw e2; + } + if (rollback) { + txn.abort(); + } else { + txn.commit(); + } + return result; + } finally { + inst.currentTransaction = inst.currentTransaction.parent; + } +} +function transact(fn) { + if (inst.currentTransaction) { + return fn(); + } + return transaction(fn); +} +class __Atom__ { + constructor(name, current, options) { + __publicField(this, "isEqual"); + __publicField(this, "computeDiff"); + __publicField(this, "lastChangedEpoch", getGlobalEpoch()); + __publicField(this, "children", new ArraySet()); + __publicField(this, "historyBuffer"); + this.name = name; + this.current = current; + this.isEqual = (options == null ? void 0 : options.isEqual) ?? null; + if (!options) return; + if (options.historyLength) { + this.historyBuffer = new HistoryBuffer(options.historyLength); + } + this.computeDiff = options.computeDiff; + } + __unsafe__getWithoutCapture(_ignoreErrors) { + return this.current; + } + get() { + maybeCaptureParent(this); + return this.current; + } + set(value, diff) { + var _a3, _b2; + if (((_a3 = this.isEqual) == null ? void 0 : _a3.call(this, this.current, value)) ?? equals(this.current, value)) { + return this.current; + } + advanceGlobalEpoch(); + if (this.historyBuffer) { + this.historyBuffer.pushEntry( + this.lastChangedEpoch, + getGlobalEpoch(), + diff ?? ((_b2 = this.computeDiff) == null ? void 0 : _b2.call(this, this.current, value, this.lastChangedEpoch, getGlobalEpoch())) ?? RESET_VALUE + ); + } + this.lastChangedEpoch = getGlobalEpoch(); + const oldValue = this.current; + this.current = value; + atomDidChange(this, oldValue); + return value; + } + update(updater) { + return this.set(updater(this.current)); + } + getDiffSince(epoch) { + var _a3; + maybeCaptureParent(this); + if (epoch >= this.lastChangedEpoch) { + return EMPTY_ARRAY; + } + return ((_a3 = this.historyBuffer) == null ? void 0 : _a3.getChangesSince(epoch)) ?? RESET_VALUE; + } +} +const _Atom = singleton("Atom", () => __Atom__); +function atom(name, initialValue, options) { + return new _Atom(name, initialValue, options); +} +let didWarnComputedGetter = false; +function logComputedGetterWarning() { + if (didWarnComputedGetter) return; + didWarnComputedGetter = true; + console.warn( + `Using \`@computed\` as a decorator for getters is deprecated and will be removed in the near future. Please refactor to use \`@computed\` as a decorator for methods. + +// Before +@computed +get foo() { + return 'foo' +} + +// After +@computed +getFoo() { + return 'foo' +} +` + ); +} +const UNINITIALIZED = Symbol.for("com.tldraw.state/UNINITIALIZED"); +function isUninitialized(value) { + return value === UNINITIALIZED; +} +const WithDiff = singleton( + "WithDiff", + () => class WithDiff { + constructor(value, diff) { + this.value = value; + this.diff = diff; + } + } +); +function withDiff(value, diff) { + return new WithDiff(value, diff); +} +class __UNSAFE__Computed { + constructor(name, derive, options) { + __publicField(this, "lastChangedEpoch", GLOBAL_START_EPOCH); + __publicField(this, "lastTraversedEpoch", GLOBAL_START_EPOCH); + /** + * The epoch when the reactor was last checked. + */ + __publicField(this, "lastCheckedEpoch", GLOBAL_START_EPOCH); + __publicField(this, "parentSet", new ArraySet()); + __publicField(this, "parents", []); + __publicField(this, "parentEpochs", []); + __publicField(this, "children", new ArraySet()); + __publicField(this, "historyBuffer"); + // The last-computed value of this signal. + __publicField(this, "state", UNINITIALIZED); + // If the signal throws an error we stash it so we can rethrow it on the next get() + __publicField(this, "error", null); + __publicField(this, "computeDiff"); + __publicField(this, "isEqual"); + this.name = name; + this.derive = derive; + if (options == null ? void 0 : options.historyLength) { + this.historyBuffer = new HistoryBuffer(options.historyLength); + } + this.computeDiff = options == null ? void 0 : options.computeDiff; + this.isEqual = (options == null ? void 0 : options.isEqual) ?? equals; + } + // eslint-disable-next-line no-restricted-syntax + get isActivelyListening() { + return !this.children.isEmpty; + } + __unsafe__getWithoutCapture(ignoreErrors) { + var _a3; + const isNew = this.lastChangedEpoch === GLOBAL_START_EPOCH; + const globalEpoch = getGlobalEpoch(); + if (!isNew && (this.lastCheckedEpoch === globalEpoch || this.isActivelyListening && getIsReacting() && this.lastTraversedEpoch < getReactionEpoch() || !haveParentsChanged(this))) { + this.lastCheckedEpoch = globalEpoch; + if (this.error) { + if (!ignoreErrors) { + throw this.error.thrownValue; + } else { + return this.state; + } + } else { + return this.state; + } + } + try { + startCapturingParents(this); + const result = this.derive(this.state, this.lastCheckedEpoch); + const newState = result instanceof WithDiff ? result.value : result; + const isUninitialized2 = this.state === UNINITIALIZED; + if (isUninitialized2 || !this.isEqual(newState, this.state)) { + if (this.historyBuffer && !isUninitialized2) { + const diff = result instanceof WithDiff ? result.diff : void 0; + this.historyBuffer.pushEntry( + this.lastChangedEpoch, + getGlobalEpoch(), + diff ?? ((_a3 = this.computeDiff) == null ? void 0 : _a3.call(this, this.state, newState, this.lastCheckedEpoch, getGlobalEpoch())) ?? RESET_VALUE + ); + } + this.lastChangedEpoch = getGlobalEpoch(); + this.state = newState; + } + this.error = null; + this.lastCheckedEpoch = getGlobalEpoch(); + return this.state; + } catch (e2) { + if (this.state !== UNINITIALIZED) { + this.state = UNINITIALIZED; + this.lastChangedEpoch = getGlobalEpoch(); + } + this.lastCheckedEpoch = getGlobalEpoch(); + if (this.historyBuffer) { + this.historyBuffer.clear(); + } + this.error = { thrownValue: e2 }; + if (!ignoreErrors) throw e2; + return this.state; + } finally { + stopCapturingParents(); + } + } + get() { + try { + return this.__unsafe__getWithoutCapture(); + } finally { + maybeCaptureParent(this); + } + } + getDiffSince(epoch) { + var _a3; + this.__unsafe__getWithoutCapture(true); + maybeCaptureParent(this); + if (epoch >= this.lastChangedEpoch) { + return EMPTY_ARRAY; + } + return ((_a3 = this.historyBuffer) == null ? void 0 : _a3.getChangesSince(epoch)) ?? RESET_VALUE; + } +} +const _Computed = singleton("Computed", () => __UNSAFE__Computed); +function computedMethodLegacyDecorator(options = {}, _target, key, descriptor) { + const originalMethod = descriptor.value; + const derivationKey = Symbol.for("__@tldraw/state__computed__" + key); + descriptor.value = function() { + let d2 = this[derivationKey]; + if (!d2) { + d2 = new _Computed(key, originalMethod.bind(this), options); + Object.defineProperty(this, derivationKey, { + enumerable: false, + configurable: false, + writable: false, + value: d2 + }); + } + return d2.get(); + }; + descriptor.value[isComputedMethodKey] = true; + return descriptor; +} +function computedGetterLegacyDecorator(options = {}, _target, key, descriptor) { + const originalMethod = descriptor.get; + const derivationKey = Symbol.for("__@tldraw/state__computed__" + key); + descriptor.get = function() { + let d2 = this[derivationKey]; + if (!d2) { + d2 = new _Computed(key, originalMethod.bind(this), options); + Object.defineProperty(this, derivationKey, { + enumerable: false, + configurable: false, + writable: false, + value: d2 + }); + } + return d2.get(); + }; + return descriptor; +} +function computedMethodTc39Decorator(options, compute, context) { + assert(context.kind === "method", "@computed can only be used on methods"); + const derivationKey = Symbol.for("__@tldraw/state__computed__" + String(context.name)); + const fn = function() { + let d2 = this[derivationKey]; + if (!d2) { + d2 = new _Computed(String(context.name), compute.bind(this), options); + Object.defineProperty(this, derivationKey, { + enumerable: false, + configurable: false, + writable: false, + value: d2 + }); + } + return d2.get(); + }; + fn[isComputedMethodKey] = true; + return fn; +} +function computedDecorator(options = {}, args) { + if (args.length === 2) { + const [originalMethod, context] = args; + return computedMethodTc39Decorator(options, originalMethod, context); + } else { + const [_target, key, descriptor] = args; + if (descriptor.get) { + logComputedGetterWarning(); + return computedGetterLegacyDecorator(options, _target, key, descriptor); + } else { + return computedMethodLegacyDecorator(options, _target, key, descriptor); + } + } +} +const isComputedMethodKey = "@@__isComputedMethod__@@"; +function computed() { + if (arguments.length === 1) { + const options = arguments[0]; + return (...args) => computedDecorator(options, args); + } else if (typeof arguments[0] === "string") { + return new _Computed(arguments[0], arguments[1], arguments[2]); + } else { + return computedDecorator(void 0, arguments); + } +} +const currentApiVersion = 1; +const actualApiVersion = singleton("apiVersion", () => currentApiVersion); +if (actualApiVersion !== currentApiVersion) { + throw new Error( + `You have multiple incompatible versions of @tldraw/state in your app. Please deduplicate the package.` + ); +} +registerTldrawLibraryVersion( + "@tldraw/state", + "3.4.1", + "esm" +); +function useStateTracking(name, render) { + const renderRef = React.useRef(render); + renderRef.current = render; + const [scheduler2, subscribe, getSnapshot2] = React.useMemo(() => { + let scheduleUpdate = null; + const subscribe2 = (cb) => { + scheduleUpdate = cb; + return () => { + scheduleUpdate = null; + }; + }; + const scheduler22 = new EffectScheduler( + `useStateTracking(${name})`, + // this is what `scheduler.execute()` will call + () => { + var _a3; + return (_a3 = renderRef.current) == null ? void 0 : _a3.call(renderRef); + }, + // this is what will be invoked when @tldraw/state detects a change in an upstream reactive value + { + scheduleEffect() { + scheduleUpdate == null ? void 0 : scheduleUpdate(); + } + } + ); + const getSnapshot22 = () => scheduler22.scheduleCount; + return [scheduler22, subscribe2, getSnapshot22]; + }, [name]); + React.useSyncExternalStore(subscribe, getSnapshot2, getSnapshot2); + React.useEffect(() => { + scheduler2.attach(); + scheduler2.maybeScheduleEffect(); + return () => { + scheduler2.detach(); + }; + }, [scheduler2]); + return scheduler2.execute(); +} +const ProxyHandlers = { + /** + * This is a function call trap for functional components. When this is called, we know it means + * React did run 'Component()', that means we can use any hooks here to setup our effect and + * store. + * + * With the native Proxy, all other calls such as access/setting to/of properties will be + * forwarded to the target Component, so we don't need to copy the Component's own or inherited + * properties. + * + * @see https://github.com/facebook/react/blob/2d80a0cd690bb5650b6c8a6c079a87b5dc42bd15/packages/react-reconciler/src/ReactFiberHooks.old.js#L460 + */ + apply(Component, thisArg, argumentsList) { + return useStateTracking( + Component.displayName ?? Component.name ?? "tracked(???)", + () => Component.apply(thisArg, argumentsList) + ); + } +}; +const ReactMemoSymbol = Symbol.for("react.memo"); +const ReactForwardRefSymbol = Symbol.for("react.forward_ref"); +function track(baseComponent) { + let compare = null; + const $$typeof = baseComponent["$$typeof"]; + if ($$typeof === ReactMemoSymbol) { + baseComponent = baseComponent.type; + compare = baseComponent.compare; + } + if ($$typeof === ReactForwardRefSymbol) { + return reactExports.memo(reactExports.forwardRef(new Proxy(baseComponent.render, ProxyHandlers))); + } + return reactExports.memo(new Proxy(baseComponent, ProxyHandlers), compare); +} +function useAtom(name, valueOrInitialiser, options) { + return reactExports.useState(() => { + const initialValue = typeof valueOrInitialiser === "function" ? valueOrInitialiser() : valueOrInitialiser; + return atom(`useAtom(${name})`, initialValue, options); + })[0]; +} +function useComputed() { + const name = arguments[0]; + const compute = arguments[1]; + const opts = arguments.length === 3 ? void 0 : arguments[2]; + const deps = arguments.length === 3 ? arguments[2] : arguments[3]; + return reactExports.useMemo(() => computed(`useComputed(${name})`, compute, opts), deps); +} +function useQuickReactor(name, reactFn, deps = EMPTY_ARRAY) { + reactExports.useEffect(() => { + const scheduler2 = new EffectScheduler(name, reactFn); + scheduler2.attach(); + scheduler2.execute(); + return () => { + scheduler2.detach(); + }; + }, deps); +} +function useValue() { + const args = arguments; + const deps = args.length === 3 ? args[2] : [args[0]]; + const name = args.length === 3 ? args[0] : `useValue(${args[0].name})`; + const isInRender = reactExports.useRef(true); + isInRender.current = true; + const $val = reactExports.useMemo(() => { + if (args.length === 1) { + return args[0]; + } + return computed(name, () => { + if (isInRender.current) { + return args[1](); + } else { + try { + return args[1](); + } catch { + return {}; + } + } + }); + }, deps); + try { + const { subscribe, getSnapshot: getSnapshot2 } = reactExports.useMemo(() => { + return { + subscribe: (listen) => { + return react(`useValue(${name})`, () => { + $val.get(); + listen(); + }); + }, + getSnapshot: () => $val.get() + }; + }, [$val]); + return reactExports.useSyncExternalStore(subscribe, getSnapshot2, getSnapshot2); + } finally { + isInRender.current = false; + } +} +registerTldrawLibraryVersion( + "@tldraw/state-react", + "3.4.1", + "esm" +); +class IncrementalSetConstructor { + constructor(previousValue) { + /** + * The next value of the set. + * + * @internal + */ + __publicField(this, "nextValue"); + /** + * The diff of the set. + * + * @internal + */ + __publicField(this, "diff"); + this.previousValue = previousValue; + } + /** + * Get the next value of the set. + * + * @public + */ + get() { + var _a3, _b2, _c2, _d2; + const numRemoved = ((_b2 = (_a3 = this.diff) == null ? void 0 : _a3.removed) == null ? void 0 : _b2.size) ?? 0; + const numAdded = ((_d2 = (_c2 = this.diff) == null ? void 0 : _c2.added) == null ? void 0 : _d2.size) ?? 0; + if (numRemoved === 0 && numAdded === 0) { + return void 0; + } + return { value: this.nextValue, diff: this.diff }; + } + /** + * Add an item to the set. + * + * @param item - The item to add. + * @param wasAlreadyPresent - Whether the item was already present in the set. + * @internal + */ + _add(item, wasAlreadyPresent) { + var _a3, _b2; + this.nextValue ?? (this.nextValue = new Set(this.previousValue)); + this.nextValue.add(item); + this.diff ?? (this.diff = {}); + if (wasAlreadyPresent) { + (_a3 = this.diff.removed) == null ? void 0 : _a3.delete(item); + } else { + (_b2 = this.diff).added ?? (_b2.added = /* @__PURE__ */ new Set()); + this.diff.added.add(item); + } + } + /** + * Add an item to the set. + * + * @param item - The item to add. + * @public + */ + add(item) { + var _a3, _b2, _c2; + const wasAlreadyPresent = this.previousValue.has(item); + if (wasAlreadyPresent) { + const wasRemoved = (_b2 = (_a3 = this.diff) == null ? void 0 : _a3.removed) == null ? void 0 : _b2.has(item); + if (!wasRemoved) return; + return this._add(item, wasAlreadyPresent); + } + const isCurrentlyPresent = (_c2 = this.nextValue) == null ? void 0 : _c2.has(item); + if (isCurrentlyPresent) return; + this._add(item, wasAlreadyPresent); + } + /** + * Remove an item from the set. + * + * @param item - The item to remove. + * @param wasAlreadyPresent - Whether the item was already present in the set. + * @internal + */ + _remove(item, wasAlreadyPresent) { + var _a3, _b2; + this.nextValue ?? (this.nextValue = new Set(this.previousValue)); + this.nextValue.delete(item); + this.diff ?? (this.diff = {}); + if (wasAlreadyPresent) { + (_a3 = this.diff).removed ?? (_a3.removed = /* @__PURE__ */ new Set()); + this.diff.removed.add(item); + } else { + (_b2 = this.diff.added) == null ? void 0 : _b2.delete(item); + } + } + /** + * Remove an item from the set. + * + * @param item - The item to remove. + * @public + */ + remove(item) { + var _a3, _b2, _c2, _d2; + const wasAlreadyPresent = this.previousValue.has(item); + if (!wasAlreadyPresent) { + const wasAdded = (_b2 = (_a3 = this.diff) == null ? void 0 : _a3.added) == null ? void 0 : _b2.has(item); + if (!wasAdded) return; + return this._remove(item, wasAlreadyPresent); + } + const hasAlreadyBeenRemoved = (_d2 = (_c2 = this.diff) == null ? void 0 : _c2.removed) == null ? void 0 : _d2.has(item); + if (hasAlreadyBeenRemoved) return; + this._remove(item, wasAlreadyPresent); + } +} +class RecordType { + constructor(typeName, config) { + __publicField(this, "createDefaultProperties"); + __publicField(this, "validator"); + __publicField(this, "ephemeralKeys"); + __publicField(this, "ephemeralKeySet"); + __publicField(this, "scope"); + this.typeName = typeName; + this.createDefaultProperties = config.createDefaultProperties; + this.validator = config.validator ?? { validate: (r) => r }; + this.scope = config.scope ?? "document"; + this.ephemeralKeys = config.ephemeralKeys; + const ephemeralKeySet = /* @__PURE__ */ new Set(); + if (config.ephemeralKeys) { + for (const [key, isEphemeral] of objectMapEntries(config.ephemeralKeys)) { + if (isEphemeral) ephemeralKeySet.add(key); + } + } + this.ephemeralKeySet = ephemeralKeySet; + } + /** + * Create a new record of this type. + * + * @param properties - The properties of the record. + * @returns The new record. + */ + create(properties) { + const result = { ...this.createDefaultProperties(), id: this.createId() }; + for (const [k, v2] of Object.entries(properties)) { + if (v2 !== void 0) { + result[k] = v2; + } + } + result.typeName = this.typeName; + return result; + } + /** + * Clone a record of this type. + * + * @param record - The record to clone. + * @returns The cloned record. + * @public + */ + clone(record) { + return { ...structuredClone(record), id: this.createId() }; + } + /** + * Create a new ID for this record type. + * + * @example + * + * ```ts + * const id = recordType.createId() + * ``` + * + * @returns The new ID. + * @public + */ + createId(customUniquePart) { + return this.typeName + ":" + (customUniquePart ?? uniqueId()); + } + /** + * Create a new ID for this record type based on the given ID. + * + * @example + * + * ```ts + * const id = recordType.createCustomId('myId') + * ``` + * + * @deprecated - Use `createId` instead. + * @param id - The ID to base the new ID on. + * @returns The new ID. + */ + createCustomId(id2) { + return this.typeName + ":" + id2; + } + /** + * Takes an id like `user:123` and returns the part after the colon `123` + * + * @param id - The id + * @returns + */ + parseId(id2) { + if (!this.isId(id2)) { + throw new Error(`ID "${id2}" is not a valid ID for type "${this.typeName}"`); + } + return id2.slice(this.typeName.length + 1); + } + /** + * Check whether a record is an instance of this record type. + * + * @example + * + * ```ts + * const result = recordType.isInstance(someRecord) + * ``` + * + * @param record - The record to check. + * @returns Whether the record is an instance of this record type. + */ + isInstance(record) { + return (record == null ? void 0 : record.typeName) === this.typeName; + } + /** + * Check whether an id is an id of this type. + * + * @example + * + * ```ts + * const result = recordType.isIn('someId') + * ``` + * + * @param id - The id to check. + * @returns Whether the id is an id of this type. + */ + isId(id2) { + if (!id2) return false; + for (let i2 = 0; i2 < this.typeName.length; i2++) { + if (id2[i2] !== this.typeName[i2]) return false; + } + return id2[this.typeName.length] === ":"; + } + /** + * Create a new RecordType that has the same type name as this RecordType and includes the given + * default properties. + * + * @example + * + * ```ts + * const authorType = createRecordType('author', () => ({ living: true })) + * const deadAuthorType = authorType.withDefaultProperties({ living: false }) + * ``` + * + * @param createDefaultProperties - A function that returns the default properties of the new RecordType. + * @returns The new RecordType. + */ + withDefaultProperties(createDefaultProperties) { + return new RecordType(this.typeName, { + createDefaultProperties, + validator: this.validator, + scope: this.scope, + ephemeralKeys: this.ephemeralKeys + }); + } + /** + * Check that the passed in record passes the validations for this type. Returns its input + * correctly typed if it does, but throws an error otherwise. + */ + validate(record, recordBefore) { + if (recordBefore && this.validator.validateUsingKnownGoodVersion) { + return this.validator.validateUsingKnownGoodVersion(recordBefore, record); + } + return this.validator.validate(record); + } +} +function createRecordType(typeName, config) { + return new RecordType(typeName, { + createDefaultProperties: () => ({}), + validator: config.validator, + scope: config.scope, + ephemeralKeys: config.ephemeralKeys + }); +} +function createEmptyRecordsDiff() { + return { added: {}, updated: {}, removed: {} }; +} +function reverseRecordsDiff(diff) { + const result = { added: diff.removed, removed: diff.added, updated: {} }; + for (const [from, to] of Object.values(diff.updated)) { + result.updated[from.id] = [to, from]; + } + return result; +} +function isRecordsDiffEmpty(diff) { + return Object.keys(diff.added).length === 0 && Object.keys(diff.updated).length === 0 && Object.keys(diff.removed).length === 0; +} +function squashRecordDiffs(diffs) { + const result = { added: {}, removed: {}, updated: {} }; + squashRecordDiffsMutable(result, diffs); + return result; +} +function squashRecordDiffsMutable(target, diffs) { + for (const diff of diffs) { + for (const [id2, value] of objectMapEntries(diff.added)) { + if (target.removed[id2]) { + const original = target.removed[id2]; + delete target.removed[id2]; + if (original !== value) { + target.updated[id2] = [original, value]; + } + } else { + target.added[id2] = value; + } + } + for (const [id2, [_from, to]] of objectMapEntries(diff.updated)) { + if (target.added[id2]) { + target.added[id2] = to; + delete target.updated[id2]; + delete target.removed[id2]; + continue; + } + if (target.updated[id2]) { + target.updated[id2] = [target.updated[id2][0], to]; + delete target.removed[id2]; + continue; + } + target.updated[id2] = diff.updated[id2]; + delete target.removed[id2]; + } + for (const [id2, value] of objectMapEntries(diff.removed)) { + if (target.added[id2]) { + delete target.added[id2]; + } else if (target.updated[id2]) { + target.removed[id2] = target.updated[id2][0]; + delete target.updated[id2]; + } else { + target.removed[id2] = value; + } + } + } +} +var lodash_isequal = { exports: {} }; +lodash_isequal.exports; +(function(module, exports) { + var LARGE_ARRAY_SIZE2 = 200; + var HASH_UNDEFINED2 = "__lodash_hash_undefined__"; + var COMPARE_PARTIAL_FLAG = 1, COMPARE_UNORDERED_FLAG = 2; + var MAX_SAFE_INTEGER2 = 9007199254740991; + var argsTag = "[object Arguments]", arrayTag = "[object Array]", asyncTag = "[object AsyncFunction]", boolTag = "[object Boolean]", dateTag = "[object Date]", errorTag = "[object Error]", funcTag2 = "[object Function]", genTag2 = "[object GeneratorFunction]", mapTag = "[object Map]", numberTag = "[object Number]", nullTag = "[object Null]", objectTag = "[object Object]", promiseTag = "[object Promise]", proxyTag = "[object Proxy]", regexpTag = "[object RegExp]", setTag = "[object Set]", stringTag = "[object String]", symbolTag2 = "[object Symbol]", undefinedTag = "[object Undefined]", weakMapTag = "[object WeakMap]"; + var arrayBufferTag = "[object ArrayBuffer]", dataViewTag = "[object DataView]", float32Tag = "[object Float32Array]", float64Tag = "[object Float64Array]", int8Tag = "[object Int8Array]", int16Tag = "[object Int16Array]", int32Tag = "[object Int32Array]", uint8Tag = "[object Uint8Array]", uint8ClampedTag = "[object Uint8ClampedArray]", uint16Tag = "[object Uint16Array]", uint32Tag = "[object Uint32Array]"; + var reRegExpChar2 = /[\\^$.*+?()[\]{}|]/g; + var reIsHostCtor2 = /^\[object .+?Constructor\]$/; + var reIsUint = /^(?:0|[1-9]\d*)$/; + var typedArrayTags = {}; + typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = typedArrayTags[uint32Tag] = true; + typedArrayTags[argsTag] = typedArrayTags[arrayTag] = typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = typedArrayTags[errorTag] = typedArrayTags[funcTag2] = typedArrayTags[mapTag] = typedArrayTags[numberTag] = typedArrayTags[objectTag] = typedArrayTags[regexpTag] = typedArrayTags[setTag] = typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; + var freeGlobal2 = typeof commonjsGlobal == "object" && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; + var freeSelf2 = typeof self == "object" && self && self.Object === Object && self; + var root2 = freeGlobal2 || freeSelf2 || Function("return this")(); + var freeExports = exports && !exports.nodeType && exports; + var freeModule = freeExports && true && module && !module.nodeType && module; + var moduleExports = freeModule && freeModule.exports === freeExports; + var freeProcess = moduleExports && freeGlobal2.process; + var nodeUtil = function() { + try { + return freeProcess && freeProcess.binding && freeProcess.binding("util"); + } catch (e2) { + } + }(); + var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; + function arrayFilter(array2, predicate) { + var index2 = -1, length = array2 == null ? 0 : array2.length, resIndex = 0, result = []; + while (++index2 < length) { + var value = array2[index2]; + if (predicate(value, index2, array2)) { + result[resIndex++] = value; + } + } + return result; + } + function arrayPush(array2, values) { + var index2 = -1, length = values.length, offset2 = array2.length; + while (++index2 < length) { + array2[offset2 + index2] = values[index2]; + } + return array2; + } + function arraySome(array2, predicate) { + var index2 = -1, length = array2 == null ? 0 : array2.length; + while (++index2 < length) { + if (predicate(array2[index2], index2, array2)) { + return true; + } + } + return false; + } + function baseTimes(n, iteratee) { + var index2 = -1, result = Array(n); + while (++index2 < n) { + result[index2] = iteratee(index2); + } + return result; + } + function baseUnary(func) { + return function(value) { + return func(value); + }; + } + function cacheHas2(cache, key) { + return cache.has(key); + } + function getValue2(object2, key) { + return object2 == null ? void 0 : object2[key]; + } + function mapToArray(map) { + var index2 = -1, result = Array(map.size); + map.forEach(function(value, key) { + result[++index2] = [key, value]; + }); + return result; + } + function overArg(func, transform) { + return function(arg) { + return func(transform(arg)); + }; + } + function setToArray2(set2) { + var index2 = -1, result = Array(set2.size); + set2.forEach(function(value) { + result[++index2] = value; + }); + return result; + } + var arrayProto2 = Array.prototype, funcProto2 = Function.prototype, objectProto2 = Object.prototype; + var coreJsData2 = root2["__core-js_shared__"]; + var funcToString2 = funcProto2.toString; + var hasOwnProperty2 = objectProto2.hasOwnProperty; + var maskSrcKey2 = function() { + var uid2 = /[^.]+$/.exec(coreJsData2 && coreJsData2.keys && coreJsData2.keys.IE_PROTO || ""); + return uid2 ? "Symbol(src)_1." + uid2 : ""; + }(); + var nativeObjectToString = objectProto2.toString; + var reIsNative2 = RegExp( + "^" + funcToString2.call(hasOwnProperty2).replace(reRegExpChar2, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$" + ); + var Buffer2 = moduleExports ? root2.Buffer : void 0, Symbol2 = root2.Symbol, Uint8Array2 = root2.Uint8Array, propertyIsEnumerable2 = objectProto2.propertyIsEnumerable, splice2 = arrayProto2.splice, symToStringTag = Symbol2 ? Symbol2.toStringTag : void 0; + var nativeGetSymbols = Object.getOwnPropertySymbols, nativeIsBuffer = Buffer2 ? Buffer2.isBuffer : void 0, nativeKeys = overArg(Object.keys, Object); + var DataView2 = getNative2(root2, "DataView"), Map2 = getNative2(root2, "Map"), Promise2 = getNative2(root2, "Promise"), Set2 = getNative2(root2, "Set"), WeakMap2 = getNative2(root2, "WeakMap"), nativeCreate2 = getNative2(Object, "create"); + var dataViewCtorString = toSource2(DataView2), mapCtorString = toSource2(Map2), promiseCtorString = toSource2(Promise2), setCtorString = toSource2(Set2), weakMapCtorString = toSource2(WeakMap2); + var symbolProto = Symbol2 ? Symbol2.prototype : void 0, symbolValueOf = symbolProto ? symbolProto.valueOf : void 0; + function Hash2(entries) { + var index2 = -1, length = entries == null ? 0 : entries.length; + this.clear(); + while (++index2 < length) { + var entry2 = entries[index2]; + this.set(entry2[0], entry2[1]); + } + } + function hashClear2() { + this.__data__ = nativeCreate2 ? nativeCreate2(null) : {}; + this.size = 0; + } + function hashDelete2(key) { + var result = this.has(key) && delete this.__data__[key]; + this.size -= result ? 1 : 0; + return result; + } + function hashGet2(key) { + var data2 = this.__data__; + if (nativeCreate2) { + var result = data2[key]; + return result === HASH_UNDEFINED2 ? void 0 : result; + } + return hasOwnProperty2.call(data2, key) ? data2[key] : void 0; + } + function hashHas2(key) { + var data2 = this.__data__; + return nativeCreate2 ? data2[key] !== void 0 : hasOwnProperty2.call(data2, key); + } + function hashSet2(key, value) { + var data2 = this.__data__; + this.size += this.has(key) ? 0 : 1; + data2[key] = nativeCreate2 && value === void 0 ? HASH_UNDEFINED2 : value; + return this; + } + Hash2.prototype.clear = hashClear2; + Hash2.prototype["delete"] = hashDelete2; + Hash2.prototype.get = hashGet2; + Hash2.prototype.has = hashHas2; + Hash2.prototype.set = hashSet2; + function ListCache2(entries) { + var index2 = -1, length = entries == null ? 0 : entries.length; + this.clear(); + while (++index2 < length) { + var entry2 = entries[index2]; + this.set(entry2[0], entry2[1]); + } + } + function listCacheClear2() { + this.__data__ = []; + this.size = 0; + } + function listCacheDelete2(key) { + var data2 = this.__data__, index2 = assocIndexOf2(data2, key); + if (index2 < 0) { + return false; + } + var lastIndex = data2.length - 1; + if (index2 == lastIndex) { + data2.pop(); + } else { + splice2.call(data2, index2, 1); + } + --this.size; + return true; + } + function listCacheGet2(key) { + var data2 = this.__data__, index2 = assocIndexOf2(data2, key); + return index2 < 0 ? void 0 : data2[index2][1]; + } + function listCacheHas2(key) { + return assocIndexOf2(this.__data__, key) > -1; + } + function listCacheSet2(key, value) { + var data2 = this.__data__, index2 = assocIndexOf2(data2, key); + if (index2 < 0) { + ++this.size; + data2.push([key, value]); + } else { + data2[index2][1] = value; + } + return this; + } + ListCache2.prototype.clear = listCacheClear2; + ListCache2.prototype["delete"] = listCacheDelete2; + ListCache2.prototype.get = listCacheGet2; + ListCache2.prototype.has = listCacheHas2; + ListCache2.prototype.set = listCacheSet2; + function MapCache2(entries) { + var index2 = -1, length = entries == null ? 0 : entries.length; + this.clear(); + while (++index2 < length) { + var entry2 = entries[index2]; + this.set(entry2[0], entry2[1]); + } + } + function mapCacheClear2() { + this.size = 0; + this.__data__ = { + "hash": new Hash2(), + "map": new (Map2 || ListCache2)(), + "string": new Hash2() + }; + } + function mapCacheDelete2(key) { + var result = getMapData2(this, key)["delete"](key); + this.size -= result ? 1 : 0; + return result; + } + function mapCacheGet2(key) { + return getMapData2(this, key).get(key); + } + function mapCacheHas2(key) { + return getMapData2(this, key).has(key); + } + function mapCacheSet2(key, value) { + var data2 = getMapData2(this, key), size2 = data2.size; + data2.set(key, value); + this.size += data2.size == size2 ? 0 : 1; + return this; + } + MapCache2.prototype.clear = mapCacheClear2; + MapCache2.prototype["delete"] = mapCacheDelete2; + MapCache2.prototype.get = mapCacheGet2; + MapCache2.prototype.has = mapCacheHas2; + MapCache2.prototype.set = mapCacheSet2; + function SetCache2(values) { + var index2 = -1, length = values == null ? 0 : values.length; + this.__data__ = new MapCache2(); + while (++index2 < length) { + this.add(values[index2]); + } + } + function setCacheAdd2(value) { + this.__data__.set(value, HASH_UNDEFINED2); + return this; + } + function setCacheHas2(value) { + return this.__data__.has(value); + } + SetCache2.prototype.add = SetCache2.prototype.push = setCacheAdd2; + SetCache2.prototype.has = setCacheHas2; + function Stack(entries) { + var data2 = this.__data__ = new ListCache2(entries); + this.size = data2.size; + } + function stackClear() { + this.__data__ = new ListCache2(); + this.size = 0; + } + function stackDelete(key) { + var data2 = this.__data__, result = data2["delete"](key); + this.size = data2.size; + return result; + } + function stackGet(key) { + return this.__data__.get(key); + } + function stackHas(key) { + return this.__data__.has(key); + } + function stackSet(key, value) { + var data2 = this.__data__; + if (data2 instanceof ListCache2) { + var pairs = data2.__data__; + if (!Map2 || pairs.length < LARGE_ARRAY_SIZE2 - 1) { + pairs.push([key, value]); + this.size = ++data2.size; + return this; + } + data2 = this.__data__ = new MapCache2(pairs); + } + data2.set(key, value); + this.size = data2.size; + return this; + } + Stack.prototype.clear = stackClear; + Stack.prototype["delete"] = stackDelete; + Stack.prototype.get = stackGet; + Stack.prototype.has = stackHas; + Stack.prototype.set = stackSet; + function arrayLikeKeys(value, inherited) { + var isArr = isArray3(value), isArg = !isArr && isArguments(value), isBuff = !isArr && !isArg && isBuffer(value), isType = !isArr && !isArg && !isBuff && isTypedArray(value), skipIndexes = isArr || isArg || isBuff || isType, result = skipIndexes ? baseTimes(value.length, String) : [], length = result.length; + for (var key in value) { + if (hasOwnProperty2.call(value, key) && !(skipIndexes && // Safari 9 has enumerable `arguments.length` in strict mode. + (key == "length" || // Node.js 0.10 has enumerable non-index properties on buffers. + isBuff && (key == "offset" || key == "parent") || // PhantomJS 2 has enumerable non-index properties on typed arrays. + isType && (key == "buffer" || key == "byteLength" || key == "byteOffset") || // Skip index properties. + isIndex(key, length)))) { + result.push(key); + } + } + return result; + } + function assocIndexOf2(array2, key) { + var length = array2.length; + while (length--) { + if (eq2(array2[length][0], key)) { + return length; + } + } + return -1; + } + function baseGetAllKeys(object2, keysFunc, symbolsFunc) { + var result = keysFunc(object2); + return isArray3(object2) ? result : arrayPush(result, symbolsFunc(object2)); + } + function baseGetTag(value) { + if (value == null) { + return value === void 0 ? undefinedTag : nullTag; + } + return symToStringTag && symToStringTag in Object(value) ? getRawTag(value) : objectToString2(value); + } + function baseIsArguments(value) { + return isObjectLike2(value) && baseGetTag(value) == argsTag; + } + function baseIsEqual(value, other, bitmask, customizer, stack2) { + if (value === other) { + return true; + } + if (value == null || other == null || !isObjectLike2(value) && !isObjectLike2(other)) { + return value !== value && other !== other; + } + return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack2); + } + function baseIsEqualDeep(object2, other, bitmask, customizer, equalFunc, stack2) { + var objIsArr = isArray3(object2), othIsArr = isArray3(other), objTag = objIsArr ? arrayTag : getTag(object2), othTag = othIsArr ? arrayTag : getTag(other); + objTag = objTag == argsTag ? objectTag : objTag; + othTag = othTag == argsTag ? objectTag : othTag; + var objIsObj = objTag == objectTag, othIsObj = othTag == objectTag, isSameTag = objTag == othTag; + if (isSameTag && isBuffer(object2)) { + if (!isBuffer(other)) { + return false; + } + objIsArr = true; + objIsObj = false; + } + if (isSameTag && !objIsObj) { + stack2 || (stack2 = new Stack()); + return objIsArr || isTypedArray(object2) ? equalArrays(object2, other, bitmask, customizer, equalFunc, stack2) : equalByTag(object2, other, objTag, bitmask, customizer, equalFunc, stack2); + } + if (!(bitmask & COMPARE_PARTIAL_FLAG)) { + var objIsWrapped = objIsObj && hasOwnProperty2.call(object2, "__wrapped__"), othIsWrapped = othIsObj && hasOwnProperty2.call(other, "__wrapped__"); + if (objIsWrapped || othIsWrapped) { + var objUnwrapped = objIsWrapped ? object2.value() : object2, othUnwrapped = othIsWrapped ? other.value() : other; + stack2 || (stack2 = new Stack()); + return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack2); + } + } + if (!isSameTag) { + return false; + } + stack2 || (stack2 = new Stack()); + return equalObjects(object2, other, bitmask, customizer, equalFunc, stack2); + } + function baseIsNative2(value) { + if (!isObject2(value) || isMasked2(value)) { + return false; + } + var pattern = isFunction2(value) ? reIsNative2 : reIsHostCtor2; + return pattern.test(toSource2(value)); + } + function baseIsTypedArray(value) { + return isObjectLike2(value) && isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; + } + function baseKeys(object2) { + if (!isPrototype(object2)) { + return nativeKeys(object2); + } + var result = []; + for (var key in Object(object2)) { + if (hasOwnProperty2.call(object2, key) && key != "constructor") { + result.push(key); + } + } + return result; + } + function equalArrays(array2, other, bitmask, customizer, equalFunc, stack2) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, arrLength = array2.length, othLength = other.length; + if (arrLength != othLength && !(isPartial && othLength > arrLength)) { + return false; + } + var stacked = stack2.get(array2); + if (stacked && stack2.get(other)) { + return stacked == other; + } + var index2 = -1, result = true, seen = bitmask & COMPARE_UNORDERED_FLAG ? new SetCache2() : void 0; + stack2.set(array2, other); + stack2.set(other, array2); + while (++index2 < arrLength) { + var arrValue = array2[index2], othValue = other[index2]; + if (customizer) { + var compared = isPartial ? customizer(othValue, arrValue, index2, other, array2, stack2) : customizer(arrValue, othValue, index2, array2, other, stack2); + } + if (compared !== void 0) { + if (compared) { + continue; + } + result = false; + break; + } + if (seen) { + if (!arraySome(other, function(othValue2, othIndex) { + if (!cacheHas2(seen, othIndex) && (arrValue === othValue2 || equalFunc(arrValue, othValue2, bitmask, customizer, stack2))) { + return seen.push(othIndex); + } + })) { + result = false; + break; + } + } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack2))) { + result = false; + break; + } + } + stack2["delete"](array2); + stack2["delete"](other); + return result; + } + function equalByTag(object2, other, tag, bitmask, customizer, equalFunc, stack2) { + switch (tag) { + case dataViewTag: + if (object2.byteLength != other.byteLength || object2.byteOffset != other.byteOffset) { + return false; + } + object2 = object2.buffer; + other = other.buffer; + case arrayBufferTag: + if (object2.byteLength != other.byteLength || !equalFunc(new Uint8Array2(object2), new Uint8Array2(other))) { + return false; + } + return true; + case boolTag: + case dateTag: + case numberTag: + return eq2(+object2, +other); + case errorTag: + return object2.name == other.name && object2.message == other.message; + case regexpTag: + case stringTag: + return object2 == other + ""; + case mapTag: + var convert = mapToArray; + case setTag: + var isPartial = bitmask & COMPARE_PARTIAL_FLAG; + convert || (convert = setToArray2); + if (object2.size != other.size && !isPartial) { + return false; + } + var stacked = stack2.get(object2); + if (stacked) { + return stacked == other; + } + bitmask |= COMPARE_UNORDERED_FLAG; + stack2.set(object2, other); + var result = equalArrays(convert(object2), convert(other), bitmask, customizer, equalFunc, stack2); + stack2["delete"](object2); + return result; + case symbolTag2: + if (symbolValueOf) { + return symbolValueOf.call(object2) == symbolValueOf.call(other); + } + } + return false; + } + function equalObjects(object2, other, bitmask, customizer, equalFunc, stack2) { + var isPartial = bitmask & COMPARE_PARTIAL_FLAG, objProps = getAllKeys(object2), objLength = objProps.length, othProps = getAllKeys(other), othLength = othProps.length; + if (objLength != othLength && !isPartial) { + return false; + } + var index2 = objLength; + while (index2--) { + var key = objProps[index2]; + if (!(isPartial ? key in other : hasOwnProperty2.call(other, key))) { + return false; + } + } + var stacked = stack2.get(object2); + if (stacked && stack2.get(other)) { + return stacked == other; + } + var result = true; + stack2.set(object2, other); + stack2.set(other, object2); + var skipCtor = isPartial; + while (++index2 < objLength) { + key = objProps[index2]; + var objValue = object2[key], othValue = other[key]; + if (customizer) { + var compared = isPartial ? customizer(othValue, objValue, key, other, object2, stack2) : customizer(objValue, othValue, key, object2, other, stack2); + } + if (!(compared === void 0 ? objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack2) : compared)) { + result = false; + break; + } + skipCtor || (skipCtor = key == "constructor"); + } + if (result && !skipCtor) { + var objCtor = object2.constructor, othCtor = other.constructor; + if (objCtor != othCtor && ("constructor" in object2 && "constructor" in other) && !(typeof objCtor == "function" && objCtor instanceof objCtor && typeof othCtor == "function" && othCtor instanceof othCtor)) { + result = false; + } + } + stack2["delete"](object2); + stack2["delete"](other); + return result; + } + function getAllKeys(object2) { + return baseGetAllKeys(object2, keys3, getSymbols); + } + function getMapData2(map, key) { + var data2 = map.__data__; + return isKeyable2(key) ? data2[typeof key == "string" ? "string" : "hash"] : data2.map; + } + function getNative2(object2, key) { + var value = getValue2(object2, key); + return baseIsNative2(value) ? value : void 0; + } + function getRawTag(value) { + var isOwn = hasOwnProperty2.call(value, symToStringTag), tag = value[symToStringTag]; + try { + value[symToStringTag] = void 0; + var unmasked = true; + } catch (e2) { + } + var result = nativeObjectToString.call(value); + if (unmasked) { + if (isOwn) { + value[symToStringTag] = tag; + } else { + delete value[symToStringTag]; + } + } + return result; + } + var getSymbols = !nativeGetSymbols ? stubArray : function(object2) { + if (object2 == null) { + return []; + } + object2 = Object(object2); + return arrayFilter(nativeGetSymbols(object2), function(symbol) { + return propertyIsEnumerable2.call(object2, symbol); + }); + }; + var getTag = baseGetTag; + if (DataView2 && getTag(new DataView2(new ArrayBuffer(1))) != dataViewTag || Map2 && getTag(new Map2()) != mapTag || Promise2 && getTag(Promise2.resolve()) != promiseTag || Set2 && getTag(new Set2()) != setTag || WeakMap2 && getTag(new WeakMap2()) != weakMapTag) { + getTag = function(value) { + var result = baseGetTag(value), Ctor = result == objectTag ? value.constructor : void 0, ctorString = Ctor ? toSource2(Ctor) : ""; + if (ctorString) { + switch (ctorString) { + case dataViewCtorString: + return dataViewTag; + case mapCtorString: + return mapTag; + case promiseCtorString: + return promiseTag; + case setCtorString: + return setTag; + case weakMapCtorString: + return weakMapTag; + } + } + return result; + }; + } + function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER2 : length; + return !!length && (typeof value == "number" || reIsUint.test(value)) && (value > -1 && value % 1 == 0 && value < length); + } + function isKeyable2(value) { + var type = typeof value; + return type == "string" || type == "number" || type == "symbol" || type == "boolean" ? value !== "__proto__" : value === null; + } + function isMasked2(func) { + return !!maskSrcKey2 && maskSrcKey2 in func; + } + function isPrototype(value) { + var Ctor = value && value.constructor, proto = typeof Ctor == "function" && Ctor.prototype || objectProto2; + return value === proto; + } + function objectToString2(value) { + return nativeObjectToString.call(value); + } + function toSource2(func) { + if (func != null) { + try { + return funcToString2.call(func); + } catch (e2) { + } + try { + return func + ""; + } catch (e2) { + } + } + return ""; + } + function eq2(value, other) { + return value === other || value !== value && other !== other; + } + var isArguments = baseIsArguments(/* @__PURE__ */ function() { + return arguments; + }()) ? baseIsArguments : function(value) { + return isObjectLike2(value) && hasOwnProperty2.call(value, "callee") && !propertyIsEnumerable2.call(value, "callee"); + }; + var isArray3 = Array.isArray; + function isArrayLike(value) { + return value != null && isLength(value.length) && !isFunction2(value); + } + var isBuffer = nativeIsBuffer || stubFalse; + function isEqual2(value, other) { + return baseIsEqual(value, other); + } + function isFunction2(value) { + if (!isObject2(value)) { + return false; + } + var tag = baseGetTag(value); + return tag == funcTag2 || tag == genTag2 || tag == asyncTag || tag == proxyTag; + } + function isLength(value) { + return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER2; + } + function isObject2(value) { + var type = typeof value; + return value != null && (type == "object" || type == "function"); + } + function isObjectLike2(value) { + return value != null && typeof value == "object"; + } + var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; + function keys3(object2) { + return isArrayLike(object2) ? arrayLikeKeys(object2) : baseKeys(object2); + } + function stubArray() { + return []; + } + function stubFalse() { + return false; + } + module.exports = isEqual2; +})(lodash_isequal, lodash_isequal.exports); +var lodash_isequalExports = lodash_isequal.exports; +const isEqual = /* @__PURE__ */ getDefaultExportFromCjs(lodash_isequalExports); +function intersectSets(sets) { + if (sets.length === 0) return /* @__PURE__ */ new Set(); + const first = sets[0]; + const rest = sets.slice(1); + const result = /* @__PURE__ */ new Set(); + for (const val of first) { + if (rest.every((set2) => set2.has(val))) { + result.add(val); + } + } + return result; +} +function diffSets(prev, next) { + const result = {}; + for (const val of next) { + if (!prev.has(val)) { + result.added ?? (result.added = /* @__PURE__ */ new Set()); + result.added.add(val); + } + } + for (const val of prev) { + if (!next.has(val)) { + result.removed ?? (result.removed = /* @__PURE__ */ new Set()); + result.removed.add(val); + } + } + return result.added || result.removed ? result : void 0; +} +function objectMatchesQuery(query, object2) { + for (const [key, _matcher] of Object.entries(query)) { + const matcher = _matcher; + const value = object2[key]; + if ("eq" in matcher && value !== matcher.eq) return false; + if ("neq" in matcher && value === matcher.neq) return false; + if ("gt" in matcher && (typeof value !== "number" || value <= matcher.gt)) return false; + } + return true; +} +function executeQuery(store, typeName, query) { + const matchIds = Object.fromEntries(Object.keys(query).map((key) => [key, /* @__PURE__ */ new Set()])); + for (const [k, matcher] of Object.entries(query)) { + if ("eq" in matcher) { + const index2 = store.index(typeName, k); + const ids = index2.get().get(matcher.eq); + if (ids) { + for (const id2 of ids) { + matchIds[k].add(id2); + } + } + } else if ("neq" in matcher) { + const index2 = store.index(typeName, k); + for (const [value, ids] of index2.get()) { + if (value !== matcher.neq) { + for (const id2 of ids) { + matchIds[k].add(id2); + } + } + } + } else if ("gt" in matcher) { + const index2 = store.index(typeName, k); + for (const [value, ids] of index2.get()) { + if (value > matcher.gt) { + for (const id2 of ids) { + matchIds[k].add(id2); + } + } + } + } + } + return intersectSets(Object.values(matchIds)); +} +class StoreQueries { + constructor(atoms, history) { + /** + * A cache of derivations (indexes). + * + * @internal + */ + __publicField(this, "indexCache", /* @__PURE__ */ new Map()); + /** + * A cache of derivations (filtered histories). + * + * @internal + */ + __publicField(this, "historyCache", /* @__PURE__ */ new Map()); + this.atoms = atoms; + this.history = history; + } + /** + * Create a derivation that contains the history for a given type + * + * @param typeName - The name of the type to filter by. + * @returns A derivation that returns the ids of all records of the given type. + * @public + */ + filterHistory(typeName) { + if (this.historyCache.has(typeName)) { + return this.historyCache.get(typeName); + } + const filtered = computed( + "filterHistory:" + typeName, + (lastValue, lastComputedEpoch) => { + if (isUninitialized(lastValue)) { + return this.history.get(); + } + const diff = this.history.getDiffSince(lastComputedEpoch); + if (diff === RESET_VALUE) return this.history.get(); + const res = { added: {}, removed: {}, updated: {} }; + let numAdded = 0; + let numRemoved = 0; + let numUpdated = 0; + for (const changes of diff) { + for (const added of objectMapValues(changes.added)) { + if (added.typeName === typeName) { + if (res.removed[added.id]) { + const original = res.removed[added.id]; + delete res.removed[added.id]; + numRemoved--; + if (original !== added) { + res.updated[added.id] = [original, added]; + numUpdated++; + } + } else { + res.added[added.id] = added; + numAdded++; + } + } + } + for (const [from, to] of objectMapValues(changes.updated)) { + if (to.typeName === typeName) { + if (res.added[to.id]) { + res.added[to.id] = to; + } else if (res.updated[to.id]) { + res.updated[to.id] = [res.updated[to.id][0], to]; + } else { + res.updated[to.id] = [from, to]; + numUpdated++; + } + } + } + for (const removed of objectMapValues(changes.removed)) { + if (removed.typeName === typeName) { + if (res.added[removed.id]) { + delete res.added[removed.id]; + numAdded--; + } else if (res.updated[removed.id]) { + res.removed[removed.id] = res.updated[removed.id][0]; + delete res.updated[removed.id]; + numUpdated--; + numRemoved++; + } else { + res.removed[removed.id] = removed; + numRemoved++; + } + } + } + } + if (numAdded || numRemoved || numUpdated) { + return withDiff(this.history.get(), res); + } else { + return lastValue; + } + }, + { historyLength: 100 } + ); + this.historyCache.set(typeName, filtered); + return filtered; + } + /** + * Create a derivation that returns an index on a property for the given type. + * + * @param typeName - The name of the type. + * @param property - The name of the property. + * @public + */ + index(typeName, property) { + const cacheKey = typeName + ":" + property; + if (this.indexCache.has(cacheKey)) { + return this.indexCache.get(cacheKey); + } + const index2 = this.__uncached_createIndex(typeName, property); + this.indexCache.set(cacheKey, index2); + return index2; + } + /** + * Create a derivation that returns an index on a property for the given type. + * + * @param typeName - The name of the type?. + * @param property - The name of the property?. + * @internal + */ + __uncached_createIndex(typeName, property) { + const typeHistory = this.filterHistory(typeName); + const fromScratch = () => { + typeHistory.get(); + const res = /* @__PURE__ */ new Map(); + for (const atom2 of objectMapValues(this.atoms.get())) { + const record = atom2.get(); + if (record.typeName === typeName) { + const value = record[property]; + if (!res.has(value)) { + res.set(value, /* @__PURE__ */ new Set()); + } + res.get(value).add(record.id); + } + } + return res; + }; + return computed( + "index:" + typeName + ":" + property, + (prevValue, lastComputedEpoch) => { + if (isUninitialized(prevValue)) return fromScratch(); + const history = typeHistory.getDiffSince(lastComputedEpoch); + if (history === RESET_VALUE) { + return fromScratch(); + } + const setConstructors = /* @__PURE__ */ new Map(); + const add = (value, id2) => { + let setConstructor = setConstructors.get(value); + if (!setConstructor) + setConstructor = new IncrementalSetConstructor( + prevValue.get(value) ?? /* @__PURE__ */ new Set() + ); + setConstructor.add(id2); + setConstructors.set(value, setConstructor); + }; + const remove2 = (value, id2) => { + let set2 = setConstructors.get(value); + if (!set2) set2 = new IncrementalSetConstructor(prevValue.get(value) ?? /* @__PURE__ */ new Set()); + set2.remove(id2); + setConstructors.set(value, set2); + }; + for (const changes of history) { + for (const record of objectMapValues(changes.added)) { + if (record.typeName === typeName) { + const value = record[property]; + add(value, record.id); + } + } + for (const [from, to] of objectMapValues(changes.updated)) { + if (to.typeName === typeName) { + const prev = from[property]; + const next = to[property]; + if (prev !== next) { + remove2(prev, to.id); + add(next, to.id); + } + } + } + for (const record of objectMapValues(changes.removed)) { + if (record.typeName === typeName) { + const value = record[property]; + remove2(value, record.id); + } + } + } + let nextValue = void 0; + let nextDiff = void 0; + for (const [value, setConstructor] of setConstructors) { + const result = setConstructor.get(); + if (!result) continue; + if (!nextValue) nextValue = new Map(prevValue); + if (!nextDiff) nextDiff = /* @__PURE__ */ new Map(); + if (result.value.size === 0) { + nextValue.delete(value); + } else { + nextValue.set(value, result.value); + } + nextDiff.set(value, result.diff); + } + if (nextValue && nextDiff) { + return withDiff(nextValue, nextDiff); + } + return prevValue; + }, + { historyLength: 100 } + ); + } + /** + * Create a derivation that will return a signle record matching the given query. + * + * It will return undefined if there is no matching record + * + * @param typeName - The name of the type? + * @param queryCreator - A function that returns the query expression. + * @param name - (optinal) The name of the query. + */ + record(typeName, queryCreator = () => ({}), name = "record:" + typeName + (queryCreator ? ":" + queryCreator.toString() : "")) { + const ids = this.ids(typeName, queryCreator, name); + return computed(name, () => { + var _a3; + for (const id2 of ids.get()) { + return (_a3 = this.atoms.get()[id2]) == null ? void 0 : _a3.get(); + } + return void 0; + }); + } + /** + * Create a derivation that will return an array of records matching the given query + * + * @param typeName - The name of the type? + * @param queryCreator - A function that returns the query expression. + * @param name - (optinal) The name of the query. + */ + records(typeName, queryCreator = () => ({}), name = "records:" + typeName + (queryCreator ? ":" + queryCreator.toString() : "")) { + const ids = this.ids(typeName, queryCreator, "ids:" + name); + return computed(name, () => { + return [...ids.get()].map((id2) => { + const atom2 = this.atoms.get()[id2]; + if (!atom2) { + throw new Error("no atom found for record id: " + id2); + } + return atom2.get(); + }); + }); + } + /** + * Create a derivation that will return the ids of all records of the given type. + * + * @param typeName - The name of the type. + * @param queryCreator - A function that returns the query expression. + * @param name - (optinal) The name of the query. + */ + ids(typeName, queryCreator = () => ({}), name = "ids:" + typeName + (queryCreator ? ":" + queryCreator.toString() : "")) { + const typeHistory = this.filterHistory(typeName); + const fromScratch = () => { + typeHistory.get(); + const query = queryCreator(); + if (Object.keys(query).length === 0) { + return new Set( + objectMapValues(this.atoms.get()).flatMap((v2) => { + const r = v2.get(); + if (r.typeName === typeName) { + return r.id; + } else { + return []; + } + }) + ); + } + return executeQuery(this, typeName, query); + }; + const fromScratchWithDiff = (prevValue) => { + const nextValue = fromScratch(); + const diff = diffSets(prevValue, nextValue); + if (diff) { + return withDiff(nextValue, diff); + } else { + return prevValue; + } + }; + const cachedQuery = computed("ids_query:" + name, queryCreator, { + isEqual + }); + return computed( + "query:" + name, + (prevValue, lastComputedEpoch) => { + const query = cachedQuery.get(); + if (isUninitialized(prevValue)) { + return fromScratch(); + } + if (lastComputedEpoch < cachedQuery.lastChangedEpoch) { + return fromScratchWithDiff(prevValue); + } + const history = typeHistory.getDiffSince(lastComputedEpoch); + if (history === RESET_VALUE) { + return fromScratchWithDiff(prevValue); + } + const setConstructor = new IncrementalSetConstructor( + prevValue + ); + for (const changes of history) { + for (const added of objectMapValues(changes.added)) { + if (added.typeName === typeName && objectMatchesQuery(query, added)) { + setConstructor.add(added.id); + } + } + for (const [_2, updated] of objectMapValues(changes.updated)) { + if (updated.typeName === typeName) { + if (objectMatchesQuery(query, updated)) { + setConstructor.add(updated.id); + } else { + setConstructor.remove(updated.id); + } + } + } + for (const removed of objectMapValues(changes.removed)) { + if (removed.typeName === typeName) { + setConstructor.remove(removed.id); + } + } + } + const result = setConstructor.get(); + if (!result) { + return prevValue; + } + return withDiff(result.value, result.diff); + }, + { historyLength: 50 } + ); + } + exec(typeName, query) { + const ids = executeQuery(this, typeName, query); + if (ids.size === 0) { + return EMPTY_ARRAY; + } + const atoms = this.atoms.get(); + return [...ids].map((id2) => atoms[id2].get()); + } +} +class StoreSideEffects { + constructor(store) { + __publicField(this, "_beforeCreateHandlers", {}); + __publicField(this, "_afterCreateHandlers", {}); + __publicField(this, "_beforeChangeHandlers", {}); + __publicField(this, "_afterChangeHandlers", {}); + __publicField(this, "_beforeDeleteHandlers", {}); + __publicField(this, "_afterDeleteHandlers", {}); + __publicField(this, "_operationCompleteHandlers", []); + __publicField(this, "_isEnabled", true); + this.store = store; + } + /** @internal */ + isEnabled() { + return this._isEnabled; + } + /** @internal */ + setIsEnabled(enabled) { + this._isEnabled = enabled; + } + /** @internal */ + handleBeforeCreate(record, source) { + if (!this._isEnabled) return record; + const handlers = this._beforeCreateHandlers[record.typeName]; + if (handlers) { + let r = record; + for (const handler of handlers) { + r = handler(r, source); + } + return r; + } + return record; + } + /** @internal */ + handleAfterCreate(record, source) { + if (!this._isEnabled) return; + const handlers = this._afterCreateHandlers[record.typeName]; + if (handlers) { + for (const handler of handlers) { + handler(record, source); + } + } + } + /** @internal */ + handleBeforeChange(prev, next, source) { + if (!this._isEnabled) return next; + const handlers = this._beforeChangeHandlers[next.typeName]; + if (handlers) { + let r = next; + for (const handler of handlers) { + r = handler(prev, r, source); + } + return r; + } + return next; + } + /** @internal */ + handleAfterChange(prev, next, source) { + if (!this._isEnabled) return; + const handlers = this._afterChangeHandlers[next.typeName]; + if (handlers) { + for (const handler of handlers) { + handler(prev, next, source); + } + } + } + /** @internal */ + handleBeforeDelete(record, source) { + if (!this._isEnabled) return true; + const handlers = this._beforeDeleteHandlers[record.typeName]; + if (handlers) { + for (const handler of handlers) { + if (handler(record, source) === false) { + return false; + } + } + } + return true; + } + /** @internal */ + handleAfterDelete(record, source) { + if (!this._isEnabled) return; + const handlers = this._afterDeleteHandlers[record.typeName]; + if (handlers) { + for (const handler of handlers) { + handler(record, source); + } + } + } + /** @internal */ + handleOperationComplete(source) { + if (!this._isEnabled) return; + for (const handler of this._operationCompleteHandlers) { + handler(source); + } + } + /** + * Internal helper for registering a bunch of side effects at once and keeping them organized. + * @internal + */ + register(handlersByType) { + const disposes = []; + for (const [type, handlers] of Object.entries(handlersByType)) { + if (handlers == null ? void 0 : handlers.beforeCreate) { + disposes.push(this.registerBeforeCreateHandler(type, handlers.beforeCreate)); + } + if (handlers == null ? void 0 : handlers.afterCreate) { + disposes.push(this.registerAfterCreateHandler(type, handlers.afterCreate)); + } + if (handlers == null ? void 0 : handlers.beforeChange) { + disposes.push(this.registerBeforeChangeHandler(type, handlers.beforeChange)); + } + if (handlers == null ? void 0 : handlers.afterChange) { + disposes.push(this.registerAfterChangeHandler(type, handlers.afterChange)); + } + if (handlers == null ? void 0 : handlers.beforeDelete) { + disposes.push(this.registerBeforeDeleteHandler(type, handlers.beforeDelete)); + } + if (handlers == null ? void 0 : handlers.afterDelete) { + disposes.push(this.registerAfterDeleteHandler(type, handlers.afterDelete)); + } + } + return () => { + for (const dispose of disposes) dispose(); + }; + } + /** + * Register a handler to be called before a record of a certain type is created. Return a + * modified record from the handler to change the record that will be created. + * + * Use this handle only to modify the creation of the record itself. If you want to trigger a + * side-effect on a different record (for example, moving one shape when another is created), + * use {@link StoreSideEffects.registerAfterCreateHandler} instead. + * + * @example + * ```ts + * editor.sideEffects.registerBeforeCreateHandler('shape', (shape, source) => { + * // only modify shapes created by the user + * if (source !== 'user') return shape + * + * //by default, arrow shapes have no label. Let's make sure they always have a label. + * if (shape.type === 'arrow') { + * return {...shape, props: {...shape.props, text: 'an arrow'}} + * } + * + * // other shapes get returned unmodified + * return shape + * }) + * ``` + * + * @param typeName - The type of record to listen for + * @param handler - The handler to call + * + * @returns A callback that removes the handler. + */ + registerBeforeCreateHandler(typeName, handler) { + const handlers = this._beforeCreateHandlers[typeName]; + if (!handlers) this._beforeCreateHandlers[typeName] = []; + this._beforeCreateHandlers[typeName].push(handler); + return () => remove(this._beforeCreateHandlers[typeName], handler); + } + /** + * Register a handler to be called after a record is created. This is useful for side-effects + * that would update _other_ records. If you want to modify the record being created use + * {@link StoreSideEffects.registerBeforeCreateHandler} instead. + * + * @example + * ```ts + * editor.sideEffects.registerAfterCreateHandler('page', (page, source) => { + * // Automatically create a shape when a page is created + * editor.createShape({ + * id: createShapeId(), + * type: 'text', + * props: { text: page.name }, + * }) + * }) + * ``` + * + * @param typeName - The type of record to listen for + * @param handler - The handler to call + * + * @returns A callback that removes the handler. + */ + registerAfterCreateHandler(typeName, handler) { + const handlers = this._afterCreateHandlers[typeName]; + if (!handlers) this._afterCreateHandlers[typeName] = []; + this._afterCreateHandlers[typeName].push(handler); + return () => remove(this._afterCreateHandlers[typeName], handler); + } + /** + * Register a handler to be called before a record is changed. The handler is given the old and + * new record - you can return a modified record to apply a different update, or the old record + * to block the update entirely. + * + * Use this handler only for intercepting updates to the record itself. If you want to update + * other records in response to a change, use + * {@link StoreSideEffects.registerAfterChangeHandler} instead. + * + * @example + * ```ts + * editor.sideEffects.registerBeforeChangeHandler('shape', (prev, next, source) => { + * if (next.isLocked && !prev.isLocked) { + * // prevent shapes from ever being locked: + * return prev + * } + * // other types of change are allowed + * return next + * }) + * ``` + * + * @param typeName - The type of record to listen for + * @param handler - The handler to call + * + * @returns A callback that removes the handler. + */ + registerBeforeChangeHandler(typeName, handler) { + const handlers = this._beforeChangeHandlers[typeName]; + if (!handlers) this._beforeChangeHandlers[typeName] = []; + this._beforeChangeHandlers[typeName].push(handler); + return () => remove(this._beforeChangeHandlers[typeName], handler); + } + /** + * Register a handler to be called after a record is changed. This is useful for side-effects + * that would update _other_ records - if you want to modify the record being changed, use + * {@link StoreSideEffects.registerBeforeChangeHandler} instead. + * + * @example + * ```ts + * editor.sideEffects.registerAfterChangeHandler('shape', (prev, next, source) => { + * if (next.props.color === 'red') { + * // there can only be one red shape at a time: + * const otherRedShapes = editor.getCurrentPageShapes().filter(s => s.props.color === 'red' && s.id !== next.id) + * editor.updateShapes(otherRedShapes.map(s => ({...s, props: {...s.props, color: 'blue'}}))) + * } + * }) + * ``` + * + * @param typeName - The type of record to listen for + * @param handler - The handler to call + * + * @returns A callback that removes the handler. + */ + registerAfterChangeHandler(typeName, handler) { + const handlers = this._afterChangeHandlers[typeName]; + if (!handlers) this._afterChangeHandlers[typeName] = []; + this._afterChangeHandlers[typeName].push(handler); + return () => remove(this._afterChangeHandlers[typeName], handler); + } + /** + * Register a handler to be called before a record is deleted. The handler can return `false` to + * prevent the deletion. + * + * Use this handler only for intercepting deletions of the record itself. If you want to do + * something to other records in response to a deletion, use + * {@link StoreSideEffects.registerAfterDeleteHandler} instead. + * + * @example + * ```ts + * editor.sideEffects.registerBeforeDeleteHandler('shape', (shape, source) => { + * if (shape.props.color === 'red') { + * // prevent red shapes from being deleted + * return false + * } + * }) + * ``` + * + * @param typeName - The type of record to listen for + * @param handler - The handler to call + * + * @returns A callback that removes the handler. + */ + registerBeforeDeleteHandler(typeName, handler) { + const handlers = this._beforeDeleteHandlers[typeName]; + if (!handlers) this._beforeDeleteHandlers[typeName] = []; + this._beforeDeleteHandlers[typeName].push(handler); + return () => remove(this._beforeDeleteHandlers[typeName], handler); + } + /** + * Register a handler to be called after a record is deleted. This is useful for side-effects + * that would update _other_ records - if you want to block the deletion of the record itself, + * use {@link StoreSideEffects.registerBeforeDeleteHandler} instead. + * + * @example + * ```ts + * editor.sideEffects.registerAfterDeleteHandler('shape', (shape, source) => { + * // if the last shape in a frame is deleted, delete the frame too: + * const parentFrame = editor.getShape(shape.parentId) + * if (!parentFrame || parentFrame.type !== 'frame') return + * + * const siblings = editor.getSortedChildIdsForParent(parentFrame) + * if (siblings.length === 0) { + * editor.deleteShape(parentFrame.id) + * } + * }) + * ``` + * + * @param typeName - The type of record to listen for + * @param handler - The handler to call + * + * @returns A callback that removes the handler. + */ + registerAfterDeleteHandler(typeName, handler) { + const handlers = this._afterDeleteHandlers[typeName]; + if (!handlers) this._afterDeleteHandlers[typeName] = []; + this._afterDeleteHandlers[typeName].push(handler); + return () => remove(this._afterDeleteHandlers[typeName], handler); + } + /** + * Register a handler to be called when a store completes an atomic operation. + * + * @example + * ```ts + * let count = 0 + * + * editor.sideEffects.registerOperationCompleteHandler(() => count++) + * + * editor.selectAll() + * expect(count).toBe(1) + * + * editor.store.atomic(() => { + * editor.selectNone() + * editor.selectAll() + * }) + * + * expect(count).toBe(2) + * ``` + * + * @param handler - The handler to call + * + * @returns A callback that removes the handler. + * + * @public + */ + registerOperationCompleteHandler(handler) { + this._operationCompleteHandlers.push(handler); + return () => remove(this._operationCompleteHandlers, handler); + } +} +function remove(array2, item) { + const index2 = array2.indexOf(item); + if (index2 >= 0) { + array2.splice(index2, 1); + } +} +function devFreeze(object2) { + const proto = Object.getPrototypeOf(object2); + if (proto && !(Array.isArray(object2) || proto === Object.prototype || proto === null || proto === STRUCTURED_CLONE_OBJECT_PROTOTYPE)) { + console.error("cannot include non-js data in a record", object2); + throw new Error("cannot include non-js data in a record"); + } + const propNames = Object.getOwnPropertyNames(object2); + for (const name of propNames) { + const value = object2[name]; + if (value && typeof value === "object") { + devFreeze(value); + } + } + return Object.freeze(object2); +} +class Store { + constructor(config) { + /** + * The random id of the store. + */ + __publicField(this, "id"); + /** + * An atom containing the store's atoms. + * + * @internal + * @readonly + */ + __publicField(this, "atoms", atom("store_atoms", {})); + /** + * An atom containing the store's history. + * + * @public + * @readonly + */ + __publicField(this, "history", atom("history", 0, { + historyLength: 1e3 + })); + /** + * A StoreQueries instance for this store. + * + * @public + * @readonly + */ + __publicField(this, "query", new StoreQueries(this.atoms, this.history)); + /** + * A set containing listeners that have been added to this store. + * + * @internal + */ + __publicField(this, "listeners", /* @__PURE__ */ new Set()); + /** + * An array of history entries that have not yet been flushed. + * + * @internal + */ + __publicField(this, "historyAccumulator", new HistoryAccumulator()); + /** + * A reactor that responds to changes to the history by squashing the accumulated history and + * notifying listeners of the changes. + * + * @internal + */ + __publicField(this, "historyReactor"); + __publicField(this, "schema"); + __publicField(this, "props"); + __publicField(this, "scopedTypes"); + __publicField(this, "sideEffects", new StoreSideEffects(this)); + __publicField(this, "isMergingRemoteChanges", false); + __publicField(this, "_integrityChecker"); + __publicField(this, "_isPossiblyCorrupted", false); + __publicField(this, "pendingAfterEvents", null); + __publicField(this, "_isInAtomicOp", false); + const { initialData, schema, id: id2 } = config; + this.id = id2 ?? uniqueId(); + this.schema = schema; + this.props = config.props; + if (initialData) { + this.atoms.set( + objectMapFromEntries( + objectMapEntries(initialData).map(([id22, record]) => [ + id22, + atom( + "atom:" + id22, + devFreeze(this.schema.validateRecord(this, record, "initialize", null)) + ) + ]) + ) + ); + } + this.historyReactor = reactor( + "Store.historyReactor", + () => { + this.history.get(); + this._flushHistory(); + }, + { scheduleEffect: (cb) => this.cancelHistoryReactor = throttleToNextFrame$1(cb) } + ); + this.scopedTypes = { + document: new Set( + objectMapValues(this.schema.types).filter((t2) => t2.scope === "document").map((t2) => t2.typeName) + ), + session: new Set( + objectMapValues(this.schema.types).filter((t2) => t2.scope === "session").map((t2) => t2.typeName) + ), + presence: new Set( + objectMapValues(this.schema.types).filter((t2) => t2.scope === "presence").map((t2) => t2.typeName) + ) + }; + } + /** + * Function to dispose of any in-flight timeouts. + * + * @internal + */ + cancelHistoryReactor() { + } + _flushHistory() { + if (this.historyAccumulator.hasChanges()) { + const entries = this.historyAccumulator.flush(); + for (const { changes, source } of entries) { + let instanceChanges = null; + let documentChanges = null; + let presenceChanges = null; + for (const { onHistory, filters } of this.listeners) { + if (filters.source !== "all" && filters.source !== source) { + continue; + } + if (filters.scope !== "all") { + if (filters.scope === "document") { + documentChanges ?? (documentChanges = this.filterChangesByScope(changes, "document")); + if (!documentChanges) continue; + onHistory({ changes: documentChanges, source }); + } else if (filters.scope === "session") { + instanceChanges ?? (instanceChanges = this.filterChangesByScope(changes, "session")); + if (!instanceChanges) continue; + onHistory({ changes: instanceChanges, source }); + } else { + presenceChanges ?? (presenceChanges = this.filterChangesByScope(changes, "presence")); + if (!presenceChanges) continue; + onHistory({ changes: presenceChanges, source }); + } + } else { + onHistory({ changes, source }); + } + } + } + } + } + dispose() { + this.cancelHistoryReactor(); + } + /** + * Filters out non-document changes from a diff. Returns null if there are no changes left. + * @param change - the records diff + * @param scope - the records scope + * @returns + */ + filterChangesByScope(change, scope) { + const result = { + added: filterEntries(change.added, (_2, r) => this.scopedTypes[scope].has(r.typeName)), + updated: filterEntries(change.updated, (_2, r) => this.scopedTypes[scope].has(r[1].typeName)), + removed: filterEntries(change.removed, (_2, r) => this.scopedTypes[scope].has(r.typeName)) + }; + if (Object.keys(result.added).length === 0 && Object.keys(result.updated).length === 0 && Object.keys(result.removed).length === 0) { + return null; + } + return result; + } + /** + * Update the history with a diff of changes. + * + * @param changes - The changes to add to the history. + */ + updateHistory(changes) { + this.historyAccumulator.add({ + changes, + source: this.isMergingRemoteChanges ? "remote" : "user" + }); + if (this.listeners.size === 0) { + this.historyAccumulator.clear(); + } + this.history.set(this.history.get() + 1, changes); + } + validate(phase) { + this.allRecords().forEach((record) => this.schema.validateRecord(this, record, phase, null)); + } + /** + * Add some records to the store. It's an error if they already exist. + * + * @param records - The records to add. + * @param phaseOverride - The phase override. + * @public + */ + put(records, phaseOverride) { + this.atomic(() => { + const updates = {}; + const additions = {}; + const currentMap = this.atoms.__unsafe__getWithoutCapture(); + let map = null; + let record; + let didChange = false; + const source = this.isMergingRemoteChanges ? "remote" : "user"; + for (let i2 = 0, n = records.length; i2 < n; i2++) { + record = records[i2]; + const recordAtom = (map ?? currentMap)[record.id]; + if (recordAtom) { + const initialValue = recordAtom.__unsafe__getWithoutCapture(); + record = this.sideEffects.handleBeforeChange(initialValue, record, source); + const validated = this.schema.validateRecord( + this, + record, + phaseOverride ?? "updateRecord", + initialValue + ); + if (validated === initialValue) continue; + recordAtom.set(devFreeze(record)); + didChange = true; + const updated = recordAtom.__unsafe__getWithoutCapture(); + updates[record.id] = [initialValue, updated]; + this.addDiffForAfterEvent(initialValue, updated); + } else { + record = this.sideEffects.handleBeforeCreate(record, source); + didChange = true; + record = this.schema.validateRecord( + this, + record, + phaseOverride ?? "createRecord", + null + ); + additions[record.id] = record; + this.addDiffForAfterEvent(null, record); + if (!map) { + map = { ...currentMap }; + } + map[record.id] = atom("atom:" + record.id, record); + } + } + if (map) { + this.atoms.set(map); + } + if (!didChange) return; + this.updateHistory({ + added: additions, + updated: updates, + removed: {} + }); + }); + } + /** + * Remove some records from the store via their ids. + * + * @param ids - The ids of the records to remove. + * @public + */ + remove(ids) { + this.atomic(() => { + const cancelled = /* @__PURE__ */ new Set(); + const source = this.isMergingRemoteChanges ? "remote" : "user"; + if (this.sideEffects.isEnabled()) { + for (const id2 of ids) { + const atom2 = this.atoms.__unsafe__getWithoutCapture()[id2]; + if (!atom2) continue; + if (this.sideEffects.handleBeforeDelete(atom2.get(), source) === false) { + cancelled.add(id2); + } + } + } + let removed = void 0; + this.atoms.update((atoms) => { + let result = void 0; + for (const id2 of ids) { + if (cancelled.has(id2)) continue; + if (!(id2 in atoms)) continue; + if (!result) result = { ...atoms }; + if (!removed) removed = {}; + delete result[id2]; + const record = atoms[id2].get(); + removed[id2] = record; + this.addDiffForAfterEvent(record, null); + } + return result ?? atoms; + }); + if (!removed) return; + this.updateHistory({ added: {}, updated: {}, removed }); + }); + } + /** + * Get the value of a store record by its id. + * + * @param id - The id of the record to get. + * @public + */ + get(id2) { + var _a3; + return (_a3 = this.atoms.get()[id2]) == null ? void 0 : _a3.get(); + } + /** + * Get the value of a store record by its id without updating its epoch. + * + * @param id - The id of the record to get. + * @public + */ + unsafeGetWithoutCapture(id2) { + var _a3; + return (_a3 = this.atoms.__unsafe__getWithoutCapture()[id2]) == null ? void 0 : _a3.__unsafe__getWithoutCapture(); + } + /** + * Creates a JSON payload from the record store. + * + * @param scope - The scope of records to serialize. Defaults to 'document'. + * @returns The record store snapshot as a JSON payload. + */ + serialize(scope = "document") { + const result = {}; + for (const [id2, atom2] of objectMapEntries(this.atoms.get())) { + const record = atom2.get(); + if (scope === "all" || this.scopedTypes[scope].has(record.typeName)) { + result[id2] = record; + } + } + return result; + } + /** + * Get a serialized snapshot of the store and its schema. + * + * ```ts + * const snapshot = store.getStoreSnapshot() + * store.loadStoreSnapshot(snapshot) + * ``` + * + * @param scope - The scope of records to serialize. Defaults to 'document'. + * + * @public + */ + getStoreSnapshot(scope = "document") { + return { + store: this.serialize(scope), + schema: this.schema.serialize() + }; + } + /** + * @deprecated use `getSnapshot` from the 'tldraw' package instead. + */ + getSnapshot(scope = "document") { + console.warn( + "[tldraw] `Store.getSnapshot` is deprecated and will be removed in a future release. Use `getSnapshot` from the `tldraw` package instead." + ); + return this.getStoreSnapshot(scope); + } + /** + * Migrate a serialized snapshot of the store and its schema. + * + * ```ts + * const snapshot = store.getSnapshot() + * store.migrateSnapshot(snapshot) + * ``` + * + * @param snapshot - The snapshot to load. + * @public + */ + migrateSnapshot(snapshot) { + const migrationResult = this.schema.migrateStoreSnapshot(snapshot); + if (migrationResult.type === "error") { + throw new Error(`Failed to migrate snapshot: ${migrationResult.reason}`); + } + return { + store: migrationResult.value, + schema: this.schema.serialize() + }; + } + /** + * Load a serialized snapshot. + * + * ```ts + * const snapshot = store.getStoreSnapshot() + * store.loadStoreSnapshot(snapshot) + * ``` + * + * @param snapshot - The snapshot to load. + * @public + */ + loadStoreSnapshot(snapshot) { + const migrationResult = this.schema.migrateStoreSnapshot(snapshot); + if (migrationResult.type === "error") { + throw new Error(`Failed to migrate snapshot: ${migrationResult.reason}`); + } + const prevSideEffectsEnabled = this.sideEffects.isEnabled(); + try { + this.sideEffects.setIsEnabled(false); + this.atomic(() => { + this.clear(); + this.put(Object.values(migrationResult.value)); + this.ensureStoreIsUsable(); + }); + } finally { + this.sideEffects.setIsEnabled(prevSideEffectsEnabled); + } + } + /** + * @public + * @deprecated use `loadSnapshot` from the 'tldraw' package instead. + */ + loadSnapshot(snapshot) { + console.warn( + "[tldraw] `Store.loadSnapshot` is deprecated and will be removed in a future release. Use `loadSnapshot` from the 'tldraw' package instead." + ); + this.loadStoreSnapshot(snapshot); + } + /** + * Get an array of all values in the store. + * + * @returns An array of all values in the store. + * @public + */ + allRecords() { + return objectMapValues(this.atoms.get()).map((atom2) => atom2.get()); + } + /** + * Removes all records from the store. + * + * @public + */ + clear() { + this.remove(objectMapKeys(this.atoms.get())); + } + /** + * Update a record. To update multiple records at once, use the `update` method of the + * `TypedStore` class. + * + * @param id - The id of the record to update. + * @param updater - A function that updates the record. + */ + update(id2, updater) { + const atom2 = this.atoms.get()[id2]; + if (!atom2) { + console.error(`Record ${id2} not found. This is probably an error`); + return; + } + this.put([updater(atom2.__unsafe__getWithoutCapture())]); + } + /** + * Get whether the record store has a id. + * + * @param id - The id of the record to check. + * @public + */ + has(id2) { + return !!this.atoms.get()[id2]; + } + /** + * Add a new listener to the store. + * + * @param onHistory - The listener to call when the store updates. + * @param filters - Filters to apply to the listener. + * @returns A function to remove the listener. + */ + listen(onHistory, filters) { + this._flushHistory(); + const listener = { + onHistory, + filters: { + source: (filters == null ? void 0 : filters.source) ?? "all", + scope: (filters == null ? void 0 : filters.scope) ?? "all" + } + }; + this.listeners.add(listener); + if (!this.historyReactor.scheduler.isActivelyListening) { + this.historyReactor.start(); + } + return () => { + this.listeners.delete(listener); + if (this.listeners.size === 0) { + this.historyReactor.stop(); + } + }; + } + /** + * Merge changes from a remote source without triggering listeners. + * + * @param fn - A function that merges the external changes. + * @public + */ + mergeRemoteChanges(fn) { + if (this.isMergingRemoteChanges) { + return fn(); + } + if (this._isInAtomicOp) { + throw new Error("Cannot merge remote changes while in atomic operation"); + } + try { + this.isMergingRemoteChanges = true; + transact(fn); + } finally { + this.isMergingRemoteChanges = false; + } + } + /** + * Run `fn` and return a {@link RecordsDiff} of the changes that occurred as a result. + */ + extractingChanges(fn) { + const changes = []; + const dispose = this.historyAccumulator.addInterceptor((entry2) => changes.push(entry2.changes)); + try { + transact(fn); + return squashRecordDiffs(changes); + } finally { + dispose(); + } + } + applyDiff(diff, { + runCallbacks = true, + ignoreEphemeralKeys = false + } = {}) { + this.atomic(() => { + const toPut = objectMapValues(diff.added); + for (const [_from, to] of objectMapValues(diff.updated)) { + const type = this.schema.getType(to.typeName); + if (ignoreEphemeralKeys && type.ephemeralKeySet.size) { + const existing = this.get(to.id); + if (!existing) { + toPut.push(to); + continue; + } + let changed = null; + for (const [key, value] of Object.entries(to)) { + if (type.ephemeralKeySet.has(key) || Object.is(value, getOwnProperty(existing, key))) { + continue; + } + if (!changed) changed = { ...existing }; + changed[key] = value; + } + if (changed) toPut.push(changed); + } else { + toPut.push(to); + } + } + const toRemove = objectMapKeys(diff.removed); + if (toPut.length) { + this.put(toPut); + } + if (toRemove.length) { + this.remove(toRemove); + } + }, runCallbacks); + } + /** + * Create a computed cache. + * + * @param name - The name of the derivation cache. + * @param derive - A function used to derive the value of the cache. + * @param isEqual - A function that determins equality between two records. + * @public + */ + createComputedCache(name, derive, isEqual2) { + const cache = new WeakCache(); + return { + get: (id2) => { + const atom2 = this.atoms.get()[id2]; + if (!atom2) { + return void 0; + } + return cache.get(atom2, () => { + const recordSignal = isEqual2 ? computed(atom2.name + ":equals", () => atom2.get(), { isEqual: isEqual2 }) : atom2; + return computed(name + ":" + id2, () => { + return derive(recordSignal.get()); + }); + }).get(); + } + }; + } + /** + * Create a computed cache from a selector + * + * @param name - The name of the derivation cache. + * @param selector - A function that returns a subset of the original shape + * @param derive - A function used to derive the value of the cache. + * @public + */ + createSelectedComputedCache(name, selector, derive) { + const cache = new WeakCache(); + return { + get: (id2) => { + const atom2 = this.atoms.get()[id2]; + if (!atom2) { + return void 0; + } + return cache.get(atom2, () => { + const d2 = computed( + name + ":" + id2 + ":selector", + () => selector(atom2.get()) + ); + return computed(name + ":" + id2, () => derive(d2.get())); + }).get(); + } + }; + } + /** @internal */ + ensureStoreIsUsable() { + this.atomic(() => { + var _a3; + this._integrityChecker ?? (this._integrityChecker = this.schema.createIntegrityChecker(this)); + (_a3 = this._integrityChecker) == null ? void 0 : _a3.call(this); + }); + } + /** @internal */ + markAsPossiblyCorrupted() { + this._isPossiblyCorrupted = true; + } + /** @internal */ + isPossiblyCorrupted() { + return this._isPossiblyCorrupted; + } + addDiffForAfterEvent(before, after) { + assert(this.pendingAfterEvents, "must be in event operation"); + if (before === after) return; + if (before && after) assert(before.id === after.id); + if (!before && !after) return; + const id2 = (before || after).id; + const existing = this.pendingAfterEvents.get(id2); + if (existing) { + existing.after = after; + } else { + this.pendingAfterEvents.set(id2, { before, after }); + } + } + flushAtomicCallbacks() { + let updateDepth = 0; + const source = this.isMergingRemoteChanges ? "remote" : "user"; + while (this.pendingAfterEvents) { + const events = this.pendingAfterEvents; + this.pendingAfterEvents = null; + if (!this.sideEffects.isEnabled()) continue; + updateDepth++; + if (updateDepth > 100) { + throw new Error("Maximum store update depth exceeded, bailing out"); + } + for (const { before, after } of events.values()) { + if (before && after) { + this.sideEffects.handleAfterChange(before, after, source); + } else if (before && !after) { + this.sideEffects.handleAfterDelete(before, source); + } else if (!before && after) { + this.sideEffects.handleAfterCreate(after, source); + } + } + if (!this.pendingAfterEvents) { + this.sideEffects.handleOperationComplete(source); + } + } + } + /** @internal */ + atomic(fn, runCallbacks = true) { + return transact(() => { + if (this._isInAtomicOp) { + if (!this.pendingAfterEvents) this.pendingAfterEvents = /* @__PURE__ */ new Map(); + return fn(); + } + this.pendingAfterEvents = /* @__PURE__ */ new Map(); + const prevSideEffectsEnabled = this.sideEffects.isEnabled(); + this.sideEffects.setIsEnabled(runCallbacks ?? prevSideEffectsEnabled); + this._isInAtomicOp = true; + try { + const result = fn(); + this.flushAtomicCallbacks(); + return result; + } finally { + this.pendingAfterEvents = null; + this.sideEffects.setIsEnabled(prevSideEffectsEnabled); + this._isInAtomicOp = false; + } + }); + } + /** @internal */ + addHistoryInterceptor(fn) { + return this.historyAccumulator.addInterceptor( + (entry2) => fn(entry2, this.isMergingRemoteChanges ? "remote" : "user") + ); + } +} +function squashHistoryEntries(entries) { + if (entries.length === 0) return []; + const chunked = []; + let chunk = [entries[0]]; + let entry2; + for (let i2 = 1, n = entries.length; i2 < n; i2++) { + entry2 = entries[i2]; + if (chunk[0].source !== entry2.source) { + chunked.push(chunk); + chunk = []; + } + chunk.push(entry2); + } + chunked.push(chunk); + return devFreeze( + chunked.map((chunk2) => ({ + source: chunk2[0].source, + changes: squashRecordDiffs(chunk2.map((e2) => e2.changes)) + })) + ); +} +class HistoryAccumulator { + constructor() { + __publicField(this, "_history", []); + __publicField(this, "_interceptors", /* @__PURE__ */ new Set()); + } + addInterceptor(fn) { + this._interceptors.add(fn); + return () => { + this._interceptors.delete(fn); + }; + } + add(entry2) { + this._history.push(entry2); + for (const interceptor of this._interceptors) { + interceptor(entry2); + } + } + flush() { + const history = squashHistoryEntries(this._history); + this._history = []; + return history; + } + clear() { + this._history = []; + } + hasChanges() { + return this._history.length > 0; + } +} +function createComputedCache(name, derive, isEqual2) { + const cache = new WeakCache(); + return { + get(context, id2) { + const computedCache = cache.get(context, () => { + const store = context instanceof Store ? context : context.store; + return store.createComputedCache(name, (record) => derive(context, record), isEqual2); + }); + return computedCache.get(id2); + } + }; +} +function squashDependsOn(sequence) { + const result = []; + for (let i2 = sequence.length - 1; i2 >= 0; i2--) { + const elem = sequence[i2]; + if (!("id" in elem)) { + const dependsOn = elem.dependsOn; + const prev = result[0]; + if (prev) { + result[0] = { + ...prev, + dependsOn: dependsOn.concat(prev.dependsOn ?? []) + }; + } + } else { + result.unshift(elem); + } + } + return result; +} +function createMigrationSequence({ + sequence, + sequenceId, + retroactive = true +}) { + const migrations = { + sequenceId, + retroactive, + sequence: squashDependsOn(sequence) + }; + validateMigrations(migrations); + return migrations; +} +function createMigrationIds(sequenceId, versions2) { + return Object.fromEntries( + objectMapEntries(versions2).map(([key, version2]) => [key, `${sequenceId}/${version2}`]) + ); +} +function createRecordMigrationSequence(opts) { + const sequenceId = opts.sequenceId; + return createMigrationSequence({ + sequenceId, + retroactive: opts.retroactive ?? true, + sequence: opts.sequence.map( + (m2) => "id" in m2 ? { + ...m2, + scope: "record", + filter: (r) => { + var _a3, _b2; + return r.typeName === opts.recordType && (((_a3 = m2.filter) == null ? void 0 : _a3.call(m2, r)) ?? true) && (((_b2 = opts.filter) == null ? void 0 : _b2.call(opts, r)) ?? true); + } + } : m2 + ) + }); +} +function sortMigrations(migrations) { + const byId = new Map(migrations.map((m2) => [m2.id, m2])); + const isProcessing = /* @__PURE__ */ new Set(); + const result = []; + function process2(m2) { + assert(!isProcessing.has(m2.id), `Circular dependency in migrations: ${m2.id}`); + isProcessing.add(m2.id); + const { version: version2, sequenceId } = parseMigrationId(m2.id); + const parent = byId.get(`${sequenceId}/${version2 - 1}`); + if (parent) { + process2(parent); + } + if (m2.dependsOn) { + for (const dep of m2.dependsOn) { + const depMigration = byId.get(dep); + if (depMigration) { + process2(depMigration); + } + } + } + byId.delete(m2.id); + result.push(m2); + } + for (const m2 of byId.values()) { + process2(m2); + } + return result; +} +function parseMigrationId(id2) { + const [sequenceId, version2] = id2.split("/"); + return { sequenceId, version: parseInt(version2) }; +} +function validateMigrationId(id2, expectedSequenceId) { + if (expectedSequenceId) { + assert( + id2.startsWith(expectedSequenceId + "/"), + `Every migration in sequence '${expectedSequenceId}' must have an id starting with '${expectedSequenceId}/'. Got invalid id: '${id2}'` + ); + } + assert(id2.match(/^(.*?)\/(0|[1-9]\d*)$/), `Invalid migration id: '${id2}'`); +} +function validateMigrations(migrations) { + assert( + !migrations.sequenceId.includes("/"), + `sequenceId cannot contain a '/', got ${migrations.sequenceId}` + ); + assert(migrations.sequenceId.length, "sequenceId must be a non-empty string"); + if (migrations.sequence.length === 0) { + return; + } + validateMigrationId(migrations.sequence[0].id, migrations.sequenceId); + let n = parseMigrationId(migrations.sequence[0].id).version; + assert( + n === 1, + `Expected the first migrationId to be '${migrations.sequenceId}/1' but got '${migrations.sequence[0].id}'` + ); + for (let i2 = 1; i2 < migrations.sequence.length; i2++) { + const id2 = migrations.sequence[i2].id; + validateMigrationId(id2, migrations.sequenceId); + const m2 = parseMigrationId(id2).version; + assert( + m2 === n + 1, + `Migration id numbers must increase in increments of 1, expected ${migrations.sequenceId}/${n + 1} but got '${migrations.sequence[i2].id}'` + ); + n = m2; + } +} +var MigrationFailureReason = /* @__PURE__ */ ((MigrationFailureReason2) => { + MigrationFailureReason2["IncompatibleSubtype"] = "incompatible-subtype"; + MigrationFailureReason2["UnknownType"] = "unknown-type"; + MigrationFailureReason2["TargetVersionTooNew"] = "target-version-too-new"; + MigrationFailureReason2["TargetVersionTooOld"] = "target-version-too-old"; + MigrationFailureReason2["MigrationError"] = "migration-error"; + MigrationFailureReason2["UnrecognizedSubtype"] = "unrecognized-subtype"; + return MigrationFailureReason2; +})(MigrationFailureReason || {}); +function upgradeSchema(schema) { + if (schema.schemaVersion > 2 || schema.schemaVersion < 1) return Result.err("Bad schema version"); + if (schema.schemaVersion === 2) return Result.ok(schema); + const result = { + schemaVersion: 2, + sequences: { + "com.tldraw.store": schema.storeVersion + } + }; + for (const [typeName, recordVersion] of Object.entries(schema.recordVersions)) { + result.sequences[`com.tldraw.${typeName}`] = recordVersion.version; + if ("subTypeKey" in recordVersion) { + for (const [subType, version2] of Object.entries(recordVersion.subTypeVersions)) { + result.sequences[`com.tldraw.${typeName}.${subType}`] = version2; + } + } + } + return Result.ok(result); +} +class StoreSchema { + constructor(types, options) { + __publicField(this, "migrations", {}); + __publicField(this, "sortedMigrations"); + var _a3; + this.types = types; + this.options = options; + for (const m2 of options.migrations ?? []) { + assert(!this.migrations[m2.sequenceId], `Duplicate migration sequenceId ${m2.sequenceId}`); + validateMigrations(m2); + this.migrations[m2.sequenceId] = m2; + } + const allMigrations = Object.values(this.migrations).flatMap((m2) => m2.sequence); + this.sortedMigrations = sortMigrations(allMigrations); + for (const migration of this.sortedMigrations) { + if (!((_a3 = migration.dependsOn) == null ? void 0 : _a3.length)) continue; + for (const dep of migration.dependsOn) { + const depMigration = allMigrations.find((m2) => m2.id === dep); + assert(depMigration, `Migration '${migration.id}' depends on missing migration '${dep}'`); + } + } + } + static create(types, options) { + return new StoreSchema(types, options ?? {}); + } + validateRecord(store, record, phase, recordBefore) { + try { + const recordType = getOwnProperty(this.types, record.typeName); + if (!recordType) { + throw new Error(`Missing definition for record type ${record.typeName}`); + } + return recordType.validate(record, recordBefore ?? void 0); + } catch (error) { + if (this.options.onValidationFailure) { + return this.options.onValidationFailure({ + store, + record, + phase, + recordBefore, + error + }); + } else { + throw error; + } + } + } + // TODO: use a weakmap to store the result of this function + getMigrationsSince(persistedSchema) { + const upgradeResult = upgradeSchema(persistedSchema); + if (!upgradeResult.ok) { + return upgradeResult; + } + const schema = upgradeResult.value; + const sequenceIdsToInclude = new Set( + // start with any shared sequences + Object.keys(schema.sequences).filter((sequenceId) => this.migrations[sequenceId]) + ); + for (const sequenceId in this.migrations) { + if (schema.sequences[sequenceId] === void 0 && this.migrations[sequenceId].retroactive) { + sequenceIdsToInclude.add(sequenceId); + } + } + if (sequenceIdsToInclude.size === 0) { + return Result.ok([]); + } + const allMigrationsToInclude = /* @__PURE__ */ new Set(); + for (const sequenceId of sequenceIdsToInclude) { + const theirVersion = schema.sequences[sequenceId]; + if (typeof theirVersion !== "number" && this.migrations[sequenceId].retroactive || theirVersion === 0) { + for (const migration of this.migrations[sequenceId].sequence) { + allMigrationsToInclude.add(migration.id); + } + continue; + } + const theirVersionId = `${sequenceId}/${theirVersion}`; + const idx = this.migrations[sequenceId].sequence.findIndex((m2) => m2.id === theirVersionId); + if (idx === -1) { + return Result.err("Incompatible schema?"); + } + for (const migration of this.migrations[sequenceId].sequence.slice(idx + 1)) { + allMigrationsToInclude.add(migration.id); + } + } + return Result.ok(this.sortedMigrations.filter(({ id: id2 }) => allMigrationsToInclude.has(id2))); + } + migratePersistedRecord(record, persistedSchema, direction = "up") { + const migrations = this.getMigrationsSince(persistedSchema); + if (!migrations.ok) { + console.error("Error migrating record", migrations.error); + return { type: "error", reason: MigrationFailureReason.MigrationError }; + } + let migrationsToApply = migrations.value; + if (migrationsToApply.length === 0) { + return { type: "success", value: record }; + } + if (migrationsToApply.some((m2) => m2.scope === "store")) { + return { + type: "error", + reason: direction === "down" ? MigrationFailureReason.TargetVersionTooOld : MigrationFailureReason.TargetVersionTooNew + }; + } + if (direction === "down") { + if (!migrationsToApply.every((m2) => m2.down)) { + return { + type: "error", + reason: MigrationFailureReason.TargetVersionTooOld + }; + } + migrationsToApply = migrationsToApply.slice().reverse(); + } + record = structuredClone(record); + try { + for (const migration of migrationsToApply) { + if (migration.scope === "store") throw new Error( + /* won't happen, just for TS */ + ); + const shouldApply = migration.filter ? migration.filter(record) : true; + if (!shouldApply) continue; + const result = migration[direction](record); + if (result) { + record = structuredClone(result); + } + } + } catch (e2) { + console.error("Error migrating record", e2); + return { type: "error", reason: MigrationFailureReason.MigrationError }; + } + return { type: "success", value: record }; + } + migrateStoreSnapshot(snapshot) { + let { store } = snapshot; + const migrations = this.getMigrationsSince(snapshot.schema); + if (!migrations.ok) { + console.error("Error migrating store", migrations.error); + return { type: "error", reason: MigrationFailureReason.MigrationError }; + } + const migrationsToApply = migrations.value; + if (migrationsToApply.length === 0) { + return { type: "success", value: store }; + } + store = structuredClone(store); + try { + for (const migration of migrationsToApply) { + if (migration.scope === "record") { + for (const [id2, record] of Object.entries(store)) { + const shouldApply = migration.filter ? migration.filter(record) : true; + if (!shouldApply) continue; + const result = migration.up(record); + if (result) { + store[id2] = structuredClone(result); + } + } + } else if (migration.scope === "store") { + const result = migration.up(store); + if (result) { + store = structuredClone(result); + } + } else { + exhaustiveSwitchError(migration); + } + } + } catch (e2) { + console.error("Error migrating store", e2); + return { type: "error", reason: MigrationFailureReason.MigrationError }; + } + return { type: "success", value: store }; + } + /** @internal */ + createIntegrityChecker(store) { + var _a3, _b2; + return ((_b2 = (_a3 = this.options).createIntegrityChecker) == null ? void 0 : _b2.call(_a3, store)) ?? void 0; + } + serialize() { + return { + schemaVersion: 2, + sequences: Object.fromEntries( + Object.values(this.migrations).map(({ sequenceId, sequence }) => [ + sequenceId, + sequence.length ? parseMigrationId(sequence.at(-1).id).version : 0 + ]) + ) + }; + } + /** + * @deprecated This is only here for legacy reasons, don't use it unless you have david's blessing! + */ + serializeEarliestVersion() { + return { + schemaVersion: 2, + sequences: Object.fromEntries( + Object.values(this.migrations).map(({ sequenceId }) => [sequenceId, 0]) + ) + }; + } + /** @internal */ + getType(typeName) { + const type = getOwnProperty(this.types, typeName); + assert(type, "record type does not exists"); + return type; + } +} +registerTldrawLibraryVersion( + "@tldraw/store", + "3.4.1", + "esm" +); +function formatPath(path) { + if (!path.length) { + return null; + } + let formattedPath = ""; + for (const item of path) { + if (typeof item === "number") { + formattedPath += `.${item}`; + } else if (item.startsWith("(")) { + if (formattedPath.endsWith(")")) { + formattedPath = `${formattedPath.slice(0, -1)}, ${item.slice(1)}`; + } else { + formattedPath += item; + } + } else { + formattedPath += `.${item}`; + } + } + formattedPath = formattedPath.replace(/id = [^,]+, /, "").replace(/id = [^)]+/, ""); + if (formattedPath.startsWith(".")) { + return formattedPath.slice(1); + } + return formattedPath; +} +class ValidationError extends Error { + constructor(rawMessage, path = []) { + const formattedPath = formatPath(path); + const indentedMessage = rawMessage.split("\n").map((line, i2) => i2 === 0 ? line : ` ${line}`).join("\n"); + super(path ? `At ${formattedPath}: ${indentedMessage}` : indentedMessage); + __publicField(this, "name", "ValidationError"); + this.rawMessage = rawMessage; + this.path = path; + } +} +function prefixError(path, fn) { + try { + return fn(); + } catch (err) { + if (err instanceof ValidationError) { + throw new ValidationError(err.rawMessage, [path, ...err.path]); + } + throw new ValidationError(err.toString(), [path]); + } +} +function typeToString(value) { + if (value === null) return "null"; + if (Array.isArray(value)) return "an array"; + const type = typeof value; + switch (type) { + case "bigint": + case "boolean": + case "function": + case "number": + case "string": + case "symbol": + return `a ${type}`; + case "object": + return `an ${type}`; + case "undefined": + return "undefined"; + default: + exhaustiveSwitchError(type); + } +} +class Validator { + constructor(validationFn, validateUsingKnownGoodVersionFn) { + this.validationFn = validationFn; + this.validateUsingKnownGoodVersionFn = validateUsingKnownGoodVersionFn; + } + /** + * Asserts that the passed value is of the correct type and returns it. The returned value is + * guaranteed to be referentially equal to the passed value. + */ + validate(value) { + const validated = this.validationFn(value); + if (!Object.is(value, validated)) { + throw new ValidationError("Validator functions must return the same value they were passed"); + } + return validated; + } + validateUsingKnownGoodVersion(knownGoodValue, newValue) { + if (Object.is(knownGoodValue, newValue)) { + return knownGoodValue; + } + if (this.validateUsingKnownGoodVersionFn) { + return this.validateUsingKnownGoodVersionFn(knownGoodValue, newValue); + } + return this.validate(newValue); + } + /** Checks that the passed value is of the correct type. */ + isValid(value) { + try { + this.validate(value); + return true; + } catch { + return false; + } + } + /** + * Returns a new validator that also accepts null or undefined. The resulting value will always be + * null. + */ + nullable() { + return nullable(this); + } + /** + * Returns a new validator that also accepts null or undefined. The resulting value will always be + * null. + */ + optional() { + return optional(this); + } + /** + * Refine this validation to a new type. The passed-in validation function should throw an error + * if the value can't be converted to the new type, or return the new type otherwise. + */ + refine(otherValidationFn) { + return new Validator( + (value) => { + return otherValidationFn(this.validate(value)); + }, + (knownGoodValue, newValue) => { + const validated = this.validateUsingKnownGoodVersion(knownGoodValue, newValue); + if (Object.is(knownGoodValue, validated)) { + return knownGoodValue; + } + return otherValidationFn(validated); + } + ); + } + check(nameOrCheckFn, checkFn) { + if (typeof nameOrCheckFn === "string") { + return this.refine((value) => { + prefixError(`(check ${nameOrCheckFn})`, () => checkFn(value)); + return value; + }); + } else { + return this.refine((value) => { + nameOrCheckFn(value); + return value; + }); + } + } +} +class ArrayOfValidator extends Validator { + constructor(itemValidator) { + super( + (value) => { + const arr = array.validate(value); + for (let i2 = 0; i2 < arr.length; i2++) { + prefixError(i2, () => itemValidator.validate(arr[i2])); + } + return arr; + }, + (knownGoodValue, newValue) => { + if (!itemValidator.validateUsingKnownGoodVersion) return this.validate(newValue); + const arr = array.validate(newValue); + let isDifferent = knownGoodValue.length !== arr.length; + for (let i2 = 0; i2 < arr.length; i2++) { + const item = arr[i2]; + if (i2 >= knownGoodValue.length) { + isDifferent = true; + prefixError(i2, () => itemValidator.validate(item)); + continue; + } + if (Object.is(knownGoodValue[i2], item)) { + continue; + } + const checkedItem = prefixError( + i2, + () => itemValidator.validateUsingKnownGoodVersion(knownGoodValue[i2], item) + ); + if (!Object.is(checkedItem, knownGoodValue[i2])) { + isDifferent = true; + } + } + return isDifferent ? newValue : knownGoodValue; + } + ); + this.itemValidator = itemValidator; + } + nonEmpty() { + return this.check((value) => { + if (value.length === 0) { + throw new ValidationError("Expected a non-empty array"); + } + }); + } + lengthGreaterThan1() { + return this.check((value) => { + if (value.length <= 1) { + throw new ValidationError("Expected an array with length greater than 1"); + } + }); + } +} +class ObjectValidator extends Validator { + constructor(config, shouldAllowUnknownProperties = false) { + super( + (object2) => { + if (typeof object2 !== "object" || object2 === null) { + throw new ValidationError(`Expected object, got ${typeToString(object2)}`); + } + for (const [key, validator] of Object.entries(config)) { + prefixError(key, () => { + ; + validator.validate(getOwnProperty(object2, key)); + }); + } + if (!shouldAllowUnknownProperties) { + for (const key of Object.keys(object2)) { + if (!hasOwnProperty$1(config, key)) { + throw new ValidationError(`Unexpected property`, [key]); + } + } + } + return object2; + }, + (knownGoodValue, newValue) => { + if (typeof newValue !== "object" || newValue === null) { + throw new ValidationError(`Expected object, got ${typeToString(newValue)}`); + } + let isDifferent = false; + for (const [key, validator] of Object.entries(config)) { + const prev = getOwnProperty(knownGoodValue, key); + const next = getOwnProperty(newValue, key); + if (Object.is(prev, next)) { + continue; + } + const checked = prefixError(key, () => { + const validatable = validator; + if (validatable.validateUsingKnownGoodVersion) { + return validatable.validateUsingKnownGoodVersion(prev, next); + } else { + return validatable.validate(next); + } + }); + if (!Object.is(checked, prev)) { + isDifferent = true; + } + } + if (!shouldAllowUnknownProperties) { + for (const key of Object.keys(newValue)) { + if (!hasOwnProperty$1(config, key)) { + throw new ValidationError(`Unexpected property`, [key]); + } + } + } + for (const key of Object.keys(knownGoodValue)) { + if (!hasOwnProperty$1(newValue, key)) { + isDifferent = true; + break; + } + } + return isDifferent ? newValue : knownGoodValue; + } + ); + this.config = config; + this.shouldAllowUnknownProperties = shouldAllowUnknownProperties; + } + allowUnknownProperties() { + return new ObjectValidator(this.config, true); + } + /** + * Extend an object validator by adding additional properties. + * + * @example + * + * ```ts + * const animalValidator = T.object({ + * name: T.string, + * }) + * const catValidator = animalValidator.extend({ + * meowVolume: T.number, + * }) + * ``` + */ + extend(extension) { + return new ObjectValidator({ ...this.config, ...extension }); + } +} +class UnionValidator extends Validator { + constructor(key, config, unknownValueValidation, useNumberKeys) { + super( + (input) => { + this.expectObject(input); + const { matchingSchema, variant } = this.getMatchingSchemaAndVariant(input); + if (matchingSchema === void 0) { + return this.unknownValueValidation(input, variant); + } + return prefixError(`(${key} = ${variant})`, () => matchingSchema.validate(input)); + }, + (prevValue, newValue) => { + this.expectObject(newValue); + this.expectObject(prevValue); + const { matchingSchema, variant } = this.getMatchingSchemaAndVariant(newValue); + if (matchingSchema === void 0) { + return this.unknownValueValidation(newValue, variant); + } + if (getOwnProperty(prevValue, key) !== getOwnProperty(newValue, key)) { + return prefixError(`(${key} = ${variant})`, () => matchingSchema.validate(newValue)); + } + return prefixError(`(${key} = ${variant})`, () => { + if (matchingSchema.validateUsingKnownGoodVersion) { + return matchingSchema.validateUsingKnownGoodVersion(prevValue, newValue); + } else { + return matchingSchema.validate(newValue); + } + }); + } + ); + this.key = key; + this.config = config; + this.unknownValueValidation = unknownValueValidation; + this.useNumberKeys = useNumberKeys; + } + expectObject(value) { + if (typeof value !== "object" || value === null) { + throw new ValidationError(`Expected an object, got ${typeToString(value)}`, []); + } + } + getMatchingSchemaAndVariant(object2) { + const variant = getOwnProperty(object2, this.key); + if (!this.useNumberKeys && typeof variant !== "string") { + throw new ValidationError( + `Expected a string for key "${this.key}", got ${typeToString(variant)}` + ); + } else if (this.useNumberKeys && !Number.isFinite(Number(variant))) { + throw new ValidationError(`Expected a number for key "${this.key}", got "${variant}"`); + } + const matchingSchema = hasOwnProperty$1(this.config, variant) ? this.config[variant] : void 0; + return { matchingSchema, variant }; + } + validateUnknownVariants(unknownValueValidation) { + return new UnionValidator(this.key, this.config, unknownValueValidation, this.useNumberKeys); + } +} +class DictValidator extends Validator { + constructor(keyValidator, valueValidator) { + super( + (object2) => { + if (typeof object2 !== "object" || object2 === null) { + throw new ValidationError(`Expected object, got ${typeToString(object2)}`); + } + for (const [key, value] of Object.entries(object2)) { + prefixError(key, () => { + keyValidator.validate(key); + valueValidator.validate(value); + }); + } + return object2; + }, + (knownGoodValue, newValue) => { + if (typeof newValue !== "object" || newValue === null) { + throw new ValidationError(`Expected object, got ${typeToString(newValue)}`); + } + let isDifferent = false; + for (const [key, value] of Object.entries(newValue)) { + if (!hasOwnProperty$1(knownGoodValue, key)) { + isDifferent = true; + prefixError(key, () => { + keyValidator.validate(key); + valueValidator.validate(value); + }); + continue; + } + const prev = getOwnProperty(knownGoodValue, key); + const next = value; + if (Object.is(prev, next)) { + continue; + } + const checked = prefixError(key, () => { + if (valueValidator.validateUsingKnownGoodVersion) { + return valueValidator.validateUsingKnownGoodVersion(prev, next); + } else { + return valueValidator.validate(next); + } + }); + if (!Object.is(checked, prev)) { + isDifferent = true; + } + } + for (const key of Object.keys(knownGoodValue)) { + if (!hasOwnProperty$1(newValue, key)) { + isDifferent = true; + break; + } + } + return isDifferent ? newValue : knownGoodValue; + } + ); + this.keyValidator = keyValidator; + this.valueValidator = valueValidator; + } +} +function typeofValidator(type) { + return new Validator((value) => { + if (typeof value !== type) { + throw new ValidationError(`Expected ${type}, got ${typeToString(value)}`); + } + return value; + }); +} +const any = new Validator((value) => value); +const string = typeofValidator("string"); +const number = typeofValidator("number").check((number2) => { + if (Number.isNaN(number2)) { + throw new ValidationError("Expected a number, got NaN"); + } + if (!Number.isFinite(number2)) { + throw new ValidationError(`Expected a finite number, got ${number2}`); + } +}); +const positiveNumber = number.check((value) => { + if (value < 0) throw new ValidationError(`Expected a positive number, got ${value}`); +}); +const nonZeroNumber = number.check((value) => { + if (value <= 0) throw new ValidationError(`Expected a non-zero positive number, got ${value}`); +}); +const integer = number.check((value) => { + if (!Number.isInteger(value)) throw new ValidationError(`Expected an integer, got ${value}`); +}); +const positiveInteger = integer.check((value) => { + if (value < 0) throw new ValidationError(`Expected a positive integer, got ${value}`); +}); +const nonZeroInteger = integer.check((value) => { + if (value <= 0) throw new ValidationError(`Expected a non-zero positive integer, got ${value}`); +}); +const boolean = typeofValidator("boolean"); +function literal(expectedValue) { + return new Validator((actualValue) => { + if (actualValue !== expectedValue) { + throw new ValidationError(`Expected ${expectedValue}, got ${JSON.stringify(actualValue)}`); + } + return expectedValue; + }); +} +const array = new Validator((value) => { + if (!Array.isArray(value)) { + throw new ValidationError(`Expected an array, got ${typeToString(value)}`); + } + return value; +}); +function arrayOf(itemValidator) { + return new ArrayOfValidator(itemValidator); +} +function object(config) { + return new ObjectValidator(config); +} +function isPlainObject(value) { + return typeof value === "object" && value !== null && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null || Object.getPrototypeOf(value) === STRUCTURED_CLONE_OBJECT_PROTOTYPE); +} +function isValidJson(value) { + if (value === null || typeof value === "number" || typeof value === "string" || typeof value === "boolean") { + return true; + } + if (Array.isArray(value)) { + return value.every(isValidJson); + } + if (isPlainObject(value)) { + return Object.values(value).every(isValidJson); + } + return false; +} +const jsonValue = new Validator( + (value) => { + if (isValidJson(value)) { + return value; + } + throw new ValidationError(`Expected json serializable value, got ${typeof value}`); + }, + (knownGoodValue, newValue) => { + if (Array.isArray(knownGoodValue) && Array.isArray(newValue)) { + let isDifferent = knownGoodValue.length !== newValue.length; + for (let i2 = 0; i2 < newValue.length; i2++) { + if (i2 >= knownGoodValue.length) { + isDifferent = true; + jsonValue.validate(newValue[i2]); + continue; + } + const prev = knownGoodValue[i2]; + const next = newValue[i2]; + if (Object.is(prev, next)) { + continue; + } + const checked = jsonValue.validateUsingKnownGoodVersion(prev, next); + if (!Object.is(checked, prev)) { + isDifferent = true; + } + } + return isDifferent ? newValue : knownGoodValue; + } else if (isPlainObject(knownGoodValue) && isPlainObject(newValue)) { + let isDifferent = false; + for (const key of Object.keys(newValue)) { + if (!hasOwnProperty$1(knownGoodValue, key)) { + isDifferent = true; + jsonValue.validate(newValue[key]); + continue; + } + const prev = knownGoodValue[key]; + const next = newValue[key]; + if (Object.is(prev, next)) { + continue; + } + const checked = jsonValue.validateUsingKnownGoodVersion(prev, next); + if (!Object.is(checked, prev)) { + isDifferent = true; + } + } + for (const key of Object.keys(knownGoodValue)) { + if (!hasOwnProperty$1(newValue, key)) { + isDifferent = true; + break; + } + } + return isDifferent ? newValue : knownGoodValue; + } else { + return jsonValue.validate(newValue); + } + } +); +function dict(keyValidator, valueValidator) { + return new DictValidator(keyValidator, valueValidator); +} +function union(key, config) { + return new UnionValidator( + key, + config, + (_unknownValue, unknownVariant) => { + throw new ValidationError( + `Expected one of ${Object.keys(config).map((key2) => JSON.stringify(key2)).join(" or ")}, got ${JSON.stringify(unknownVariant)}`, + [key] + ); + }, + false + ); +} +function numberUnion(key, config) { + return new UnionValidator( + key, + config, + (unknownValue, unknownVariant) => { + throw new ValidationError( + `Expected one of ${Object.keys(config).map((key2) => JSON.stringify(key2)).join(" or ")}, got ${JSON.stringify(unknownVariant)}`, + [key] + ); + }, + true + ); +} +function model(name, validator) { + return new Validator( + (value) => { + return prefixError(name, () => validator.validate(value)); + }, + (prevValue, newValue) => { + return prefixError(name, () => { + if (validator.validateUsingKnownGoodVersion) { + return validator.validateUsingKnownGoodVersion(prevValue, newValue); + } else { + return validator.validate(newValue); + } + }); + } + ); +} +function setEnum(values) { + return new Validator((value) => { + if (!values.has(value)) { + const valuesString = Array.from(values, (value2) => JSON.stringify(value2)).join(" or "); + throw new ValidationError(`Expected ${valuesString}, got ${value}`); + } + return value; + }); +} +function optional(validator) { + return new Validator( + (value) => { + if (value === void 0) return void 0; + return validator.validate(value); + }, + (knownGoodValue, newValue) => { + if (knownGoodValue === void 0 && newValue === void 0) return void 0; + if (newValue === void 0) return void 0; + if (validator.validateUsingKnownGoodVersion && knownGoodValue !== void 0) { + return validator.validateUsingKnownGoodVersion(knownGoodValue, newValue); + } + return validator.validate(newValue); + } + ); +} +function nullable(validator) { + return new Validator( + (value) => { + if (value === null) return null; + return validator.validate(value); + }, + (knownGoodValue, newValue) => { + if (newValue === null) return null; + if (validator.validateUsingKnownGoodVersion && knownGoodValue !== null) { + return validator.validateUsingKnownGoodVersion(knownGoodValue, newValue); + } + return validator.validate(newValue); + } + ); +} +function literalEnum(...values) { + return setEnum(new Set(values)); +} +function parseUrl(str) { + try { + return new URL(str); + } catch { + if (str.startsWith("/") || str.startsWith("./")) { + try { + return new URL(str, "http://example.com"); + } catch { + throw new ValidationError(`Expected a valid url, got ${JSON.stringify(str)}`); + } + } + throw new ValidationError(`Expected a valid url, got ${JSON.stringify(str)}`); + } +} +const validLinkProtocols = /* @__PURE__ */ new Set(["http:", "https:", "mailto:"]); +const linkUrl = string.check((value) => { + if (value === "") return; + const url = parseUrl(value); + if (!validLinkProtocols.has(url.protocol.toLowerCase())) { + throw new ValidationError( + `Expected a valid url, got ${JSON.stringify(value)} (invalid protocol)` + ); + } +}); +const validSrcProtocols = /* @__PURE__ */ new Set(["http:", "https:", "data:", "asset:"]); +const srcUrl = string.check((value) => { + if (value === "") return; + const url = parseUrl(value); + if (!validSrcProtocols.has(url.protocol.toLowerCase())) { + throw new ValidationError( + `Expected a valid url, got ${JSON.stringify(value)} (invalid protocol)` + ); + } +}); +string.check((value) => { + if (value === "") return; + const url = parseUrl(value); + if (!url.protocol.toLowerCase().match(/^https?:$/)) { + throw new ValidationError( + `Expected a valid url, got ${JSON.stringify(value)} (invalid protocol)` + ); + } +}); +const indexKey = string.refine((key) => { + try { + validateIndexKey(key); + return key; + } catch { + throw new ValidationError(`Expected an index key, got ${JSON.stringify(key)}`); + } +}); +registerTldrawLibraryVersion( + "@tldraw/validate", + "3.4.1", + "esm" +); +function idValidator(prefix) { + return string.refine((id2) => { + if (!id2.startsWith(`${prefix}:`)) { + throw new Error(`${prefix} ID must start with "${prefix}:"`); + } + return id2; + }); +} +const assetIdValidator = idValidator("asset"); +function createAssetValidator(type, props) { + return object({ + id: assetIdValidator, + typeName: literal("asset"), + type: literal(type), + props, + meta: jsonValue + }); +} +const vecModelValidator = object({ + x: number, + y: number, + z: number.optional() +}); +const boxModelValidator = object({ + x: number, + y: number, + w: number, + h: number +}); +const opacityValidator = number.check((n) => { + if (n < 0 || n > 1) { + throw new ValidationError("Opacity must be between 0 and 1"); + } +}); +const parentIdValidator = string.refine((id2) => { + if (!id2.startsWith("page:") && !id2.startsWith("shape:")) { + throw new Error('Parent ID must start with "page:" or "shape:"'); + } + return id2; +}); +const shapeIdValidator = idValidator("shape"); +function createShapeValidator(type, props, meta) { + return object({ + id: shapeIdValidator, + typeName: literal("shape"), + x: number, + y: number, + rotation: number, + index: indexKey, + parentId: parentIdValidator, + type: literal(type), + isLocked: boolean, + opacity: opacityValidator, + props: props ? object(props) : jsonValue, + meta: meta ? object(meta) : jsonValue + }); +} +const bindingIdValidator = idValidator("binding"); +function createBindingValidator(type, props, meta) { + return object({ + id: bindingIdValidator, + typeName: literal("binding"), + type: literal(type), + fromId: shapeIdValidator, + toId: shapeIdValidator, + props: props ? object(props) : jsonValue, + meta: meta ? object(meta) : jsonValue + }); +} +createMigrationIds("com.tldraw.binding", {}); +createRecordMigrationSequence({ + sequenceId: "com.tldraw.binding", + recordType: "binding", + sequence: [] +}); +function createBindingId(id2) { + return `binding:${uniqueId()}`; +} +function createBindingPropsMigrationSequence(migrations) { + return migrations; +} +function createBindingRecordType(bindings) { + return createRecordType("binding", { + scope: "document", + validator: model( + "binding", + union( + "type", + mapObjectMapValues( + bindings, + (type, { props, meta }) => createBindingValidator(type, props, meta) + ) + ) + ) + }).withDefaultProperties(() => ({ + meta: {} + })); +} +class StyleProp { + /** @internal */ + constructor(id2, defaultValue, type) { + this.id = id2; + this.defaultValue = defaultValue; + this.type = type; + } + /** + * Define a new {@link StyleProp}. + * + * @param uniqueId - Each StyleProp must have a unique ID. We recommend you prefix this with + * your app/library name. + * @param options - + * - `defaultValue`: The default value for this style prop. + * + * - `type`: Optionally, describe what type of data you expect for this style prop. + * + * @example + * ```ts + * import {T} from '@tldraw/validate' + * import {StyleProp} from '@tldraw/tlschema' + * + * const MyLineWidthProp = StyleProp.define('myApp:lineWidth', { + * defaultValue: 1, + * type: T.number, + * }) + * ``` + * @public + */ + static define(uniqueId2, options) { + const { defaultValue, type = any } = options; + return new StyleProp(uniqueId2, defaultValue, type); + } + /** + * Define a new {@link StyleProp} as a list of possible values. + * + * @param uniqueId - Each StyleProp must have a unique ID. We recommend you prefix this with + * your app/library name. + * @param options - + * - `defaultValue`: The default value for this style prop. + * + * - `values`: An array of possible values of this style prop. + * + * @example + * ```ts + * import {StyleProp} from '@tldraw/tlschema' + * + * const MySizeProp = StyleProp.defineEnum('myApp:size', { + * defaultValue: 'medium', + * values: ['small', 'medium', 'large'], + * }) + * ``` + */ + static defineEnum(uniqueId2, options) { + const { defaultValue, values } = options; + return new EnumStyleProp(uniqueId2, defaultValue, values); + } + setDefaultValue(value) { + this.defaultValue = value; + } + validate(value) { + return this.type.validate(value); + } + validateUsingKnownGoodVersion(prevValue, newValue) { + if (this.type.validateUsingKnownGoodVersion) { + return this.type.validateUsingKnownGoodVersion(prevValue, newValue); + } else { + return this.validate(newValue); + } + } +} +class EnumStyleProp extends StyleProp { + /** @internal */ + constructor(id2, defaultValue, values) { + super(id2, defaultValue, literalEnum(...values)); + this.values = values; + } +} +const rootShapeVersions = createMigrationIds("com.tldraw.shape", { + AddIsLocked: 1, + HoistOpacity: 2, + AddMeta: 3, + AddWhite: 4 +}); +const rootShapeMigrations = createRecordMigrationSequence({ + sequenceId: "com.tldraw.shape", + recordType: "shape", + sequence: [ + { + id: rootShapeVersions.AddIsLocked, + up: (record) => { + record.isLocked = false; + }, + down: (record) => { + delete record.isLocked; + } + }, + { + id: rootShapeVersions.HoistOpacity, + up: (record) => { + record.opacity = Number(record.props.opacity ?? "1"); + delete record.props.opacity; + }, + down: (record) => { + const opacity = record.opacity; + delete record.opacity; + record.props.opacity = opacity < 0.175 ? "0.1" : opacity < 0.375 ? "0.25" : opacity < 0.625 ? "0.5" : opacity < 0.875 ? "0.75" : "1"; + } + }, + { + id: rootShapeVersions.AddMeta, + up: (record) => { + record.meta = {}; + } + }, + { + id: rootShapeVersions.AddWhite, + up: (_record) => { + }, + down: (record) => { + if (record.props.color === "white") { + record.props.color = "black"; + } + } + } + ] +}); +function isShape(record) { + if (!record) return false; + return record.typeName === "shape"; +} +function isShapeId(id2) { + if (!id2) return false; + return id2.startsWith("shape:"); +} +function createShapeId(id2) { + return `shape:${id2 ?? uniqueId()}`; +} +function getShapePropKeysByStyle(props) { + const propKeysByStyle = /* @__PURE__ */ new Map(); + for (const [key, prop] of Object.entries(props)) { + if (prop instanceof StyleProp) { + if (propKeysByStyle.has(prop)) { + throw new Error( + `Duplicate style prop ${prop.id}. Each style prop can only be used once within a shape.` + ); + } + propKeysByStyle.set(prop, key); + } + } + return propKeysByStyle; +} +function createShapePropsMigrationSequence(migrations) { + return migrations; +} +function createShapePropsMigrationIds(shapeType, ids) { + return mapObjectMapValues(ids, (_k2, v2) => `com.tldraw.shape.${shapeType}/${v2}`); +} +function createShapeRecordType(shapes) { + return createRecordType("shape", { + scope: "document", + validator: model( + "shape", + union( + "type", + mapObjectMapValues( + shapes, + (type, { props, meta }) => createShapeValidator(type, props, meta) + ) + ) + ) + }).withDefaultProperties(() => ({ + x: 0, + y: 0, + rotation: 0, + isLocked: false, + opacity: 1, + meta: {} + })); +} +function processPropsMigrations(typeName, records) { + const result = []; + for (const [subType, { migrations }] of Object.entries(records)) { + const sequenceId = `com.tldraw.${typeName}.${subType}`; + if (!migrations) { + result.push( + createMigrationSequence({ + sequenceId, + retroactive: false, + sequence: [] + }) + ); + } else if ("sequenceId" in migrations) { + assert( + sequenceId === migrations.sequenceId, + `sequenceId mismatch for ${subType} ${RecordType} migrations. Expected '${sequenceId}', got '${migrations.sequenceId}'` + ); + result.push(migrations); + } else if ("sequence" in migrations) { + result.push( + createMigrationSequence({ + sequenceId, + retroactive: false, + sequence: migrations.sequence.map( + (m2) => "id" in m2 ? createPropsMigration(typeName, subType, m2) : m2 + ) + }) + ); + } else { + result.push( + createMigrationSequence({ + sequenceId, + retroactive: false, + sequence: Object.keys(migrations.migrators).map((k) => Number(k)).sort((a2, b2) => a2 - b2).map( + (version2) => ({ + id: `${sequenceId}/${version2}`, + scope: "record", + filter: (r) => r.typeName === typeName && r.type === subType, + up: (record) => { + const result2 = migrations.migrators[version2].up(record); + if (result2) { + return result2; + } + }, + down: (record) => { + const result2 = migrations.migrators[version2].down(record); + if (result2) { + return result2; + } + } + }) + ) + }) + ); + } + } + return result; +} +function createPropsMigration(typeName, subType, m2) { + return { + id: m2.id, + dependsOn: m2.dependsOn, + scope: "record", + filter: (r) => r.typeName === typeName && r.type === subType, + up: (record) => { + const result = m2.up(record.props); + if (result) { + record.props = result; + } + }, + down: typeof m2.down === "function" ? (record) => { + const result = m2.down(record.props); + if (result) { + record.props = result; + } + } : void 0 + }; +} +const defaultColorNames = [ + "black", + "grey", + "light-violet", + "violet", + "blue", + "light-blue", + "yellow", + "orange", + "green", + "light-green", + "light-red", + "red", + "white" +]; +const DefaultColorThemePalette = { + lightMode: { + id: "light", + text: "#000000", + background: "rgb(249, 250, 251)", + solid: "#fcfffe", + black: { + solid: "#1d1d1d", + fill: "#1d1d1d", + note: { + fill: "#FCE19C", + text: "#000000" + }, + semi: "#e8e8e8", + pattern: "#494949", + highlight: { + srgb: "#fddd00", + p3: "color(display-p3 0.972 0.8705 0.05)" + } + }, + blue: { + solid: "#4465e9", + fill: "#4465e9", + note: { + fill: "#8AA3FF", + text: "#000000" + }, + semi: "#dce1f8", + pattern: "#6681ee", + highlight: { + srgb: "#10acff", + p3: "color(display-p3 0.308 0.6632 0.9996)" + } + }, + green: { + solid: "#099268", + fill: "#099268", + note: { + fill: "#6FC896", + text: "#000000" + }, + semi: "#d3e9e3", + pattern: "#39a785", + highlight: { + srgb: "#00ffc8", + p3: "color(display-p3 0.2536 0.984 0.7981)" + } + }, + grey: { + solid: "#9fa8b2", + fill: "#9fa8b2", + note: { + fill: "#C0CAD3", + text: "#000000" + }, + semi: "#eceef0", + pattern: "#bcc3c9", + highlight: { + srgb: "#cbe7f1", + p3: "color(display-p3 0.8163 0.9023 0.9416)" + } + }, + "light-blue": { + solid: "#4ba1f1", + fill: "#4ba1f1", + note: { + fill: "#9BC4FD", + text: "#000000" + }, + semi: "#ddedfa", + pattern: "#6fbbf8", + highlight: { + srgb: "#00f4ff", + p3: "color(display-p3 0.1512 0.9414 0.9996)" + } + }, + "light-green": { + solid: "#4cb05e", + fill: "#4cb05e", + note: { + fill: "#98D08A", + text: "#000000" + }, + semi: "#dbf0e0", + pattern: "#65cb78", + highlight: { + srgb: "#65f641", + p3: "color(display-p3 0.563 0.9495 0.3857)" + } + }, + "light-red": { + solid: "#f87777", + fill: "#f87777", + note: { + fill: "#F7A5A1", + text: "#000000" + }, + semi: "#f4dadb", + pattern: "#fe9e9e", + highlight: { + srgb: "#ff7fa3", + p3: "color(display-p3 0.9988 0.5301 0.6397)" + } + }, + "light-violet": { + solid: "#e085f4", + fill: "#e085f4", + note: { + fill: "#DFB0F9", + text: "#000000" + }, + semi: "#f5eafa", + pattern: "#e9acf8", + highlight: { + srgb: "#ff88ff", + p3: "color(display-p3 0.9676 0.5652 0.9999)" + } + }, + orange: { + solid: "#e16919", + fill: "#e16919", + note: { + fill: "#FAA475", + text: "#000000" + }, + semi: "#f8e2d4", + pattern: "#f78438", + highlight: { + srgb: "#ffa500", + p3: "color(display-p3 0.9988 0.6905 0.266)" + } + }, + red: { + solid: "#e03131", + fill: "#e03131", + note: { + fill: "#FC8282", + text: "#000000" + }, + semi: "#f4dadb", + pattern: "#e55959", + highlight: { + srgb: "#ff636e", + p3: "color(display-p3 0.9992 0.4376 0.45)" + } + }, + violet: { + solid: "#ae3ec9", + fill: "#ae3ec9", + note: { + fill: "#DB91FD", + text: "#000000" + }, + semi: "#ecdcf2", + pattern: "#bd63d3", + highlight: { + srgb: "#c77cff", + p3: "color(display-p3 0.7469 0.5089 0.9995)" + } + }, + yellow: { + solid: "#f1ac4b", + fill: "#f1ac4b", + note: { + fill: "#FED49A", + text: "#000000" + }, + semi: "#f9f0e6", + pattern: "#fecb92", + highlight: { + srgb: "#fddd00", + p3: "color(display-p3 0.972 0.8705 0.05)" + } + }, + white: { + solid: "#FFFFFF", + fill: "#FFFFFF", + semi: "#f5f5f5", + pattern: "#f9f9f9", + note: { + fill: "#FFFFFF", + text: "#000000" + }, + highlight: { + srgb: "#ffffff", + p3: "color(display-p3 1 1 1)" + } + } + }, + darkMode: { + id: "dark", + text: "hsl(210, 17%, 98%)", + background: "hsl(240, 5%, 6.5%)", + solid: "#010403", + black: { + solid: "#f2f2f2", + fill: "#f2f2f2", + note: { + fill: "#2c2c2c", + text: "#f2f2f2" + }, + semi: "#2c3036", + pattern: "#989898", + highlight: { + srgb: "#d2b700", + p3: "color(display-p3 0.8078 0.7225 0.0312)" + } + }, + blue: { + solid: "#4f72fc", + // 3c60f0 + fill: "#4f72fc", + note: { + fill: "#2A3F98", + text: "#f2f2f2" + }, + semi: "#262d40", + pattern: "#3a4b9e", + highlight: { + srgb: "#0079d2", + p3: "color(display-p3 0.0032 0.4655 0.7991)" + } + }, + green: { + solid: "#099268", + fill: "#099268", + note: { + fill: "#014429", + text: "#f2f2f2" + }, + semi: "#253231", + pattern: "#366a53", + highlight: { + srgb: "#009774", + p3: "color(display-p3 0.0085 0.582 0.4604)" + } + }, + grey: { + solid: "#9398b0", + fill: "#9398b0", + note: { + fill: "#56595F", + text: "#f2f2f2" + }, + semi: "#33373c", + pattern: "#7c8187", + highlight: { + srgb: "#9cb4cb", + p3: "color(display-p3 0.6299 0.7012 0.7856)" + } + }, + "light-blue": { + solid: "#4dabf7", + fill: "#4dabf7", + note: { + fill: "#1F5495", + text: "#f2f2f2" + }, + semi: "#2a3642", + pattern: "#4d7aa9", + highlight: { + srgb: "#00bdc8", + p3: "color(display-p3 0.0023 0.7259 0.7735)" + } + }, + "light-green": { + solid: "#40c057", + fill: "#40c057", + note: { + fill: "#21581D", + text: "#f2f2f2" + }, + semi: "#2a3830", + pattern: "#4e874e", + highlight: { + srgb: "#00a000", + p3: "color(display-p3 0.2711 0.6172 0.0195)" + } + }, + "light-red": { + solid: "#ff8787", + fill: "#ff8787", + note: { + fill: "#923632", + text: "#f2f2f2" + }, + semi: "#3b3235", + pattern: "#a56767", + highlight: { + srgb: "#db005b", + p3: "color(display-p3 0.7849 0.0585 0.3589)" + } + }, + "light-violet": { + solid: "#e599f7", + fill: "#e599f7", + note: { + fill: "#762F8E", + text: "#f2f2f2" + }, + semi: "#383442", + pattern: "#9770a9", + highlight: { + srgb: "#c400c7", + p3: "color(display-p3 0.7024 0.0403 0.753)" + } + }, + orange: { + solid: "#f76707", + fill: "#f76707", + note: { + fill: "#843906", + text: "#f2f2f2" + }, + semi: "#3a2e2a", + pattern: "#9f552d", + highlight: { + srgb: "#d07a00", + p3: "color(display-p3 0.7699 0.4937 0.0085)" + } + }, + red: { + solid: "#e03131", + fill: "#e03131", + note: { + fill: "#89231A", + text: "#f2f2f2" + }, + semi: "#36292b", + pattern: "#8f3734", + highlight: { + srgb: "#de002c", + p3: "color(display-p3 0.7978 0.0509 0.2035)" + } + }, + violet: { + solid: "#ae3ec9", + fill: "#ae3ec9", + note: { + fill: "#681683", + text: "#f2f2f2" + }, + semi: "#31293c", + pattern: "#763a8b", + highlight: { + srgb: "#9e00ee", + p3: "color(display-p3 0.5651 0.0079 0.8986)" + } + }, + yellow: { + solid: "#ffc034", + fill: "#ffc034", + note: { + fill: "#98571B", + text: "#f2f2f2" + }, + semi: "#3c3934", + pattern: "#fecb92", + highlight: { + srgb: "#d2b700", + p3: "color(display-p3 0.8078 0.7225 0.0312)" + } + }, + white: { + solid: "#f3f3f3", + fill: "#f3f3f3", + semi: "#f5f5f5", + pattern: "#f9f9f9", + note: { + fill: "#eaeaea", + text: "#1d1d1d" + }, + highlight: { + srgb: "#ffffff", + p3: "color(display-p3 1 1 1)" + } + } + } +}; +function getDefaultColorTheme(opts) { + return opts.isDarkMode ? DefaultColorThemePalette.darkMode : DefaultColorThemePalette.lightMode; +} +const DefaultColorStyle = StyleProp.defineEnum("tldraw:color", { + defaultValue: "black", + values: defaultColorNames +}); +const DefaultLabelColorStyle = StyleProp.defineEnum("tldraw:labelColor", { + defaultValue: "black", + values: defaultColorNames +}); +const DefaultDashStyle = StyleProp.defineEnum("tldraw:dash", { + defaultValue: "draw", + values: ["draw", "solid", "dashed", "dotted"] +}); +const DefaultFillStyle = StyleProp.defineEnum("tldraw:fill", { + defaultValue: "none", + values: ["none", "semi", "solid", "pattern", "fill"] +}); +const DefaultFontStyle = StyleProp.defineEnum("tldraw:font", { + defaultValue: "draw", + values: ["draw", "sans", "serif", "mono"] +}); +const DefaultFontFamilies = { + draw: "'tldraw_draw', sans-serif", + sans: "'tldraw_sans', sans-serif", + serif: "'tldraw_serif', serif", + mono: "'tldraw_mono', monospace" +}; +const DefaultSizeStyle = StyleProp.defineEnum("tldraw:size", { + defaultValue: "m", + values: ["s", "m", "l", "xl"] +}); +const arrowheadTypes = [ + "arrow", + "triangle", + "square", + "dot", + "pipe", + "diamond", + "inverted", + "bar", + "none" +]; +const ArrowShapeArrowheadStartStyle = StyleProp.defineEnum("tldraw:arrowheadStart", { + defaultValue: "none", + values: arrowheadTypes +}); +const ArrowShapeArrowheadEndStyle = StyleProp.defineEnum("tldraw:arrowheadEnd", { + defaultValue: "arrow", + values: arrowheadTypes +}); +const arrowShapeProps = { + labelColor: DefaultLabelColorStyle, + color: DefaultColorStyle, + fill: DefaultFillStyle, + dash: DefaultDashStyle, + size: DefaultSizeStyle, + arrowheadStart: ArrowShapeArrowheadStartStyle, + arrowheadEnd: ArrowShapeArrowheadEndStyle, + font: DefaultFontStyle, + start: vecModelValidator, + end: vecModelValidator, + bend: number, + text: string, + labelPosition: number, + scale: nonZeroNumber +}; +const arrowShapeVersions = createShapePropsMigrationIds("arrow", { + AddLabelColor: 1, + AddIsPrecise: 2, + AddLabelPosition: 3, + ExtractBindings: 4, + AddScale: 5 +}); +function propsMigration(migration) { + return createPropsMigration("shape", "arrow", migration); +} +const arrowShapeMigrations = createMigrationSequence({ + sequenceId: "com.tldraw.shape.arrow", + retroactive: false, + sequence: [ + propsMigration({ + id: arrowShapeVersions.AddLabelColor, + up: (props) => { + props.labelColor = "black"; + }, + down: "retired" + }), + propsMigration({ + id: arrowShapeVersions.AddIsPrecise, + up: ({ start, end }) => { + if (start.type === "binding") { + start.isPrecise = !(start.normalizedAnchor.x === 0.5 && start.normalizedAnchor.y === 0.5); + } + if (end.type === "binding") { + end.isPrecise = !(end.normalizedAnchor.x === 0.5 && end.normalizedAnchor.y === 0.5); + } + }, + down: ({ start, end }) => { + if (start.type === "binding") { + if (!start.isPrecise) { + start.normalizedAnchor = { x: 0.5, y: 0.5 }; + } + delete start.isPrecise; + } + if (end.type === "binding") { + if (!end.isPrecise) { + end.normalizedAnchor = { x: 0.5, y: 0.5 }; + } + delete end.isPrecise; + } + } + }), + propsMigration({ + id: arrowShapeVersions.AddLabelPosition, + up: (props) => { + props.labelPosition = 0.5; + }, + down: (props) => { + delete props.labelPosition; + } + }), + { + id: arrowShapeVersions.ExtractBindings, + scope: "store", + up: (oldStore) => { + const arrows = Object.values(oldStore).filter( + (r) => r.typeName === "shape" && r.type === "arrow" + ); + for (const arrow2 of arrows) { + const { start, end } = arrow2.props; + if (start.type === "binding") { + const id2 = createBindingId(); + const binding = { + typeName: "binding", + id: id2, + type: "arrow", + fromId: arrow2.id, + toId: start.boundShapeId, + meta: {}, + props: { + terminal: "start", + normalizedAnchor: start.normalizedAnchor, + isExact: start.isExact, + isPrecise: start.isPrecise + } + }; + oldStore[id2] = binding; + arrow2.props.start = { x: 0, y: 0 }; + } else { + delete arrow2.props.start.type; + } + if (end.type === "binding") { + const id2 = createBindingId(); + const binding = { + typeName: "binding", + id: id2, + type: "arrow", + fromId: arrow2.id, + toId: end.boundShapeId, + meta: {}, + props: { + terminal: "end", + normalizedAnchor: end.normalizedAnchor, + isExact: end.isExact, + isPrecise: end.isPrecise + } + }; + oldStore[id2] = binding; + arrow2.props.end = { x: 0, y: 0 }; + } else { + delete arrow2.props.end.type; + } + } + } + }, + propsMigration({ + id: arrowShapeVersions.AddScale, + up: (props) => { + props.scale = 1; + }, + down: (props) => { + delete props.scale; + } + }) + ] +}); +const arrowBindingProps = { + terminal: literalEnum("start", "end"), + normalizedAnchor: vecModelValidator, + isExact: boolean, + isPrecise: boolean +}; +const arrowBindingMigrations = createBindingPropsMigrationSequence({ + sequence: [{ dependsOn: [arrowShapeVersions.ExtractBindings] }] +}); +const cameraValidator = model( + "camera", + object({ + typeName: literal("camera"), + id: idValidator("camera"), + x: number, + y: number, + z: number, + meta: jsonValue + }) +); +const cameraVersions = createMigrationIds("com.tldraw.camera", { + AddMeta: 1 +}); +const cameraMigrations = createRecordMigrationSequence({ + sequenceId: "com.tldraw.camera", + recordType: "camera", + sequence: [ + { + id: cameraVersions.AddMeta, + up: (record) => { + record.meta = {}; + } + } + ] +}); +const CameraRecordType = createRecordType("camera", { + validator: cameraValidator, + scope: "session" +}).withDefaultProperties( + () => ({ + x: 0, + y: 0, + z: 1, + meta: {} + }) +); +const TL_CURSOR_TYPES = /* @__PURE__ */ new Set([ + "none", + "default", + "pointer", + "cross", + "grab", + "rotate", + "grabbing", + "resize-edge", + "resize-corner", + "text", + "move", + "ew-resize", + "ns-resize", + "nesw-resize", + "nwse-resize", + "nesw-rotate", + "nwse-rotate", + "swne-rotate", + "senw-rotate", + "zoom-in", + "zoom-out" +]); +const cursorTypeValidator = setEnum(TL_CURSOR_TYPES); +const cursorValidator = object({ + type: cursorTypeValidator, + rotation: number +}); +const TL_CANVAS_UI_COLOR_TYPES = /* @__PURE__ */ new Set([ + "accent", + "white", + "black", + "selection-stroke", + "selection-fill", + "laser", + "muted-1" +]); +const canvasUiColorTypeValidator = setEnum(TL_CANVAS_UI_COLOR_TYPES); +const TL_SCRIBBLE_STATES = /* @__PURE__ */ new Set(["starting", "paused", "active", "stopping"]); +const scribbleValidator = object({ + id: string, + points: arrayOf(vecModelValidator), + size: positiveNumber, + color: canvasUiColorTypeValidator, + opacity: number, + state: setEnum(TL_SCRIBBLE_STATES), + delay: number, + shrink: number, + taper: boolean +}); +const pageIdValidator = idValidator("page"); +const pageValidator = model( + "page", + object({ + typeName: literal("page"), + id: pageIdValidator, + name: string, + index: indexKey, + meta: jsonValue + }) +); +const pageVersions = createMigrationIds("com.tldraw.page", { + AddMeta: 1 +}); +const pageMigrations = createRecordMigrationSequence({ + sequenceId: "com.tldraw.page", + recordType: "page", + sequence: [ + { + id: pageVersions.AddMeta, + up: (record) => { + record.meta = {}; + } + } + ] +}); +const PageRecordType = createRecordType("page", { + validator: pageValidator, + scope: "document" +}).withDefaultProperties(() => ({ + meta: {} +})); +function isPageId(id2) { + return PageRecordType.isId(id2); +} +const shouldKeyBePreservedBetweenSessions = { + // This object defines keys that should be preserved across calls to loadSnapshot() + id: false, + // meta + typeName: false, + // meta + currentPageId: false, + // does not preserve because who knows if the page still exists + opacityForNextShape: false, + // does not preserve because it's a temporary state + stylesForNextShape: false, + // does not preserve because it's a temporary state + followingUserId: false, + // does not preserve because it's a temporary state + highlightedUserIds: false, + // does not preserve because it's a temporary state + brush: false, + // does not preserve because it's a temporary state + cursor: false, + // does not preserve because it's a temporary state + scribbles: false, + // does not preserve because it's a temporary state + isFocusMode: true, + // preserves because it's a user preference + isDebugMode: true, + // preserves because it's a user preference + isToolLocked: true, + // preserves because it's a user preference + exportBackground: true, + // preserves because it's a user preference + screenBounds: true, + // preserves because it's capturing the user's screen state + insets: true, + // preserves because it's capturing the user's screen state + zoomBrush: false, + // does not preserve because it's a temporary state + chatMessage: false, + // does not preserve because it's a temporary state + isChatting: false, + // does not preserve because it's a temporary state + isPenMode: false, + // does not preserve because it's a temporary state + isGridMode: true, + // preserves because it's a user preference + isFocused: true, + // preserves because obviously + devicePixelRatio: true, + // preserves because it captures the user's screen state + isCoarsePointer: true, + // preserves because it captures the user's screen state + isHoveringCanvas: false, + // does not preserve because it's a temporary state + openMenus: false, + // does not preserve because it's a temporary state + isChangingStyle: false, + // does not preserve because it's a temporary state + isReadonly: true, + // preserves because it's a config option + meta: false, + // does not preserve because who knows what's in there, leave it up to sdk users to save and reinstate + duplicateProps: false + // +}; +function pluckPreservingValues(val) { + return val ? filterEntries(val, (key) => { + return shouldKeyBePreservedBetweenSessions[key]; + }) : null; +} +idValidator("instance"); +function createInstanceRecordType(stylesById) { + const stylesForNextShapeValidators = {}; + for (const [id2, style] of stylesById) { + stylesForNextShapeValidators[id2] = optional(style); + } + const instanceTypeValidator = model( + "instance", + object({ + typeName: literal("instance"), + id: idValidator("instance"), + currentPageId: pageIdValidator, + followingUserId: string.nullable(), + brush: boxModelValidator.nullable(), + opacityForNextShape: opacityValidator, + stylesForNextShape: object(stylesForNextShapeValidators), + cursor: cursorValidator, + scribbles: arrayOf(scribbleValidator), + isFocusMode: boolean, + isDebugMode: boolean, + isToolLocked: boolean, + exportBackground: boolean, + screenBounds: boxModelValidator, + insets: arrayOf(boolean), + zoomBrush: boxModelValidator.nullable(), + isPenMode: boolean, + isGridMode: boolean, + chatMessage: string, + isChatting: boolean, + highlightedUserIds: arrayOf(string), + isFocused: boolean, + devicePixelRatio: number, + isCoarsePointer: boolean, + isHoveringCanvas: boolean.nullable(), + openMenus: arrayOf(string), + isChangingStyle: boolean, + isReadonly: boolean, + meta: jsonValue, + duplicateProps: object({ + shapeIds: arrayOf(idValidator("shape")), + offset: object({ + x: number, + y: number + }) + }).nullable() + }) + ); + return createRecordType("instance", { + validator: instanceTypeValidator, + scope: "session", + ephemeralKeys: { + currentPageId: false, + meta: false, + followingUserId: true, + opacityForNextShape: true, + stylesForNextShape: true, + brush: true, + cursor: true, + scribbles: true, + isFocusMode: true, + isDebugMode: true, + isToolLocked: true, + exportBackground: true, + screenBounds: true, + insets: true, + zoomBrush: true, + isPenMode: true, + isGridMode: true, + chatMessage: true, + isChatting: true, + highlightedUserIds: true, + isFocused: true, + devicePixelRatio: true, + isCoarsePointer: true, + isHoveringCanvas: true, + openMenus: true, + isChangingStyle: true, + isReadonly: true, + duplicateProps: true + } + }).withDefaultProperties( + () => ({ + followingUserId: null, + opacityForNextShape: 1, + stylesForNextShape: {}, + brush: null, + scribbles: [], + cursor: { + type: "default", + rotation: 0 + }, + isFocusMode: false, + exportBackground: false, + isDebugMode: false, + isToolLocked: false, + screenBounds: { x: 0, y: 0, w: 1080, h: 720 }, + insets: [false, false, false, false], + zoomBrush: null, + isGridMode: false, + isPenMode: false, + chatMessage: "", + isChatting: false, + highlightedUserIds: [], + isFocused: false, + devicePixelRatio: typeof window === "undefined" ? 1 : window.devicePixelRatio, + isCoarsePointer: false, + isHoveringCanvas: null, + openMenus: [], + isChangingStyle: false, + isReadonly: false, + meta: {}, + duplicateProps: null + }) + ); +} +const instanceVersions = createMigrationIds("com.tldraw.instance", { + AddTransparentExportBgs: 1, + RemoveDialog: 2, + AddToolLockMode: 3, + RemoveExtraPropsForNextShape: 4, + AddLabelColor: 5, + AddFollowingUserId: 6, + RemoveAlignJustify: 7, + AddZoom: 8, + AddVerticalAlign: 9, + AddScribbleDelay: 10, + RemoveUserId: 11, + AddIsPenModeAndIsGridMode: 12, + HoistOpacity: 13, + AddChat: 14, + AddHighlightedUserIds: 15, + ReplacePropsForNextShapeWithStylesForNextShape: 16, + AddMeta: 17, + RemoveCursorColor: 18, + AddLonelyProperties: 19, + ReadOnlyReadonly: 20, + AddHoveringCanvas: 21, + AddScribbles: 22, + AddInset: 23, + AddDuplicateProps: 24, + RemoveCanMoveCamera: 25 +}); +const instanceMigrations = createRecordMigrationSequence({ + sequenceId: "com.tldraw.instance", + recordType: "instance", + sequence: [ + { + id: instanceVersions.AddTransparentExportBgs, + up: (instance) => { + return { ...instance, exportBackground: true }; + } + }, + { + id: instanceVersions.RemoveDialog, + up: ({ dialog: _2, ...instance }) => { + return instance; + } + }, + { + id: instanceVersions.AddToolLockMode, + up: (instance) => { + return { ...instance, isToolLocked: false }; + } + }, + { + id: instanceVersions.RemoveExtraPropsForNextShape, + up: ({ propsForNextShape, ...instance }) => { + return { + ...instance, + propsForNextShape: Object.fromEntries( + Object.entries(propsForNextShape).filter( + ([key]) => [ + "color", + "labelColor", + "dash", + "fill", + "size", + "font", + "align", + "verticalAlign", + "icon", + "geo", + "arrowheadStart", + "arrowheadEnd", + "spline" + ].includes(key) + ) + ) + }; + } + }, + { + id: instanceVersions.AddLabelColor, + up: ({ propsForNextShape, ...instance }) => { + return { + ...instance, + propsForNextShape: { + ...propsForNextShape, + labelColor: "black" + } + }; + } + }, + { + id: instanceVersions.AddFollowingUserId, + up: (instance) => { + return { ...instance, followingUserId: null }; + } + }, + { + id: instanceVersions.RemoveAlignJustify, + up: (instance) => { + let newAlign = instance.propsForNextShape.align; + if (newAlign === "justify") { + newAlign = "start"; + } + return { + ...instance, + propsForNextShape: { + ...instance.propsForNextShape, + align: newAlign + } + }; + } + }, + { + id: instanceVersions.AddZoom, + up: (instance) => { + return { ...instance, zoomBrush: null }; + } + }, + { + id: instanceVersions.AddVerticalAlign, + up: (instance) => { + return { + ...instance, + propsForNextShape: { + ...instance.propsForNextShape, + verticalAlign: "middle" + } + }; + } + }, + { + id: instanceVersions.AddScribbleDelay, + up: (instance) => { + if (instance.scribble !== null) { + return { ...instance, scribble: { ...instance.scribble, delay: 0 } }; + } + return { ...instance }; + } + }, + { + id: instanceVersions.RemoveUserId, + up: ({ userId: _2, ...instance }) => { + return instance; + } + }, + { + id: instanceVersions.AddIsPenModeAndIsGridMode, + up: (instance) => { + return { ...instance, isPenMode: false, isGridMode: false }; + } + }, + { + id: instanceVersions.HoistOpacity, + up: ({ propsForNextShape: { opacity, ...propsForNextShape }, ...instance }) => { + return { ...instance, opacityForNextShape: Number(opacity ?? "1"), propsForNextShape }; + } + }, + { + id: instanceVersions.AddChat, + up: (instance) => { + return { ...instance, chatMessage: "", isChatting: false }; + } + }, + { + id: instanceVersions.AddHighlightedUserIds, + up: (instance) => { + return { ...instance, highlightedUserIds: [] }; + } + }, + { + id: instanceVersions.ReplacePropsForNextShapeWithStylesForNextShape, + up: ({ propsForNextShape: _2, ...instance }) => { + return { ...instance, stylesForNextShape: {} }; + } + }, + { + id: instanceVersions.AddMeta, + up: (record) => { + return { + ...record, + meta: {} + }; + } + }, + { + id: instanceVersions.RemoveCursorColor, + up: (record) => { + const { color: _2, ...cursor } = record.cursor; + return { + ...record, + cursor + }; + } + }, + { + id: instanceVersions.AddLonelyProperties, + up: (record) => { + return { + ...record, + canMoveCamera: true, + isFocused: false, + devicePixelRatio: 1, + isCoarsePointer: false, + openMenus: [], + isChangingStyle: false, + isReadOnly: false + }; + } + }, + { + id: instanceVersions.ReadOnlyReadonly, + up: ({ isReadOnly: _isReadOnly, ...record }) => { + return { + ...record, + isReadonly: _isReadOnly + }; + } + }, + { + id: instanceVersions.AddHoveringCanvas, + up: (record) => { + return { + ...record, + isHoveringCanvas: null + }; + } + }, + { + id: instanceVersions.AddScribbles, + up: ({ scribble: _2, ...record }) => { + return { + ...record, + scribbles: [] + }; + } + }, + { + id: instanceVersions.AddInset, + up: (record) => { + return { + ...record, + insets: [false, false, false, false] + }; + }, + down: ({ insets: _2, ...record }) => { + return { + ...record + }; + } + }, + { + id: instanceVersions.AddDuplicateProps, + up: (record) => { + return { + ...record, + duplicateProps: null + }; + }, + down: ({ duplicateProps: _2, ...record }) => { + return { + ...record + }; + } + }, + { + id: instanceVersions.RemoveCanMoveCamera, + up: ({ canMoveCamera: _2, ...record }) => { + return { + ...record + }; + }, + down: (instance) => { + return { ...instance, canMoveCamera: true }; + } + } + ] +}); +const TLINSTANCE_ID = "instance:instance"; +const instancePageStateValidator = model( + "instance_page_state", + object({ + typeName: literal("instance_page_state"), + id: idValidator("instance_page_state"), + pageId: pageIdValidator, + selectedShapeIds: arrayOf(shapeIdValidator), + hintingShapeIds: arrayOf(shapeIdValidator), + erasingShapeIds: arrayOf(shapeIdValidator), + hoveredShapeId: shapeIdValidator.nullable(), + editingShapeId: shapeIdValidator.nullable(), + croppingShapeId: shapeIdValidator.nullable(), + focusedGroupId: shapeIdValidator.nullable(), + meta: jsonValue + }) +); +const instancePageStateVersions = createMigrationIds("com.tldraw.instance_page_state", { + AddCroppingId: 1, + RemoveInstanceIdAndCameraId: 2, + AddMeta: 3, + RenameProperties: 4, + RenamePropertiesAgain: 5 +}); +const instancePageStateMigrations = createRecordMigrationSequence({ + sequenceId: "com.tldraw.instance_page_state", + recordType: "instance_page_state", + sequence: [ + { + id: instancePageStateVersions.AddCroppingId, + up(instance) { + instance.croppingShapeId = null; + } + }, + { + id: instancePageStateVersions.RemoveInstanceIdAndCameraId, + up(instance) { + delete instance.instanceId; + delete instance.cameraId; + } + }, + { + id: instancePageStateVersions.AddMeta, + up: (record) => { + record.meta = {}; + } + }, + { + id: instancePageStateVersions.RenameProperties, + // this migration is cursed: it was written wrong and doesn't do anything. + // rather than replace it, I've added another migration below that fixes it. + up: (_record) => { + }, + down: (_record) => { + } + }, + { + id: instancePageStateVersions.RenamePropertiesAgain, + up: (record) => { + record.selectedShapeIds = record.selectedIds; + delete record.selectedIds; + record.hintingShapeIds = record.hintingIds; + delete record.hintingIds; + record.erasingShapeIds = record.erasingIds; + delete record.erasingIds; + record.hoveredShapeId = record.hoveredId; + delete record.hoveredId; + record.editingShapeId = record.editingId; + delete record.editingId; + record.croppingShapeId = record.croppingShapeId ?? record.croppingId ?? null; + delete record.croppingId; + record.focusedGroupId = record.focusLayerId; + delete record.focusLayerId; + }, + down: (record) => { + record.selectedIds = record.selectedShapeIds; + delete record.selectedShapeIds; + record.hintingIds = record.hintingShapeIds; + delete record.hintingShapeIds; + record.erasingIds = record.erasingShapeIds; + delete record.erasingShapeIds; + record.hoveredId = record.hoveredShapeId; + delete record.hoveredShapeId; + record.editingId = record.editingShapeId; + delete record.editingShapeId; + record.croppingId = record.croppingShapeId; + delete record.croppingShapeId; + record.focusLayerId = record.focusedGroupId; + delete record.focusedGroupId; + } + } + ] +}); +const InstancePageStateRecordType = createRecordType( + "instance_page_state", + { + validator: instancePageStateValidator, + scope: "session", + ephemeralKeys: { + pageId: false, + selectedShapeIds: false, + editingShapeId: false, + croppingShapeId: false, + meta: false, + hintingShapeIds: true, + erasingShapeIds: true, + hoveredShapeId: true, + focusedGroupId: true + } + } +).withDefaultProperties( + () => ({ + editingShapeId: null, + croppingShapeId: null, + selectedShapeIds: [], + hoveredShapeId: null, + erasingShapeIds: [], + hintingShapeIds: [], + focusedGroupId: null, + meta: {} + }) +); +const pointerValidator = model( + "pointer", + object({ + typeName: literal("pointer"), + id: idValidator("pointer"), + x: number, + y: number, + lastActivityTimestamp: number, + meta: jsonValue + }) +); +const pointerVersions = createMigrationIds("com.tldraw.pointer", { + AddMeta: 1 +}); +const pointerMigrations = createRecordMigrationSequence({ + sequenceId: "com.tldraw.pointer", + recordType: "pointer", + sequence: [ + { + id: pointerVersions.AddMeta, + up: (record) => { + record.meta = {}; + } + } + ] +}); +const PointerRecordType = createRecordType("pointer", { + validator: pointerValidator, + scope: "session" +}).withDefaultProperties( + () => ({ + x: 0, + y: 0, + lastActivityTimestamp: 0, + meta: {} + }) +); +const TLPOINTER_ID = PointerRecordType.createId("pointer"); +const instancePresenceValidator = model( + "instance_presence", + object({ + typeName: literal("instance_presence"), + id: idValidator("instance_presence"), + userId: string, + userName: string, + lastActivityTimestamp: number, + followingUserId: string.nullable(), + cursor: object({ + x: number, + y: number, + type: cursorTypeValidator, + rotation: number + }), + color: string, + camera: object({ + x: number, + y: number, + z: number + }), + screenBounds: boxModelValidator, + selectedShapeIds: arrayOf(idValidator("shape")), + currentPageId: idValidator("page"), + brush: boxModelValidator.nullable(), + scribbles: arrayOf(scribbleValidator), + chatMessage: string, + meta: jsonValue + }) +); +const instancePresenceVersions = createMigrationIds("com.tldraw.instance_presence", { + AddScribbleDelay: 1, + RemoveInstanceId: 2, + AddChatMessage: 3, + AddMeta: 4, + RenameSelectedShapeIds: 5 +}); +const instancePresenceMigrations = createRecordMigrationSequence({ + sequenceId: "com.tldraw.instance_presence", + recordType: "instance_presence", + sequence: [ + { + id: instancePresenceVersions.AddScribbleDelay, + up: (instance) => { + if (instance.scribble !== null) { + instance.scribble.delay = 0; + } + } + }, + { + id: instancePresenceVersions.RemoveInstanceId, + up: (instance) => { + delete instance.instanceId; + } + }, + { + id: instancePresenceVersions.AddChatMessage, + up: (instance) => { + instance.chatMessage = ""; + } + }, + { + id: instancePresenceVersions.AddMeta, + up: (record) => { + record.meta = {}; + } + }, + { + id: instancePresenceVersions.RenameSelectedShapeIds, + up: (_record) => { + } + } + ] +}); +const InstancePresenceRecordType = createRecordType( + "instance_presence", + { + validator: instancePresenceValidator, + scope: "presence" + } +).withDefaultProperties(() => ({ + lastActivityTimestamp: 0, + followingUserId: null, + color: "#FF0000", + camera: { + x: 0, + y: 0, + z: 1 + }, + cursor: { + x: 0, + y: 0, + type: "default", + rotation: 0 + }, + screenBounds: { + x: 0, + y: 0, + w: 1, + h: 1 + }, + selectedShapeIds: [], + brush: null, + scribbles: [], + chatMessage: "", + meta: {} +})); +const documentValidator = model( + "document", + object({ + typeName: literal("document"), + id: literal("document:document"), + gridSize: number, + name: string, + meta: jsonValue + }) +); +const documentVersions = createMigrationIds("com.tldraw.document", { + AddName: 1, + AddMeta: 2 +}); +const documentMigrations = createRecordMigrationSequence({ + sequenceId: "com.tldraw.document", + recordType: "document", + sequence: [ + { + id: documentVersions.AddName, + up: (document2) => { + document2.name = ""; + }, + down: (document2) => { + delete document2.name; + } + }, + { + id: documentVersions.AddMeta, + up: (record) => { + record.meta = {}; + } + } + ] +}); +const DocumentRecordType = createRecordType("document", { + validator: documentValidator, + scope: "document" +}).withDefaultProperties( + () => ({ + gridSize: 10, + name: "", + meta: {} + }) +); +const TLDOCUMENT_ID = DocumentRecordType.createId("document"); +function sortByIndex(a2, b2) { + if (a2.index < b2.index) { + return -1; + } else if (a2.index > b2.index) { + return 1; + } + return 0; } -var B$2 = { isMounted: function() { - return false; -}, enqueueForceUpdate: function() { -}, enqueueReplaceState: function() { -}, enqueueSetState: function() { -} }, C$2 = Object.assign, D$1 = {}; -function E$3(a2, b2, e2) { - this.props = a2; - this.context = b2; - this.refs = D$1; - this.updater = e2 || B$2; -} -E$3.prototype.isReactComponent = {}; -E$3.prototype.setState = function(a2, b2) { - if ("object" !== typeof a2 && "function" !== typeof a2 && null != a2) throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables."); - this.updater.enqueueSetState(this, a2, b2, "setState"); +function redactRecordForErrorReporting(record) { + if (record.typeName === "asset") { + if ("src" in record) { + record.src = ""; + } + if ("src" in record.props) { + record.props.src = ""; + } + } +} +function onValidationFailure({ + error, + phase, + record, + recordBefore +}) { + const isExistingValidationIssue = ( + // if we're initializing the store for the first time, we should + // allow invalid records so people can load old buggy data: + phase === "initialize" + ); + annotateError(error, { + tags: { + origin: "store.validateRecord", + storePhase: phase, + isExistingValidationIssue + }, + extras: { + recordBefore: recordBefore ? redactRecordForErrorReporting(structuredClone(recordBefore)) : void 0, + recordAfter: redactRecordForErrorReporting(structuredClone(record)) + } + }); + throw error; +} +function getDefaultPages() { + return [ + PageRecordType.create({ + id: "page:page", + name: "Page 1", + index: "a1", + meta: {} + }) + ]; +} +function createIntegrityChecker(store) { + const $pageIds = store.query.ids("page"); + const $pageStates = store.query.records("instance_page_state"); + const ensureStoreIsUsable = () => { + if (!store.has(TLDOCUMENT_ID)) { + store.put([DocumentRecordType.create({ id: TLDOCUMENT_ID, name: store.props.defaultName })]); + return ensureStoreIsUsable(); + } + if (!store.has(TLPOINTER_ID)) { + store.put([PointerRecordType.create({ id: TLPOINTER_ID })]); + return ensureStoreIsUsable(); + } + const pageIds = $pageIds.get(); + if (pageIds.size === 0) { + store.put(getDefaultPages()); + return ensureStoreIsUsable(); + } + const getFirstPageId = () => [...pageIds].map((id2) => store.get(id2)).sort(sortByIndex)[0].id; + const instanceState = store.get(TLINSTANCE_ID); + if (!instanceState) { + store.put([ + store.schema.types.instance.create({ + id: TLINSTANCE_ID, + currentPageId: getFirstPageId(), + exportBackground: true + }) + ]); + return ensureStoreIsUsable(); + } else if (!pageIds.has(instanceState.currentPageId)) { + store.put([{ ...instanceState, currentPageId: getFirstPageId() }]); + return ensureStoreIsUsable(); + } + const missingPageStateIds = /* @__PURE__ */ new Set(); + const missingCameraIds = /* @__PURE__ */ new Set(); + for (const id2 of pageIds) { + const pageStateId = InstancePageStateRecordType.createId(id2); + const pageState = store.get(pageStateId); + if (!pageState) { + missingPageStateIds.add(pageStateId); + } + const cameraId = CameraRecordType.createId(id2); + if (!store.has(cameraId)) { + missingCameraIds.add(cameraId); + } + } + if (missingPageStateIds.size > 0) { + store.put( + [...missingPageStateIds].map( + (id2) => InstancePageStateRecordType.create({ + id: id2, + pageId: InstancePageStateRecordType.parseId(id2) + }) + ) + ); + } + if (missingCameraIds.size > 0) { + store.put([...missingCameraIds].map((id2) => CameraRecordType.create({ id: id2 }))); + } + const pageStates = $pageStates.get(); + for (const pageState of pageStates) { + if (!pageIds.has(pageState.pageId)) { + store.remove([pageState.id]); + continue; + } + if (pageState.croppingShapeId && !store.has(pageState.croppingShapeId)) { + store.put([{ ...pageState, croppingShapeId: null }]); + return ensureStoreIsUsable(); + } + if (pageState.focusedGroupId && !store.has(pageState.focusedGroupId)) { + store.put([{ ...pageState, focusedGroupId: null }]); + return ensureStoreIsUsable(); + } + if (pageState.hoveredShapeId && !store.has(pageState.hoveredShapeId)) { + store.put([{ ...pageState, hoveredShapeId: null }]); + return ensureStoreIsUsable(); + } + const filteredSelectedIds = pageState.selectedShapeIds.filter((id2) => store.has(id2)); + if (filteredSelectedIds.length !== pageState.selectedShapeIds.length) { + store.put([{ ...pageState, selectedShapeIds: filteredSelectedIds }]); + return ensureStoreIsUsable(); + } + const filteredHintingIds = pageState.hintingShapeIds.filter((id2) => store.has(id2)); + if (filteredHintingIds.length !== pageState.hintingShapeIds.length) { + store.put([{ ...pageState, hintingShapeIds: filteredHintingIds }]); + return ensureStoreIsUsable(); + } + const filteredErasingIds = pageState.erasingShapeIds.filter((id2) => store.has(id2)); + if (filteredErasingIds.length !== pageState.erasingShapeIds.length) { + store.put([{ ...pageState, erasingShapeIds: filteredErasingIds }]); + return ensureStoreIsUsable(); + } + } + }; + return ensureStoreIsUsable; +} +const bookmarkAssetValidator = createAssetValidator( + "bookmark", + object({ + title: string, + description: string, + image: string, + favicon: string, + src: srcUrl.nullable() + }) +); +const Versions$d = createMigrationIds("com.tldraw.asset.bookmark", { + MakeUrlsValid: 1, + AddFavicon: 2 +}); +const bookmarkAssetMigrations = createRecordMigrationSequence({ + sequenceId: "com.tldraw.asset.bookmark", + recordType: "asset", + filter: (asset) => asset.type === "bookmark", + sequence: [ + { + id: Versions$d.MakeUrlsValid, + up: (asset) => { + if (!srcUrl.isValid(asset.props.src)) { + asset.props.src = ""; + } + }, + down: (_asset) => { + } + }, + { + id: Versions$d.AddFavicon, + up: (asset) => { + if (!srcUrl.isValid(asset.props.favicon)) { + asset.props.favicon = ""; + } + }, + down: (asset) => { + delete asset.props.favicon; + } + } + ] +}); +const imageAssetValidator = createAssetValidator( + "image", + object({ + w: number, + h: number, + name: string, + isAnimated: boolean, + mimeType: string.nullable(), + src: srcUrl.nullable(), + fileSize: nonZeroNumber.optional() + }) +); +const Versions$c = createMigrationIds("com.tldraw.asset.image", { + AddIsAnimated: 1, + RenameWidthHeight: 2, + MakeUrlsValid: 3, + AddFileSize: 4, + MakeFileSizeOptional: 5 +}); +const imageAssetMigrations = createRecordMigrationSequence({ + sequenceId: "com.tldraw.asset.image", + recordType: "asset", + filter: (asset) => asset.type === "image", + sequence: [ + { + id: Versions$c.AddIsAnimated, + up: (asset) => { + asset.props.isAnimated = false; + }, + down: (asset) => { + delete asset.props.isAnimated; + } + }, + { + id: Versions$c.RenameWidthHeight, + up: (asset) => { + asset.props.w = asset.props.width; + asset.props.h = asset.props.height; + delete asset.props.width; + delete asset.props.height; + }, + down: (asset) => { + asset.props.width = asset.props.w; + asset.props.height = asset.props.h; + delete asset.props.w; + delete asset.props.h; + } + }, + { + id: Versions$c.MakeUrlsValid, + up: (asset) => { + if (!srcUrl.isValid(asset.props.src)) { + asset.props.src = ""; + } + }, + down: (_asset) => { + } + }, + { + id: Versions$c.AddFileSize, + up: (asset) => { + asset.props.fileSize = -1; + }, + down: (asset) => { + delete asset.props.fileSize; + } + }, + { + id: Versions$c.MakeFileSizeOptional, + up: (asset) => { + if (asset.props.fileSize === -1) { + asset.props.fileSize = void 0; + } + }, + down: (asset) => { + if (asset.props.fileSize === void 0) { + asset.props.fileSize = -1; + } + } + } + ] +}); +const videoAssetValidator = createAssetValidator( + "video", + object({ + w: number, + h: number, + name: string, + isAnimated: boolean, + mimeType: string.nullable(), + src: srcUrl.nullable(), + fileSize: number.optional() + }) +); +const Versions$b = createMigrationIds("com.tldraw.asset.video", { + AddIsAnimated: 1, + RenameWidthHeight: 2, + MakeUrlsValid: 3, + AddFileSize: 4, + MakeFileSizeOptional: 5 +}); +const videoAssetMigrations = createRecordMigrationSequence({ + sequenceId: "com.tldraw.asset.video", + recordType: "asset", + filter: (asset) => asset.type === "video", + sequence: [ + { + id: Versions$b.AddIsAnimated, + up: (asset) => { + asset.props.isAnimated = false; + }, + down: (asset) => { + delete asset.props.isAnimated; + } + }, + { + id: Versions$b.RenameWidthHeight, + up: (asset) => { + asset.props.w = asset.props.width; + asset.props.h = asset.props.height; + delete asset.props.width; + delete asset.props.height; + }, + down: (asset) => { + asset.props.width = asset.props.w; + asset.props.height = asset.props.h; + delete asset.props.w; + delete asset.props.h; + } + }, + { + id: Versions$b.MakeUrlsValid, + up: (asset) => { + if (!srcUrl.isValid(asset.props.src)) { + asset.props.src = ""; + } + }, + down: (_asset) => { + } + }, + { + id: Versions$b.AddFileSize, + up: (asset) => { + asset.props.fileSize = -1; + }, + down: (asset) => { + delete asset.props.fileSize; + } + }, + { + id: Versions$b.MakeFileSizeOptional, + up: (asset) => { + if (asset.props.fileSize === -1) { + asset.props.fileSize = void 0; + } + }, + down: (asset) => { + if (asset.props.fileSize === void 0) { + asset.props.fileSize = -1; + } + } + } + ] +}); +const assetValidator = model( + "asset", + union("type", { + image: imageAssetValidator, + video: videoAssetValidator, + bookmark: bookmarkAssetValidator + }) +); +const assetVersions = createMigrationIds("com.tldraw.asset", { + AddMeta: 1 +}); +const assetMigrations = createRecordMigrationSequence({ + sequenceId: "com.tldraw.asset", + recordType: "asset", + sequence: [ + { + id: assetVersions.AddMeta, + up: (record) => { + record.meta = {}; + } + } + ] +}); +const AssetRecordType = createRecordType("asset", { + validator: assetValidator, + scope: "document" +}).withDefaultProperties(() => ({ + meta: {} +})); +const bookmarkShapeProps = { + w: nonZeroNumber, + h: nonZeroNumber, + assetId: assetIdValidator.nullable(), + url: linkUrl +}; +const Versions$a = createShapePropsMigrationIds("bookmark", { + NullAssetId: 1, + MakeUrlsValid: 2 +}); +const bookmarkShapeMigrations = createShapePropsMigrationSequence({ + sequence: [ + { + id: Versions$a.NullAssetId, + up: (props) => { + if (props.assetId === void 0) { + props.assetId = null; + } + }, + down: "retired" + }, + { + id: Versions$a.MakeUrlsValid, + up: (props) => { + if (!linkUrl.isValid(props.url)) { + props.url = ""; + } + }, + down: (_props) => { + } + } + ] +}); +const DrawShapeSegment = object({ + type: literalEnum("free", "straight"), + points: arrayOf(vecModelValidator) +}); +const drawShapeProps = { + color: DefaultColorStyle, + fill: DefaultFillStyle, + dash: DefaultDashStyle, + size: DefaultSizeStyle, + segments: arrayOf(DrawShapeSegment), + isComplete: boolean, + isClosed: boolean, + isPen: boolean, + scale: nonZeroNumber +}; +const Versions$9 = createShapePropsMigrationIds("draw", { + AddInPen: 1, + AddScale: 2 +}); +const drawShapeMigrations = createShapePropsMigrationSequence({ + sequence: [ + { + id: Versions$9.AddInPen, + up: (props) => { + const { points } = props.segments[0]; + if (points.length === 0) { + props.isPen = false; + return; + } + let isPen = !(points[0].z === 0 || points[0].z === 0.5); + if (points[1]) { + isPen = isPen && !(points[1].z === 0 || points[1].z === 0.5); + } + props.isPen = isPen; + }, + down: "retired" + }, + { + id: Versions$9.AddScale, + up: (props) => { + props.scale = 1; + }, + down: (props) => { + delete props.scale; + } + } + ] +}); +const TLDRAW_APP_RE$1 = /(^\/r\/[^/]+\/?$)/; +const EMBED_DEFINITIONS = [ + { + hostnames: ["beta.tldraw.com", "tldraw.com", "localhost:3000"], + fromEmbedUrl: (url) => { + const urlObj = safeParseUrl(url); + if (urlObj && urlObj.pathname.match(TLDRAW_APP_RE$1)) { + return url; + } + return; + } + }, + { + hostnames: ["figma.com"], + fromEmbedUrl: (url) => { + const urlObj = safeParseUrl(url); + if (urlObj && urlObj.pathname.match(/^\/embed\/?$/)) { + const outUrl = urlObj.searchParams.get("url"); + if (outUrl) { + return outUrl; + } + } + return; + } + }, + { + hostnames: ["google.*"], + fromEmbedUrl: (url) => { + const urlObj = safeParseUrl(url); + if (!urlObj) return; + const matches = urlObj.pathname.match(/^\/maps\/embed\/v1\/view\/?$/); + if (matches && urlObj.searchParams.has("center") && urlObj.searchParams.get("zoom")) { + const zoom = urlObj.searchParams.get("zoom"); + const [lat, lon] = urlObj.searchParams.get("center").split(","); + return `https://www.google.com/maps/@${lat},${lon},${zoom}z`; + } + return; + } + }, + { + hostnames: ["val.town"], + fromEmbedUrl: (url) => { + const urlObj = safeParseUrl(url); + const matches = urlObj && urlObj.pathname.match(/\/embed\/(.+)\/?/); + if (matches) { + return `https://www.val.town/v/${matches[1]}`; + } + return; + } + }, + { + hostnames: ["codesandbox.io"], + fromEmbedUrl: (url) => { + const urlObj = safeParseUrl(url); + const matches = urlObj && urlObj.pathname.match(/\/embed\/([^/]+)\/?/); + if (matches) { + return `https://codesandbox.io/s/${matches[1]}`; + } + return; + } + }, + { + hostnames: ["codepen.io"], + fromEmbedUrl: (url) => { + const CODEPEN_EMBED_REGEXP = /https:\/\/codepen.io\/([^/]+)\/embed\/([^/]+)/; + const matches = url.match(CODEPEN_EMBED_REGEXP); + if (matches) { + const [_2, user, id2] = matches; + return `https://codepen.io/${user}/pen/${id2}`; + } + return; + } + }, + { + hostnames: ["scratch.mit.edu"], + fromEmbedUrl: (url) => { + const SCRATCH_EMBED_REGEXP = /https:\/\/scratch.mit.edu\/projects\/embed\/([^/]+)/; + const matches = url.match(SCRATCH_EMBED_REGEXP); + if (matches) { + const [_2, id2] = matches; + return `https://scratch.mit.edu/projects/${id2}`; + } + return; + } + }, + { + hostnames: ["*.youtube.com", "youtube.com", "youtu.be"], + fromEmbedUrl: (url) => { + const urlObj = safeParseUrl(url); + if (!urlObj) return; + const hostname = urlObj.hostname.replace(/^www./, ""); + if (hostname === "youtube.com") { + const matches = urlObj.pathname.match(/^\/embed\/([^/]+)\/?/); + if (matches) { + return `https://www.youtube.com/watch?v=${matches[1]}`; + } + } + return; + } + }, + { + hostnames: ["calendar.google.*"], + fromEmbedUrl: (url) => { + const urlObj = safeParseUrl(url); + const srcQs = urlObj == null ? void 0 : urlObj.searchParams.get("src"); + if ((urlObj == null ? void 0 : urlObj.pathname.match(/\/calendar\/embed/)) && srcQs) { + urlObj.pathname = "/calendar/u/0"; + const keys3 = Array.from(urlObj.searchParams.keys()); + for (const key of keys3) { + urlObj.searchParams.delete(key); + } + urlObj.searchParams.set("cid", srcQs); + return urlObj.href; + } + return; + } + }, + { + hostnames: ["docs.google.*"], + fromEmbedUrl: (url) => { + const urlObj = safeParseUrl(url); + if ((urlObj == null ? void 0 : urlObj.pathname.match(/^\/presentation/)) && (urlObj == null ? void 0 : urlObj.pathname.match(/\/embed\/?$/))) { + urlObj.pathname = urlObj.pathname.replace(/\/embed$/, "/pub"); + const keys3 = Array.from(urlObj.searchParams.keys()); + for (const key of keys3) { + urlObj.searchParams.delete(key); + } + return urlObj.href; + } + return; + } + }, + { + hostnames: ["gist.github.com"], + fromEmbedUrl: (url) => { + const urlObj = safeParseUrl(url); + if (urlObj && urlObj.pathname.match(/\/([^/]+)\/([^/]+)/)) { + if (!url.split("/").pop()) return; + return url; + } + return; + } + }, + { + hostnames: ["replit.com"], + fromEmbedUrl: (url) => { + const urlObj = safeParseUrl(url); + if (urlObj && urlObj.pathname.match(/\/@([^/]+)\/([^/]+)/) && urlObj.searchParams.has("embed")) { + urlObj.searchParams.delete("embed"); + return urlObj.href; + } + return; + } + }, + { + hostnames: ["felt.com"], + fromEmbedUrl: (url) => { + const urlObj = safeParseUrl(url); + if (urlObj && urlObj.pathname.match(/^\/embed\/map\//)) { + urlObj.pathname = urlObj.pathname.replace(/^\/embed/, ""); + return urlObj.href; + } + return; + } + }, + { + hostnames: ["open.spotify.com"], + fromEmbedUrl: (url) => { + const urlObj = safeParseUrl(url); + if (urlObj && urlObj.pathname.match(/^\/embed\/(artist|album)\//)) { + return urlObj.origin + urlObj.pathname.replace(/^\/embed/, ""); + } + return; + } + }, + { + hostnames: ["vimeo.com", "player.vimeo.com"], + fromEmbedUrl: (url) => { + const urlObj = safeParseUrl(url); + if (urlObj && urlObj.hostname === "player.vimeo.com") { + const matches = urlObj.pathname.match(/^\/video\/([^/]+)\/?$/); + if (matches) { + return "https://vimeo.com/" + matches[1]; + } + } + return; + } + }, + { + hostnames: ["excalidraw.com"], + fromEmbedUrl: (url) => { + const urlObj = safeParseUrl(url); + if (urlObj && urlObj.hash.match(/#room=/)) { + return url; + } + return; + } + }, + { + hostnames: ["observablehq.com"], + fromEmbedUrl: (url) => { + const urlObj = safeParseUrl(url); + if (urlObj && urlObj.pathname.match(/^\/embed\/@([^/]+)\/([^/]+)\/?$/)) { + return `${urlObj.origin}${urlObj.pathname.replace("/embed", "")}#cell-*`; + } + if (urlObj && urlObj.pathname.match(/^\/embed\/([^/]+)\/?$/)) { + return `${urlObj.origin}${urlObj.pathname.replace("/embed", "/d")}#cell-*`; + } + return; + } + }, + { + hostnames: ["desmos.com"], + fromEmbedUrl: (url) => { + const urlObj = safeParseUrl(url); + if (urlObj && urlObj.hostname === "www.desmos.com" && urlObj.pathname.match(/^\/calculator\/([^/]+)\/?$/) && urlObj.search === "?embed" && urlObj.hash === "") { + return url.replace("?embed", ""); + } + return; + } + } +]; +const embedShapeProps = { + w: nonZeroNumber, + h: nonZeroNumber, + url: string +}; +const Versions$8 = createShapePropsMigrationIds("embed", { + GenOriginalUrlInEmbed: 1, + RemoveDoesResize: 2, + RemoveTmpOldUrl: 3, + RemovePermissionOverrides: 4 +}); +const embedShapeMigrations = createShapePropsMigrationSequence({ + sequence: [ + { + id: Versions$8.GenOriginalUrlInEmbed, + // add tmpOldUrl property + up: (props) => { + try { + const url = props.url; + const host = new URL(url).host.replace("www.", ""); + let originalUrl; + for (const localEmbedDef of EMBED_DEFINITIONS) { + if (localEmbedDef.hostnames.includes(host)) { + try { + originalUrl = localEmbedDef.fromEmbedUrl(url); + } catch (err) { + console.warn(err); + } + } + } + props.tmpOldUrl = props.url; + props.url = originalUrl ?? ""; + } catch { + props.url = ""; + props.tmpOldUrl = props.url; + } + }, + down: "retired" + }, + { + id: Versions$8.RemoveDoesResize, + up: (props) => { + delete props.doesResize; + }, + down: "retired" + }, + { + id: Versions$8.RemoveTmpOldUrl, + up: (props) => { + delete props.tmpOldUrl; + }, + down: "retired" + }, + { + id: Versions$8.RemovePermissionOverrides, + up: (props) => { + delete props.overridePermissions; + }, + down: "retired" + } + ] +}); +const frameShapeProps = { + w: nonZeroNumber, + h: nonZeroNumber, + name: string }; -E$3.prototype.forceUpdate = function(a2) { - this.updater.enqueueForceUpdate(this, a2, "forceUpdate"); +const frameShapeMigrations = createShapePropsMigrationSequence({ + sequence: [] +}); +const DefaultHorizontalAlignStyle = StyleProp.defineEnum("tldraw:horizontalAlign", { + defaultValue: "middle", + values: ["start", "middle", "end", "start-legacy", "end-legacy", "middle-legacy"] +}); +const DefaultVerticalAlignStyle = StyleProp.defineEnum("tldraw:verticalAlign", { + defaultValue: "middle", + values: ["start", "middle", "end"] +}); +const GeoShapeGeoStyle = StyleProp.defineEnum("tldraw:geo", { + defaultValue: "rectangle", + values: [ + "cloud", + "rectangle", + "ellipse", + "triangle", + "diamond", + "pentagon", + "hexagon", + "octagon", + "star", + "rhombus", + "rhombus-2", + "oval", + "trapezoid", + "arrow-right", + "arrow-left", + "arrow-up", + "arrow-down", + "x-box", + "check-box", + "heart" + ] +}); +const geoShapeProps = { + geo: GeoShapeGeoStyle, + labelColor: DefaultLabelColorStyle, + color: DefaultColorStyle, + fill: DefaultFillStyle, + dash: DefaultDashStyle, + size: DefaultSizeStyle, + font: DefaultFontStyle, + align: DefaultHorizontalAlignStyle, + verticalAlign: DefaultVerticalAlignStyle, + url: linkUrl, + w: nonZeroNumber, + h: nonZeroNumber, + growY: positiveNumber, + text: string, + scale: nonZeroNumber }; -function F() { -} -F.prototype = E$3.prototype; -function G$1(a2, b2, e2) { - this.props = a2; - this.context = b2; - this.refs = D$1; - this.updater = e2 || B$2; -} -var H$1 = G$1.prototype = new F(); -H$1.constructor = G$1; -C$2(H$1, E$3.prototype); -H$1.isPureReactComponent = true; -var I$2 = Array.isArray, J = Object.prototype.hasOwnProperty, K$1 = { current: null }, L$1 = { key: true, ref: true, __self: true, __source: true }; -function M$2(a2, b2, e2) { - var d2, c2 = {}, k2 = null, h2 = null; - if (null != b2) for (d2 in void 0 !== b2.ref && (h2 = b2.ref), void 0 !== b2.key && (k2 = "" + b2.key), b2) J.call(b2, d2) && !L$1.hasOwnProperty(d2) && (c2[d2] = b2[d2]); - var g2 = arguments.length - 2; - if (1 === g2) c2.children = e2; - else if (1 < g2) { - for (var f2 = Array(g2), m2 = 0; m2 < g2; m2++) f2[m2] = arguments[m2 + 2]; - c2.children = f2; - } - if (a2 && a2.defaultProps) for (d2 in g2 = a2.defaultProps, g2) void 0 === c2[d2] && (c2[d2] = g2[d2]); - return { $$typeof: l$3, type: a2, key: k2, ref: h2, props: c2, _owner: K$1.current }; -} -function N$1(a2, b2) { - return { $$typeof: l$3, type: a2.type, key: b2, ref: a2.ref, props: a2.props, _owner: a2._owner }; -} -function O$2(a2) { - return "object" === typeof a2 && null !== a2 && a2.$$typeof === l$3; -} -function escape(a2) { - var b2 = { "=": "=0", ":": "=2" }; - return "$" + a2.replace(/[=:]/g, function(a3) { - return b2[a3]; - }); -} -var P$2 = /\/+/g; -function Q$1(a2, b2) { - return "object" === typeof a2 && null !== a2 && null != a2.key ? escape("" + a2.key) : b2.toString(36); -} -function R$2(a2, b2, e2, d2, c2) { - var k2 = typeof a2; - if ("undefined" === k2 || "boolean" === k2) a2 = null; - var h2 = false; - if (null === a2) h2 = true; - else switch (k2) { - case "string": - case "number": - h2 = true; - break; - case "object": - switch (a2.$$typeof) { - case l$3: - case n$2: - h2 = true; - } - } - if (h2) return h2 = a2, c2 = c2(h2), a2 = "" === d2 ? "." + Q$1(h2, 0) : d2, I$2(c2) ? (e2 = "", null != a2 && (e2 = a2.replace(P$2, "$&/") + "/"), R$2(c2, b2, e2, "", function(a3) { - return a3; - })) : null != c2 && (O$2(c2) && (c2 = N$1(c2, e2 + (!c2.key || h2 && h2.key === c2.key ? "" : ("" + c2.key).replace(P$2, "$&/") + "/") + a2)), b2.push(c2)), 1; - h2 = 0; - d2 = "" === d2 ? "." : d2 + ":"; - if (I$2(a2)) for (var g2 = 0; g2 < a2.length; g2++) { - k2 = a2[g2]; - var f2 = d2 + Q$1(k2, g2); - h2 += R$2(k2, b2, e2, f2, c2); - } - else if (f2 = A$1(a2), "function" === typeof f2) for (a2 = f2.call(a2), g2 = 0; !(k2 = a2.next()).done; ) k2 = k2.value, f2 = d2 + Q$1(k2, g2++), h2 += R$2(k2, b2, e2, f2, c2); - else if ("object" === k2) throw b2 = String(a2), Error("Objects are not valid as a React child (found: " + ("[object Object]" === b2 ? "object with keys {" + Object.keys(a2).join(", ") + "}" : b2) + "). If you meant to render a collection of children, use an array instead."); - return h2; -} -function S$2(a2, b2, e2) { - if (null == a2) return a2; - var d2 = [], c2 = 0; - R$2(a2, d2, "", "", function(a3) { - return b2.call(e2, a3, c2++); - }); - return d2; -} -function T$1(a2) { - if (-1 === a2._status) { - var b2 = a2._result; - b2 = b2(); - b2.then(function(b3) { - if (0 === a2._status || -1 === a2._status) a2._status = 1, a2._result = b3; - }, function(b3) { - if (0 === a2._status || -1 === a2._status) a2._status = 2, a2._result = b3; - }); - -1 === a2._status && (a2._status = 0, a2._result = b2); - } - if (1 === a2._status) return a2._result.default; - throw a2._result; -} -var U$1 = { current: null }, V$2 = { transition: null }, W$1 = { ReactCurrentDispatcher: U$1, ReactCurrentBatchConfig: V$2, ReactCurrentOwner: K$1 }; -function X$1() { - throw Error("act(...) is not supported in production builds of React."); -} -react_production_min.Children = { map: S$2, forEach: function(a2, b2, e2) { - S$2(a2, function() { - b2.apply(this, arguments); - }, e2); -}, count: function(a2) { - var b2 = 0; - S$2(a2, function() { - b2++; - }); - return b2; -}, toArray: function(a2) { - return S$2(a2, function(a3) { - return a3; - }) || []; -}, only: function(a2) { - if (!O$2(a2)) throw Error("React.Children.only expected to receive a single React element child."); - return a2; -} }; -react_production_min.Component = E$3; -react_production_min.Fragment = p$4; -react_production_min.Profiler = r$1; -react_production_min.PureComponent = G$1; -react_production_min.StrictMode = q$2; -react_production_min.Suspense = w$2; -react_production_min.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = W$1; -react_production_min.act = X$1; -react_production_min.cloneElement = function(a2, b2, e2) { - if (null === a2 || void 0 === a2) throw Error("React.cloneElement(...): The argument must be a React element, but you passed " + a2 + "."); - var d2 = C$2({}, a2.props), c2 = a2.key, k2 = a2.ref, h2 = a2._owner; - if (null != b2) { - void 0 !== b2.ref && (k2 = b2.ref, h2 = K$1.current); - void 0 !== b2.key && (c2 = "" + b2.key); - if (a2.type && a2.type.defaultProps) var g2 = a2.type.defaultProps; - for (f2 in b2) J.call(b2, f2) && !L$1.hasOwnProperty(f2) && (d2[f2] = void 0 === b2[f2] && void 0 !== g2 ? g2[f2] : b2[f2]); - } - var f2 = arguments.length - 2; - if (1 === f2) d2.children = e2; - else if (1 < f2) { - g2 = Array(f2); - for (var m2 = 0; m2 < f2; m2++) g2[m2] = arguments[m2 + 2]; - d2.children = g2; - } - return { $$typeof: l$3, type: a2.type, key: c2, ref: k2, props: d2, _owner: h2 }; +const geoShapeVersions = createShapePropsMigrationIds("geo", { + AddUrlProp: 1, + AddLabelColor: 2, + RemoveJustify: 3, + AddCheckBox: 4, + AddVerticalAlign: 5, + MigrateLegacyAlign: 6, + AddCloud: 7, + MakeUrlsValid: 8, + AddScale: 9 +}); +const geoShapeMigrations = createShapePropsMigrationSequence({ + sequence: [ + { + id: geoShapeVersions.AddUrlProp, + up: (props) => { + props.url = ""; + }, + down: "retired" + }, + { + id: geoShapeVersions.AddLabelColor, + up: (props) => { + props.labelColor = "black"; + }, + down: "retired" + }, + { + id: geoShapeVersions.RemoveJustify, + up: (props) => { + if (props.align === "justify") { + props.align = "start"; + } + }, + down: "retired" + }, + { + id: geoShapeVersions.AddCheckBox, + up: (_props) => { + }, + down: "retired" + }, + { + id: geoShapeVersions.AddVerticalAlign, + up: (props) => { + props.verticalAlign = "middle"; + }, + down: "retired" + }, + { + id: geoShapeVersions.MigrateLegacyAlign, + up: (props) => { + let newAlign; + switch (props.align) { + case "start": + newAlign = "start-legacy"; + break; + case "end": + newAlign = "end-legacy"; + break; + default: + newAlign = "middle-legacy"; + break; + } + props.align = newAlign; + }, + down: "retired" + }, + { + id: geoShapeVersions.AddCloud, + up: (_props) => { + }, + down: "retired" + }, + { + id: geoShapeVersions.MakeUrlsValid, + up: (props) => { + if (!linkUrl.isValid(props.url)) { + props.url = ""; + } + }, + down: (_props) => { + } + }, + { + id: geoShapeVersions.AddScale, + up: (props) => { + props.scale = 1; + }, + down: (props) => { + delete props.scale; + } + } + ] +}); +const groupShapeProps = {}; +const groupShapeMigrations = createShapePropsMigrationSequence({ sequence: [] }); +const highlightShapeProps = { + color: DefaultColorStyle, + size: DefaultSizeStyle, + segments: arrayOf(DrawShapeSegment), + isComplete: boolean, + isPen: boolean, + scale: nonZeroNumber +}; +const Versions$7 = createShapePropsMigrationIds("highlight", { + AddScale: 1 +}); +const highlightShapeMigrations = createShapePropsMigrationSequence({ + sequence: [ + { + id: Versions$7.AddScale, + up: (props) => { + props.scale = 1; + }, + down: (props) => { + delete props.scale; + } + } + ] +}); +const ImageShapeCrop = object({ + topLeft: vecModelValidator, + bottomRight: vecModelValidator +}); +const imageShapeProps = { + w: nonZeroNumber, + h: nonZeroNumber, + playing: boolean, + url: linkUrl, + assetId: assetIdValidator.nullable(), + crop: ImageShapeCrop.nullable(), + flipX: boolean, + flipY: boolean }; -react_production_min.createContext = function(a2) { - a2 = { $$typeof: u$2, _currentValue: a2, _currentValue2: a2, _threadCount: 0, Provider: null, Consumer: null, _defaultValue: null, _globalName: null }; - a2.Provider = { $$typeof: t$3, _context: a2 }; - return a2.Consumer = a2; +const Versions$6 = createShapePropsMigrationIds("image", { + AddUrlProp: 1, + AddCropProp: 2, + MakeUrlsValid: 3, + AddFlipProps: 4 +}); +const imageShapeMigrations = createShapePropsMigrationSequence({ + sequence: [ + { + id: Versions$6.AddUrlProp, + up: (props) => { + props.url = ""; + }, + down: "retired" + }, + { + id: Versions$6.AddCropProp, + up: (props) => { + props.crop = null; + }, + down: (props) => { + delete props.crop; + } + }, + { + id: Versions$6.MakeUrlsValid, + up: (props) => { + if (!linkUrl.isValid(props.url)) { + props.url = ""; + } + }, + down: (_props) => { + } + }, + { + id: Versions$6.AddFlipProps, + up: (props) => { + props.flipX = false; + props.flipY = false; + }, + down: (props) => { + delete props.flipX; + delete props.flipY; + } + } + ] +}); +const LineShapeSplineStyle = StyleProp.defineEnum("tldraw:spline", { + defaultValue: "line", + values: ["cubic", "line"] +}); +const lineShapePointValidator = object({ + id: string, + index: indexKey, + x: number, + y: number +}); +const lineShapeProps = { + color: DefaultColorStyle, + dash: DefaultDashStyle, + size: DefaultSizeStyle, + spline: LineShapeSplineStyle, + points: dict(string, lineShapePointValidator), + scale: nonZeroNumber }; -react_production_min.createElement = M$2; -react_production_min.createFactory = function(a2) { - var b2 = M$2.bind(null, a2); - b2.type = a2; - return b2; +const lineShapeVersions = createShapePropsMigrationIds("line", { + AddSnapHandles: 1, + RemoveExtraHandleProps: 2, + HandlesToPoints: 3, + PointIndexIds: 4, + AddScale: 5 +}); +const lineShapeMigrations = createShapePropsMigrationSequence({ + sequence: [ + { + id: lineShapeVersions.AddSnapHandles, + up: (props) => { + for (const handle of Object.values(props.handles)) { + handle.canSnap = true; + } + }, + down: "retired" + }, + { + id: lineShapeVersions.RemoveExtraHandleProps, + up: (props) => { + props.handles = objectMapFromEntries( + Object.values(props.handles).map((handle) => [ + handle.index, + { + x: handle.x, + y: handle.y + } + ]) + ); + }, + down: (props) => { + const handles = Object.entries(props.handles).map(([index2, handle]) => ({ index: index2, ...handle })).sort(sortByIndex$1); + props.handles = Object.fromEntries( + handles.map((handle, i2) => { + const id2 = i2 === 0 ? "start" : i2 === handles.length - 1 ? "end" : `handle:${handle.index}`; + return [ + id2, + { + id: id2, + type: "vertex", + canBind: false, + canSnap: true, + index: handle.index, + x: handle.x, + y: handle.y + } + ]; + }) + ); + } + }, + { + id: lineShapeVersions.HandlesToPoints, + up: (props) => { + const sortedHandles = Object.entries(props.handles).map(([index2, { x: x2, y: y2 }]) => ({ x: x2, y: y2, index: index2 })).sort(sortByIndex$1); + props.points = sortedHandles.map(({ x: x2, y: y2 }) => ({ x: x2, y: y2 })); + delete props.handles; + }, + down: (props) => { + const indices = getIndices(props.points.length); + props.handles = Object.fromEntries( + props.points.map((handle, i2) => { + const index2 = indices[i2]; + return [ + index2, + { + x: handle.x, + y: handle.y + } + ]; + }) + ); + delete props.points; + } + }, + { + id: lineShapeVersions.PointIndexIds, + up: (props) => { + const indices = getIndices(props.points.length); + props.points = Object.fromEntries( + props.points.map((point, i2) => { + const id2 = indices[i2]; + return [ + id2, + { + id: id2, + index: id2, + x: point.x, + y: point.y + } + ]; + }) + ); + }, + down: (props) => { + const sortedHandles = Object.values(props.points).sort(sortByIndex$1); + props.points = sortedHandles.map(({ x: x2, y: y2 }) => ({ x: x2, y: y2 })); + } + }, + { + id: lineShapeVersions.AddScale, + up: (props) => { + props.scale = 1; + }, + down: (props) => { + delete props.scale; + } + } + ] +}); +const noteShapeProps = { + color: DefaultColorStyle, + labelColor: DefaultLabelColorStyle, + size: DefaultSizeStyle, + font: DefaultFontStyle, + fontSizeAdjustment: positiveNumber, + align: DefaultHorizontalAlignStyle, + verticalAlign: DefaultVerticalAlignStyle, + growY: positiveNumber, + url: linkUrl, + text: string, + scale: nonZeroNumber }; -react_production_min.createRef = function() { - return { current: null }; +const Versions$5 = createShapePropsMigrationIds("note", { + AddUrlProp: 1, + RemoveJustify: 2, + MigrateLegacyAlign: 3, + AddVerticalAlign: 4, + MakeUrlsValid: 5, + AddFontSizeAdjustment: 6, + AddScale: 7, + AddLabelColor: 8 +}); +const noteShapeMigrations = createShapePropsMigrationSequence({ + sequence: [ + { + id: Versions$5.AddUrlProp, + up: (props) => { + props.url = ""; + }, + down: "retired" + }, + { + id: Versions$5.RemoveJustify, + up: (props) => { + if (props.align === "justify") { + props.align = "start"; + } + }, + down: "retired" + }, + { + id: Versions$5.MigrateLegacyAlign, + up: (props) => { + switch (props.align) { + case "start": + props.align = "start-legacy"; + return; + case "end": + props.align = "end-legacy"; + return; + default: + props.align = "middle-legacy"; + return; + } + }, + down: "retired" + }, + { + id: Versions$5.AddVerticalAlign, + up: (props) => { + props.verticalAlign = "middle"; + }, + down: "retired" + }, + { + id: Versions$5.MakeUrlsValid, + up: (props) => { + if (!linkUrl.isValid(props.url)) { + props.url = ""; + } + }, + down: (_props) => { + } + }, + { + id: Versions$5.AddFontSizeAdjustment, + up: (props) => { + props.fontSizeAdjustment = 0; + }, + down: (props) => { + delete props.fontSizeAdjustment; + } + }, + { + id: Versions$5.AddScale, + up: (props) => { + props.scale = 1; + }, + down: (props) => { + delete props.scale; + } + }, + { + id: Versions$5.AddLabelColor, + up: (props) => { + props.labelColor = "black"; + }, + down: (props) => { + delete props.labelColor; + } + } + ] +}); +const DefaultTextAlignStyle = StyleProp.defineEnum("tldraw:textAlign", { + defaultValue: "start", + values: ["start", "middle", "end"] +}); +const textShapeProps = { + color: DefaultColorStyle, + size: DefaultSizeStyle, + font: DefaultFontStyle, + textAlign: DefaultTextAlignStyle, + w: nonZeroNumber, + text: string, + scale: nonZeroNumber, + autoSize: boolean }; -react_production_min.forwardRef = function(a2) { - return { $$typeof: v$2, render: a2 }; +const Versions$4 = createShapePropsMigrationIds("text", { + RemoveJustify: 1, + AddTextAlign: 2 +}); +const textShapeMigrations = createShapePropsMigrationSequence({ + sequence: [ + { + id: Versions$4.RemoveJustify, + up: (props) => { + if (props.align === "justify") { + props.align = "start"; + } + }, + down: "retired" + }, + { + id: Versions$4.AddTextAlign, + up: (props) => { + props.textAlign = props.align; + delete props.align; + }, + down: (props) => { + props.align = props.textAlign; + delete props.textAlign; + } + } + ] +}); +const videoShapeProps = { + w: nonZeroNumber, + h: nonZeroNumber, + time: number, + playing: boolean, + url: linkUrl, + assetId: assetIdValidator.nullable() }; -react_production_min.isValidElement = O$2; -react_production_min.lazy = function(a2) { - return { $$typeof: y$1, _payload: { _status: -1, _result: a2 }, _init: T$1 }; +const Versions$3 = createShapePropsMigrationIds("video", { + AddUrlProp: 1, + MakeUrlsValid: 2 +}); +const videoShapeMigrations = createShapePropsMigrationSequence({ + sequence: [ + { + id: Versions$3.AddUrlProp, + up: (props) => { + props.url = ""; + }, + down: "retired" + }, + { + id: Versions$3.MakeUrlsValid, + up: (props) => { + if (!linkUrl.isValid(props.url)) { + props.url = ""; + } + }, + down: (_props) => { + } + } + ] +}); +const Versions$2 = createMigrationIds("com.tldraw.store", { + RemoveCodeAndIconShapeTypes: 1, + AddInstancePresenceType: 2, + RemoveTLUserAndPresenceAndAddPointer: 3, + RemoveUserDocument: 4 +}); +const storeMigrations = createMigrationSequence({ + sequenceId: "com.tldraw.store", + retroactive: false, + sequence: [ + { + id: Versions$2.RemoveCodeAndIconShapeTypes, + scope: "store", + up: (store) => { + for (const [id2, record] of objectMapEntries(store)) { + if (record.typeName === "shape" && (record.type === "icon" || record.type === "code")) { + delete store[id2]; + } + } + } + }, + { + id: Versions$2.AddInstancePresenceType, + scope: "store", + up(_store) { + } + }, + { + // remove user and presence records and add pointer records + id: Versions$2.RemoveTLUserAndPresenceAndAddPointer, + scope: "store", + up: (store) => { + for (const [id2, record] of objectMapEntries(store)) { + if (record.typeName.match(/^(user|user_presence)$/)) { + delete store[id2]; + } + } + } + }, + { + // remove user document records + id: Versions$2.RemoveUserDocument, + scope: "store", + up: (store) => { + for (const [id2, record] of objectMapEntries(store)) { + if (record.typeName.match("user_document")) { + delete store[id2]; + } + } + } + } + ] +}); +const defaultShapeSchemas = { + arrow: { migrations: arrowShapeMigrations, props: arrowShapeProps }, + bookmark: { migrations: bookmarkShapeMigrations, props: bookmarkShapeProps }, + draw: { migrations: drawShapeMigrations, props: drawShapeProps }, + embed: { migrations: embedShapeMigrations, props: embedShapeProps }, + frame: { migrations: frameShapeMigrations, props: frameShapeProps }, + geo: { migrations: geoShapeMigrations, props: geoShapeProps }, + group: { migrations: groupShapeMigrations, props: groupShapeProps }, + highlight: { migrations: highlightShapeMigrations, props: highlightShapeProps }, + image: { migrations: imageShapeMigrations, props: imageShapeProps }, + line: { migrations: lineShapeMigrations, props: lineShapeProps }, + note: { migrations: noteShapeMigrations, props: noteShapeProps }, + text: { migrations: textShapeMigrations, props: textShapeProps }, + video: { migrations: videoShapeMigrations, props: videoShapeProps } }; -react_production_min.memo = function(a2, b2) { - return { $$typeof: x$1, type: a2, compare: void 0 === b2 ? null : b2 }; +const defaultBindingSchemas = { + arrow: { migrations: arrowBindingMigrations, props: arrowBindingProps } }; -react_production_min.startTransition = function(a2) { - var b2 = V$2.transition; - V$2.transition = {}; - try { - a2(); - } finally { - V$2.transition = b2; +function createTLSchema({ + shapes = defaultShapeSchemas, + bindings = defaultBindingSchemas, + migrations +} = {}) { + const stylesById = /* @__PURE__ */ new Map(); + for (const shape of objectMapValues(shapes)) { + for (const style of getShapePropKeysByStyle(shape.props ?? {}).keys()) { + if (stylesById.has(style.id) && stylesById.get(style.id) !== style) { + throw new Error(`Multiple StyleProp instances with the same id: ${style.id}`); + } + stylesById.set(style.id, style); + } } + const ShapeRecordType = createShapeRecordType(shapes); + const BindingRecordType = createBindingRecordType(bindings); + const InstanceRecordType = createInstanceRecordType(stylesById); + return StoreSchema.create( + { + asset: AssetRecordType, + binding: BindingRecordType, + camera: CameraRecordType, + document: DocumentRecordType, + instance: InstanceRecordType, + instance_page_state: InstancePageStateRecordType, + page: PageRecordType, + instance_presence: InstancePresenceRecordType, + pointer: PointerRecordType, + shape: ShapeRecordType + }, + { + migrations: [ + storeMigrations, + assetMigrations, + cameraMigrations, + documentMigrations, + instanceMigrations, + instancePageStateMigrations, + pageMigrations, + instancePresenceMigrations, + pointerMigrations, + rootShapeMigrations, + bookmarkAssetMigrations, + imageAssetMigrations, + videoAssetMigrations, + ...processPropsMigrations("shape", shapes), + ...processPropsMigrations("binding", bindings), + ...migrations ?? [] + ], + onValidationFailure, + createIntegrityChecker + } + ); +} +const LANGUAGES = [ + { locale: "id", label: "Bahasa Indonesia" }, + { locale: "ca", label: "Català" }, + { locale: "cs", label: "Čeština" }, + { locale: "da", label: "Danish" }, + { locale: "de", label: "Deutsch" }, + { locale: "en", label: "English" }, + { locale: "es", label: "Español" }, + { locale: "fr", label: "Français" }, + { locale: "gl", label: "Galego" }, + { locale: "hr", label: "Hrvatski" }, + { locale: "it", label: "Italiano" }, + { locale: "hu", label: "Magyar" }, + { locale: "no", label: "Norwegian" }, + { locale: "pl", label: "Polski" }, + { locale: "pt-br", label: "Português - Brasil" }, + { locale: "pt-pt", label: "Português - Europeu" }, + { locale: "ro", label: "Română" }, + { locale: "ru", label: "Russian" }, + { locale: "sl", label: "Slovenščina" }, + { locale: "fi", label: "Suomi" }, + { locale: "sv", label: "Svenska" }, + { locale: "vi", label: "Tiếng Việt" }, + { locale: "tr", label: "Türkçe" }, + { locale: "uk", label: "Ukrainian" }, + { locale: "he", label: "עברית" }, + { locale: "ar", label: "عربي" }, + { locale: "fa", label: "فارسی" }, + { locale: "ku", label: "کوردی" }, + { locale: "ne", label: "नेपाली" }, + { locale: "hi-in", label: "हिन्दी" }, + { locale: "te", label: "తెలుగు" }, + { locale: "th", label: "ภาษาไทย" }, + { locale: "my", label: "မြန်မာစာ" }, + { locale: "ko-kr", label: "한국어" }, + { locale: "ja", label: "日本語" }, + { locale: "zh-cn", label: "简体中文" }, + { locale: "zh-tw", label: "繁體中文 (台灣)" } +]; +function getDefaultTranslationLocale() { + const locales = typeof window !== "undefined" ? window.navigator.languages ?? ["en"] : ["en"]; + return _getDefaultTranslationLocale(locales); +} +function _getDefaultTranslationLocale(locales) { + for (const locale of locales) { + const supportedLocale = getSupportedLocale(locale); + if (supportedLocale) { + return supportedLocale; + } + } + return "en"; +} +const DEFAULT_LOCALE_REGIONS = { + zh: "zh-cn", + pt: "pt-br", + ko: "ko-kr", + hi: "hi-in" }; -react_production_min.unstable_act = X$1; -react_production_min.useCallback = function(a2, b2) { - return U$1.current.useCallback(a2, b2); -}; -react_production_min.useContext = function(a2) { - return U$1.current.useContext(a2); -}; -react_production_min.useDebugValue = function() { -}; -react_production_min.useDeferredValue = function(a2) { - return U$1.current.useDeferredValue(a2); -}; -react_production_min.useEffect = function(a2, b2) { - return U$1.current.useEffect(a2, b2); -}; -react_production_min.useId = function() { - return U$1.current.useId(); -}; -react_production_min.useImperativeHandle = function(a2, b2, e2) { - return U$1.current.useImperativeHandle(a2, b2, e2); -}; -react_production_min.useInsertionEffect = function(a2, b2) { - return U$1.current.useInsertionEffect(a2, b2); -}; -react_production_min.useLayoutEffect = function(a2, b2) { - return U$1.current.useLayoutEffect(a2, b2); -}; -react_production_min.useMemo = function(a2, b2) { - return U$1.current.useMemo(a2, b2); -}; -react_production_min.useReducer = function(a2, b2, e2) { - return U$1.current.useReducer(a2, b2, e2); -}; -react_production_min.useRef = function(a2) { - return U$1.current.useRef(a2); -}; -react_production_min.useState = function(a2) { - return U$1.current.useState(a2); -}; -react_production_min.useSyncExternalStore = function(a2, b2, e2) { - return U$1.current.useSyncExternalStore(a2, b2, e2); -}; -react_production_min.useTransition = function() { - return U$1.current.useTransition(); -}; -react_production_min.version = "18.3.1"; -{ - react$1.exports = react_production_min; +function getSupportedLocale(locale) { + const exactMatch = LANGUAGES.find((t2) => t2.locale === locale.toLowerCase()); + if (exactMatch) { + return exactMatch.locale; + } + const [language, region] = locale.split(/[-_]/).map((s2) => s2.toLowerCase()); + if (region) { + const languageMatch = LANGUAGES.find((t2) => t2.locale === language); + if (languageMatch) { + return languageMatch.locale; + } + } + if (language in DEFAULT_LOCALE_REGIONS) { + return DEFAULT_LOCALE_REGIONS[language]; + } + return null; } -var reactExports = react$1.exports; -const React = /* @__PURE__ */ getDefaultExportFromCjs(reactExports); -const React$1 = /* @__PURE__ */ _mergeNamespaces({ - __proto__: null, - default: React -}, [reactExports]); +registerTldrawLibraryVersion( + "@tldraw/tlschema", + "3.4.1", + "esm" +); +var jsxRuntime = { exports: {} }; +var reactJsxRuntime_development = {}; /** * @license React - * react-jsx-runtime.production.min.js + * react-jsx-runtime.development.js * * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ -var f$1 = reactExports, k$1 = Symbol.for("react.element"), l$2 = Symbol.for("react.fragment"), m$2 = Object.prototype.hasOwnProperty, n$1 = f$1.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner, p$3 = { key: true, ref: true, __self: true, __source: true }; -function q$1(c2, a2, g2) { - var b2, d2 = {}, e2 = null, h2 = null; - void 0 !== g2 && (e2 = "" + g2); - void 0 !== a2.key && (e2 = "" + a2.key); - void 0 !== a2.ref && (h2 = a2.ref); - for (b2 in a2) m$2.call(a2, b2) && !p$3.hasOwnProperty(b2) && (d2[b2] = a2[b2]); - if (c2 && c2.defaultProps) for (b2 in a2 = c2.defaultProps, a2) void 0 === d2[b2] && (d2[b2] = a2[b2]); - return { $$typeof: k$1, type: c2, key: e2, ref: h2, props: d2, _owner: n$1.current }; -} -reactJsxRuntime_production_min.Fragment = l$2; -reactJsxRuntime_production_min.jsx = q$1; -reactJsxRuntime_production_min.jsxs = q$1; { - jsxRuntime.exports = reactJsxRuntime_production_min; + (function() { + var React2 = reactExports; + var REACT_ELEMENT_TYPE = Symbol.for("react.element"); + var REACT_PORTAL_TYPE = Symbol.for("react.portal"); + var REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"); + var REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"); + var REACT_PROFILER_TYPE = Symbol.for("react.profiler"); + var REACT_PROVIDER_TYPE = Symbol.for("react.provider"); + var REACT_CONTEXT_TYPE = Symbol.for("react.context"); + var REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"); + var REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"); + var REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"); + var REACT_MEMO_TYPE = Symbol.for("react.memo"); + var REACT_LAZY_TYPE = Symbol.for("react.lazy"); + var REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"); + var MAYBE_ITERATOR_SYMBOL = Symbol.iterator; + var FAUX_ITERATOR_SYMBOL = "@@iterator"; + function getIteratorFn(maybeIterable) { + if (maybeIterable === null || typeof maybeIterable !== "object") { + return null; + } + var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]; + if (typeof maybeIterator === "function") { + return maybeIterator; + } + return null; + } + var ReactSharedInternals = React2.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; + function error(format2) { + { + { + for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + args[_key2 - 1] = arguments[_key2]; + } + printWarning("error", format2, args); + } + } + } + function printWarning(level, format2, args) { + { + var ReactDebugCurrentFrame2 = ReactSharedInternals.ReactDebugCurrentFrame; + var stack2 = ReactDebugCurrentFrame2.getStackAddendum(); + if (stack2 !== "") { + format2 += "%s"; + args = args.concat([stack2]); + } + var argsWithFormat = args.map(function(item) { + return String(item); + }); + argsWithFormat.unshift("Warning: " + format2); + Function.prototype.apply.call(console[level], console, argsWithFormat); + } + } + var enableScopeAPI = false; + var enableCacheElement = false; + var enableTransitionTracing = false; + var enableLegacyHidden = false; + var enableDebugTracing = false; + var REACT_MODULE_REFERENCE; + { + REACT_MODULE_REFERENCE = Symbol.for("react.module.reference"); + } + function isValidElementType(type) { + if (typeof type === "string" || typeof type === "function") { + return true; + } + if (type === REACT_FRAGMENT_TYPE || type === REACT_PROFILER_TYPE || enableDebugTracing || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || enableLegacyHidden || type === REACT_OFFSCREEN_TYPE || enableScopeAPI || enableCacheElement || enableTransitionTracing) { + return true; + } + if (typeof type === "object" && type !== null) { + if (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || // This needs to include all possible module reference object + // types supported by any Flight configuration anywhere since + // we don't know which Flight build this will end up being used + // with. + type.$$typeof === REACT_MODULE_REFERENCE || type.getModuleId !== void 0) { + return true; + } + } + return false; + } + function getWrappedName(outerType, innerType, wrapperName) { + var displayName = outerType.displayName; + if (displayName) { + return displayName; + } + var functionName2 = innerType.displayName || innerType.name || ""; + return functionName2 !== "" ? wrapperName + "(" + functionName2 + ")" : wrapperName; + } + function getContextName(type) { + return type.displayName || "Context"; + } + function getComponentNameFromType(type) { + if (type == null) { + return null; + } + { + if (typeof type.tag === "number") { + error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."); + } + } + if (typeof type === "function") { + return type.displayName || type.name || null; + } + if (typeof type === "string") { + return type; + } + switch (type) { + case REACT_FRAGMENT_TYPE: + return "Fragment"; + case REACT_PORTAL_TYPE: + return "Portal"; + case REACT_PROFILER_TYPE: + return "Profiler"; + case REACT_STRICT_MODE_TYPE: + return "StrictMode"; + case REACT_SUSPENSE_TYPE: + return "Suspense"; + case REACT_SUSPENSE_LIST_TYPE: + return "SuspenseList"; + } + if (typeof type === "object") { + switch (type.$$typeof) { + case REACT_CONTEXT_TYPE: + var context = type; + return getContextName(context) + ".Consumer"; + case REACT_PROVIDER_TYPE: + var provider = type; + return getContextName(provider._context) + ".Provider"; + case REACT_FORWARD_REF_TYPE: + return getWrappedName(type, type.render, "ForwardRef"); + case REACT_MEMO_TYPE: + var outerName = type.displayName || null; + if (outerName !== null) { + return outerName; + } + return getComponentNameFromType(type.type) || "Memo"; + case REACT_LAZY_TYPE: { + var lazyComponent = type; + var payload = lazyComponent._payload; + var init = lazyComponent._init; + try { + return getComponentNameFromType(init(payload)); + } catch (x2) { + return null; + } + } + } + } + return null; + } + var assign = Object.assign; + var disabledDepth = 0; + var prevLog; + var prevInfo; + var prevWarn; + var prevError; + var prevGroup; + var prevGroupCollapsed; + var prevGroupEnd; + function disabledLog() { + } + disabledLog.__reactDisabledLog = true; + function disableLogs() { + { + if (disabledDepth === 0) { + prevLog = console.log; + prevInfo = console.info; + prevWarn = console.warn; + prevError = console.error; + prevGroup = console.group; + prevGroupCollapsed = console.groupCollapsed; + prevGroupEnd = console.groupEnd; + var props = { + configurable: true, + enumerable: true, + value: disabledLog, + writable: true + }; + Object.defineProperties(console, { + info: props, + log: props, + warn: props, + error: props, + group: props, + groupCollapsed: props, + groupEnd: props + }); + } + disabledDepth++; + } + } + function reenableLogs() { + { + disabledDepth--; + if (disabledDepth === 0) { + var props = { + configurable: true, + enumerable: true, + writable: true + }; + Object.defineProperties(console, { + log: assign({}, props, { + value: prevLog + }), + info: assign({}, props, { + value: prevInfo + }), + warn: assign({}, props, { + value: prevWarn + }), + error: assign({}, props, { + value: prevError + }), + group: assign({}, props, { + value: prevGroup + }), + groupCollapsed: assign({}, props, { + value: prevGroupCollapsed + }), + groupEnd: assign({}, props, { + value: prevGroupEnd + }) + }); + } + if (disabledDepth < 0) { + error("disabledDepth fell below zero. This is a bug in React. Please file an issue."); + } + } + } + var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; + var prefix; + function describeBuiltInComponentFrame(name, source, ownerFn) { + { + if (prefix === void 0) { + try { + throw Error(); + } catch (x2) { + var match2 = x2.stack.trim().match(/\n( *(at )?)/); + prefix = match2 && match2[1] || ""; + } + } + return "\n" + prefix + name; + } + } + var reentry = false; + var componentFrameCache; + { + var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; + componentFrameCache = new PossiblyWeakMap(); + } + function describeNativeComponentFrame(fn, construct2) { + if (!fn || reentry) { + return ""; + } + { + var frame2 = componentFrameCache.get(fn); + if (frame2 !== void 0) { + return frame2; + } + } + var control; + reentry = true; + var previousPrepareStackTrace = Error.prepareStackTrace; + Error.prepareStackTrace = void 0; + var previousDispatcher; + { + previousDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = null; + disableLogs(); + } + try { + if (construct2) { + var Fake = function() { + throw Error(); + }; + Object.defineProperty(Fake.prototype, "props", { + set: function() { + throw Error(); + } + }); + if (typeof Reflect === "object" && Reflect.construct) { + try { + Reflect.construct(Fake, []); + } catch (x2) { + control = x2; + } + Reflect.construct(fn, [], Fake); + } else { + try { + Fake.call(); + } catch (x2) { + control = x2; + } + fn.call(Fake.prototype); + } + } else { + try { + throw Error(); + } catch (x2) { + control = x2; + } + fn(); + } + } catch (sample) { + if (sample && control && typeof sample.stack === "string") { + var sampleLines = sample.stack.split("\n"); + var controlLines = control.stack.split("\n"); + var s2 = sampleLines.length - 1; + var c2 = controlLines.length - 1; + while (s2 >= 1 && c2 >= 0 && sampleLines[s2] !== controlLines[c2]) { + c2--; + } + for (; s2 >= 1 && c2 >= 0; s2--, c2--) { + if (sampleLines[s2] !== controlLines[c2]) { + if (s2 !== 1 || c2 !== 1) { + do { + s2--; + c2--; + if (c2 < 0 || sampleLines[s2] !== controlLines[c2]) { + var _frame = "\n" + sampleLines[s2].replace(" at new ", " at "); + if (fn.displayName && _frame.includes("")) { + _frame = _frame.replace("", fn.displayName); + } + { + if (typeof fn === "function") { + componentFrameCache.set(fn, _frame); + } + } + return _frame; + } + } while (s2 >= 1 && c2 >= 0); + } + break; + } + } + } + } finally { + reentry = false; + { + ReactCurrentDispatcher.current = previousDispatcher; + reenableLogs(); + } + Error.prepareStackTrace = previousPrepareStackTrace; + } + var name = fn ? fn.displayName || fn.name : ""; + var syntheticFrame = name ? describeBuiltInComponentFrame(name) : ""; + { + if (typeof fn === "function") { + componentFrameCache.set(fn, syntheticFrame); + } + } + return syntheticFrame; + } + function describeFunctionComponentFrame(fn, source, ownerFn) { + { + return describeNativeComponentFrame(fn, false); + } + } + function shouldConstruct(Component) { + var prototype = Component.prototype; + return !!(prototype && prototype.isReactComponent); + } + function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { + if (type == null) { + return ""; + } + if (typeof type === "function") { + { + return describeNativeComponentFrame(type, shouldConstruct(type)); + } + } + if (typeof type === "string") { + return describeBuiltInComponentFrame(type); + } + switch (type) { + case REACT_SUSPENSE_TYPE: + return describeBuiltInComponentFrame("Suspense"); + case REACT_SUSPENSE_LIST_TYPE: + return describeBuiltInComponentFrame("SuspenseList"); + } + if (typeof type === "object") { + switch (type.$$typeof) { + case REACT_FORWARD_REF_TYPE: + return describeFunctionComponentFrame(type.render); + case REACT_MEMO_TYPE: + return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); + case REACT_LAZY_TYPE: { + var lazyComponent = type; + var payload = lazyComponent._payload; + var init = lazyComponent._init; + try { + return describeUnknownElementTypeFrameInDEV(init(payload), source, ownerFn); + } catch (x2) { + } + } + } + } + return ""; + } + var hasOwnProperty2 = Object.prototype.hasOwnProperty; + var loggedTypeFailures = {}; + var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + function setCurrentlyValidatingElement(element) { + { + if (element) { + var owner = element._owner; + var stack2 = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null); + ReactDebugCurrentFrame.setExtraStackFrame(stack2); + } else { + ReactDebugCurrentFrame.setExtraStackFrame(null); + } + } + } + function checkPropTypes(typeSpecs, values, location, componentName, element) { + { + var has2 = Function.call.bind(hasOwnProperty2); + for (var typeSpecName in typeSpecs) { + if (has2(typeSpecs, typeSpecName)) { + var error$1 = void 0; + try { + if (typeof typeSpecs[typeSpecName] !== "function") { + var err = Error((componentName || "React class") + ": " + location + " type `" + typeSpecName + "` is invalid; it must be a function, usually from the `prop-types` package, but received `" + typeof typeSpecs[typeSpecName] + "`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`."); + err.name = "Invariant Violation"; + throw err; + } + error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"); + } catch (ex) { + error$1 = ex; + } + if (error$1 && !(error$1 instanceof Error)) { + setCurrentlyValidatingElement(element); + error("%s: type specification of %s `%s` is invalid; the type checker function must return `null` or an `Error` but returned a %s. You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument).", componentName || "React class", location, typeSpecName, typeof error$1); + setCurrentlyValidatingElement(null); + } + if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) { + loggedTypeFailures[error$1.message] = true; + setCurrentlyValidatingElement(element); + error("Failed %s type: %s", location, error$1.message); + setCurrentlyValidatingElement(null); + } + } + } + } + } + var isArrayImpl = Array.isArray; + function isArray3(a2) { + return isArrayImpl(a2); + } + function typeName(value) { + { + var hasToStringTag = typeof Symbol === "function" && Symbol.toStringTag; + var type = hasToStringTag && value[Symbol.toStringTag] || value.constructor.name || "Object"; + return type; + } + } + function willCoercionThrow(value) { + { + try { + testStringCoercion(value); + return false; + } catch (e2) { + return true; + } + } + } + function testStringCoercion(value) { + return "" + value; + } + function checkKeyStringCoercion(value) { + { + if (willCoercionThrow(value)) { + error("The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.", typeName(value)); + return testStringCoercion(value); + } + } + } + var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner; + var RESERVED_PROPS = { + key: true, + ref: true, + __self: true, + __source: true + }; + var specialPropKeyWarningShown; + var specialPropRefWarningShown; + var didWarnAboutStringRefs; + { + didWarnAboutStringRefs = {}; + } + function hasValidRef(config) { + { + if (hasOwnProperty2.call(config, "ref")) { + var getter = Object.getOwnPropertyDescriptor(config, "ref").get; + if (getter && getter.isReactWarning) { + return false; + } + } + } + return config.ref !== void 0; + } + function hasValidKey(config) { + { + if (hasOwnProperty2.call(config, "key")) { + var getter = Object.getOwnPropertyDescriptor(config, "key").get; + if (getter && getter.isReactWarning) { + return false; + } + } + } + return config.key !== void 0; + } + function warnIfStringRefCannotBeAutoConverted(config, self2) { + { + if (typeof config.ref === "string" && ReactCurrentOwner.current && self2 && ReactCurrentOwner.current.stateNode !== self2) { + var componentName = getComponentNameFromType(ReactCurrentOwner.current.type); + if (!didWarnAboutStringRefs[componentName]) { + error('Component "%s" contains the string ref "%s". Support for string refs will be removed in a future major release. This case cannot be automatically converted to an arrow function. We ask you to manually fix this case by using useRef() or createRef() instead. Learn more about using refs safely here: https://reactjs.org/link/strict-mode-string-ref', getComponentNameFromType(ReactCurrentOwner.current.type), config.ref); + didWarnAboutStringRefs[componentName] = true; + } + } + } + } + function defineKeyPropWarningGetter(props, displayName) { + { + var warnAboutAccessingKey = function() { + if (!specialPropKeyWarningShown) { + specialPropKeyWarningShown = true; + error("%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://reactjs.org/link/special-props)", displayName); + } + }; + warnAboutAccessingKey.isReactWarning = true; + Object.defineProperty(props, "key", { + get: warnAboutAccessingKey, + configurable: true + }); + } + } + function defineRefPropWarningGetter(props, displayName) { + { + var warnAboutAccessingRef = function() { + if (!specialPropRefWarningShown) { + specialPropRefWarningShown = true; + error("%s: `ref` 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://reactjs.org/link/special-props)", displayName); + } + }; + warnAboutAccessingRef.isReactWarning = true; + Object.defineProperty(props, "ref", { + get: warnAboutAccessingRef, + configurable: true + }); + } + } + var ReactElement = function(type, key, ref, self2, source, owner, props) { + var element = { + // This tag allows us to uniquely identify this as a React Element + $$typeof: REACT_ELEMENT_TYPE, + // Built-in properties that belong on the element + type, + key, + ref, + props, + // Record the component responsible for creating this element. + _owner: owner + }; + { + element._store = {}; + Object.defineProperty(element._store, "validated", { + configurable: false, + enumerable: false, + writable: true, + value: false + }); + Object.defineProperty(element, "_self", { + configurable: false, + enumerable: false, + writable: false, + value: self2 + }); + Object.defineProperty(element, "_source", { + configurable: false, + enumerable: false, + writable: false, + value: source + }); + if (Object.freeze) { + Object.freeze(element.props); + Object.freeze(element); + } + } + return element; + }; + function jsxDEV(type, config, maybeKey, source, self2) { + { + var propName; + var props = {}; + var key = null; + var ref = null; + if (maybeKey !== void 0) { + { + checkKeyStringCoercion(maybeKey); + } + key = "" + maybeKey; + } + if (hasValidKey(config)) { + { + checkKeyStringCoercion(config.key); + } + key = "" + config.key; + } + if (hasValidRef(config)) { + ref = config.ref; + warnIfStringRefCannotBeAutoConverted(config, self2); + } + for (propName in config) { + if (hasOwnProperty2.call(config, propName) && !RESERVED_PROPS.hasOwnProperty(propName)) { + props[propName] = config[propName]; + } + } + if (type && type.defaultProps) { + var defaultProps = type.defaultProps; + for (propName in defaultProps) { + if (props[propName] === void 0) { + props[propName] = defaultProps[propName]; + } + } + } + if (key || ref) { + var displayName = typeof type === "function" ? type.displayName || type.name || "Unknown" : type; + if (key) { + defineKeyPropWarningGetter(props, displayName); + } + if (ref) { + defineRefPropWarningGetter(props, displayName); + } + } + return ReactElement(type, key, ref, self2, source, ReactCurrentOwner.current, props); + } + } + var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner; + var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame; + function setCurrentlyValidatingElement$1(element) { + { + if (element) { + var owner = element._owner; + var stack2 = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null); + ReactDebugCurrentFrame$1.setExtraStackFrame(stack2); + } else { + ReactDebugCurrentFrame$1.setExtraStackFrame(null); + } + } + } + var propTypesMisspellWarningShown; + { + propTypesMisspellWarningShown = false; + } + function isValidElement(object2) { + { + return typeof object2 === "object" && object2 !== null && object2.$$typeof === REACT_ELEMENT_TYPE; + } + } + function getDeclarationErrorAddendum() { + { + if (ReactCurrentOwner$1.current) { + var name = getComponentNameFromType(ReactCurrentOwner$1.current.type); + if (name) { + return "\n\nCheck the render method of `" + name + "`."; + } + } + return ""; + } + } + function getSourceInfoErrorAddendum(source) { + { + return ""; + } + } + var ownerHasKeyUseWarning = {}; + function getCurrentComponentErrorInfo(parentType) { + { + var info = getDeclarationErrorAddendum(); + if (!info) { + var parentName = typeof parentType === "string" ? parentType : parentType.displayName || parentType.name; + if (parentName) { + info = "\n\nCheck the top-level render call using <" + parentName + ">."; + } + } + return info; + } + } + function validateExplicitKey(element, parentType) { + { + if (!element._store || element._store.validated || element.key != null) { + return; + } + element._store.validated = true; + var currentComponentErrorInfo = getCurrentComponentErrorInfo(parentType); + if (ownerHasKeyUseWarning[currentComponentErrorInfo]) { + return; + } + ownerHasKeyUseWarning[currentComponentErrorInfo] = true; + var childOwner = ""; + if (element && element._owner && element._owner !== ReactCurrentOwner$1.current) { + childOwner = " It was passed a child from " + getComponentNameFromType(element._owner.type) + "."; + } + setCurrentlyValidatingElement$1(element); + error('Each child in a list should have a unique "key" prop.%s%s See https://reactjs.org/link/warning-keys for more information.', currentComponentErrorInfo, childOwner); + setCurrentlyValidatingElement$1(null); + } + } + function validateChildKeys(node, parentType) { + { + if (typeof node !== "object") { + return; + } + if (isArray3(node)) { + for (var i2 = 0; i2 < node.length; i2++) { + var child = node[i2]; + if (isValidElement(child)) { + validateExplicitKey(child, parentType); + } + } + } else if (isValidElement(node)) { + if (node._store) { + node._store.validated = true; + } + } else if (node) { + var iteratorFn = getIteratorFn(node); + if (typeof iteratorFn === "function") { + if (iteratorFn !== node.entries) { + var iterator = iteratorFn.call(node); + var step; + while (!(step = iterator.next()).done) { + if (isValidElement(step.value)) { + validateExplicitKey(step.value, parentType); + } + } + } + } + } + } + } + function validatePropTypes(element) { + { + var type = element.type; + if (type === null || type === void 0 || typeof type === "string") { + return; + } + var propTypes; + if (typeof type === "function") { + propTypes = type.propTypes; + } else if (typeof type === "object" && (type.$$typeof === REACT_FORWARD_REF_TYPE || // Note: Memo only checks outer props here. + // Inner props are checked in the reconciler. + type.$$typeof === REACT_MEMO_TYPE)) { + propTypes = type.propTypes; + } else { + return; + } + if (propTypes) { + var name = getComponentNameFromType(type); + checkPropTypes(propTypes, element.props, "prop", name, element); + } else if (type.PropTypes !== void 0 && !propTypesMisspellWarningShown) { + propTypesMisspellWarningShown = true; + var _name = getComponentNameFromType(type); + error("Component %s declared `PropTypes` instead of `propTypes`. Did you misspell the property assignment?", _name || "Unknown"); + } + if (typeof type.getDefaultProps === "function" && !type.getDefaultProps.isReactClassApproved) { + error("getDefaultProps is only used on classic React.createClass definitions. Use a static property named `defaultProps` instead."); + } + } + } + function validateFragmentProps(fragment) { + { + var keys3 = Object.keys(fragment.props); + for (var i2 = 0; i2 < keys3.length; i2++) { + var key = keys3[i2]; + if (key !== "children" && key !== "key") { + setCurrentlyValidatingElement$1(fragment); + error("Invalid prop `%s` supplied to `React.Fragment`. React.Fragment can only have `key` and `children` props.", key); + setCurrentlyValidatingElement$1(null); + break; + } + } + if (fragment.ref !== null) { + setCurrentlyValidatingElement$1(fragment); + error("Invalid attribute `ref` supplied to `React.Fragment`."); + setCurrentlyValidatingElement$1(null); + } + } + } + var didWarnAboutKeySpread = {}; + function jsxWithValidation(type, props, key, isStaticChildren, source, self2) { + { + var validType = isValidElementType(type); + if (!validType) { + var info = ""; + if (type === void 0 || typeof type === "object" && type !== null && Object.keys(type).length === 0) { + info += " You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports."; + } + var sourceInfo = getSourceInfoErrorAddendum(); + if (sourceInfo) { + info += sourceInfo; + } else { + info += getDeclarationErrorAddendum(); + } + var typeString; + if (type === null) { + typeString = "null"; + } else if (isArray3(type)) { + typeString = "array"; + } else if (type !== void 0 && type.$$typeof === REACT_ELEMENT_TYPE) { + typeString = "<" + (getComponentNameFromType(type.type) || "Unknown") + " />"; + info = " Did you accidentally export a JSX literal instead of a component?"; + } else { + typeString = typeof type; + } + error("React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: %s.%s", typeString, info); + } + var element = jsxDEV(type, props, key, source, self2); + if (element == null) { + return element; + } + if (validType) { + var children = props.children; + if (children !== void 0) { + if (isStaticChildren) { + if (isArray3(children)) { + for (var i2 = 0; i2 < children.length; i2++) { + validateChildKeys(children[i2], type); + } + if (Object.freeze) { + Object.freeze(children); + } + } else { + error("React.jsx: Static children should always be an array. You are likely explicitly calling React.jsxs or React.jsxDEV. Use the Babel transform instead."); + } + } else { + validateChildKeys(children, type); + } + } + } + { + if (hasOwnProperty2.call(props, "key")) { + var componentName = getComponentNameFromType(type); + var keys3 = Object.keys(props).filter(function(k) { + return k !== "key"; + }); + var beforeExample = keys3.length > 0 ? "{key: someKey, " + keys3.join(": ..., ") + ": ...}" : "{key: someKey}"; + if (!didWarnAboutKeySpread[componentName + beforeExample]) { + var afterExample = keys3.length > 0 ? "{" + keys3.join(": ..., ") + ": ...}" : "{}"; + error('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} />', beforeExample, componentName, afterExample, componentName); + didWarnAboutKeySpread[componentName + beforeExample] = true; + } + } + } + if (type === REACT_FRAGMENT_TYPE) { + validateFragmentProps(element); + } else { + validatePropTypes(element); + } + return element; + } + } + function jsxWithValidationStatic(type, props, key) { + { + return jsxWithValidation(type, props, key, true); + } + } + function jsxWithValidationDynamic(type, props, key) { + { + return jsxWithValidation(type, props, key, false); + } + } + var jsx = jsxWithValidationDynamic; + var jsxs = jsxWithValidationStatic; + reactJsxRuntime_development.Fragment = REACT_FRAGMENT_TYPE; + reactJsxRuntime_development.jsx = jsx; + reactJsxRuntime_development.jsxs = jsxs; + })(); +} +{ + jsxRuntime.exports = reactJsxRuntime_development; } var jsxRuntimeExports = jsxRuntime.exports; -const TLDRAW_LIBRARY_VERSION_KEY = "__TLDRAW_LIBRARY_VERSIONS__"; -function getLibraryVersions() { - if (globalThis[TLDRAW_LIBRARY_VERSION_KEY]) { - return globalThis[TLDRAW_LIBRARY_VERSION_KEY]; +var classnames = { exports: {} }; +/*! + Copyright (c) 2018 Jed Watson. + Licensed under the MIT License (MIT), see + http://jedwatson.github.io/classnames +*/ +(function(module) { + (function() { + var hasOwn3 = {}.hasOwnProperty; + function classNames2() { + var classes = ""; + for (var i2 = 0; i2 < arguments.length; i2++) { + var arg = arguments[i2]; + if (arg) { + classes = appendClass(classes, parseValue(arg)); + } + } + return classes; + } + function parseValue(arg) { + if (typeof arg === "string" || typeof arg === "number") { + return arg; + } + if (typeof arg !== "object") { + return ""; + } + if (Array.isArray(arg)) { + return classNames2.apply(null, arg); + } + if (arg.toString !== Object.prototype.toString && !arg.toString.toString().includes("[native code]")) { + return arg.toString(); + } + var classes = ""; + for (var key in arg) { + if (hasOwn3.call(arg, key) && arg[key]) { + classes = appendClass(classes, key); + } + } + return classes; + } + function appendClass(value, newClass) { + if (!newClass) { + return value; + } + if (value) { + return value + " " + newClass; + } + return value + newClass; + } + if (module.exports) { + classNames2.default = classNames2; + module.exports = classNames2; + } else { + window.classNames = classNames2; + } + })(); +})(classnames); +var classnamesExports = classnames.exports; +const classNames = /* @__PURE__ */ getDefaultExportFromCjs(classnamesExports); +const version = "3.4.1"; +const publishDates = { + major: "2024-09-13T14:36:29.063Z", + minor: "2024-10-24T14:44:00.648Z", + patch: "2024-11-04T14:53:50.127Z" +}; +const initialState = { error: null }; +class ErrorBoundary extends reactExports.Component { + constructor() { + super(...arguments); + __publicField(this, "state", initialState); } - const info = { - versions: [], - didWarn: false, - scheduledNotice: null - }; - Object.defineProperty(globalThis, TLDRAW_LIBRARY_VERSION_KEY, { - value: info, - writable: false, - configurable: false, - enumerable: false - }); - return info; -} -function registerTldrawLibraryVersion(name, version2, modules) { - if (!name || !version2 || !modules) { - { - throw new Error("Missing name/version/module system in built version of tldraw library"); + static getDerivedStateFromError(error) { + return { error }; + } + componentDidCatch(error) { + var _a3, _b2; + (_b2 = (_a3 = this.props).onError) == null ? void 0 : _b2.call(_a3, error); + } + render() { + const { error } = this.state; + if (error !== null) { + const { fallback: Fallback } = this.props; + return /* @__PURE__ */ jsxRuntimeExports.jsx(Fallback, { error }); } + return this.props.children; } - const info = getLibraryVersions(); - info.versions.push({ name, version: version2, modules }); - if (!info.scheduledNotice) { - try { - info.scheduledNotice = setTimeout(() => { - info.scheduledNotice = null; - checkLibraryVersions(info); - }, 100); - } catch { - checkLibraryVersions(info); +} +function OptionalErrorBoundary({ + children, + fallback, + ...props +}) { + if (fallback === null) { + return children; + } + return /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorBoundary, { fallback, ...props, children }); +} +function suffixSafeId(id2, suffix) { + return sanitizeId(`${id2}_${suffix}`); +} +function useUniqueSafeId(suffix) { + return sanitizeId(`${reactExports.useId()}${suffix ?? ""}`); +} +function useSharedSafeId(id2) { + const idScope = assertExists(reactExports.useContext(IdContext)); + return sanitizeId(`${idScope}_${id2}`); +} +function sanitizeId(id2) { + return id2.replace(/:/g, "_"); +} +const IdContext = reactExports.createContext(null); +function IdProvider({ children }) { + const id2 = useUniqueSafeId(); + return /* @__PURE__ */ jsxRuntimeExports.jsx(IdContext.Provider, { value: id2, children }); +} +const EditorContext = reactExports.createContext(null); +function useEditor() { + const editor = React.useContext(EditorContext); + if (!editor) { + throw new Error( + "useEditor must be used inside of the or components" + ); + } + return editor; +} +function useMaybeEditor() { + return React.useContext(EditorContext); +} +function EditorProvider({ + editor, + children +}) { + return /* @__PURE__ */ jsxRuntimeExports.jsx(EditorContext.Provider, { value: editor, children: /* @__PURE__ */ jsxRuntimeExports.jsx(IdProvider, { children }) }); +} +function DefaultBackground() { + return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "tl-background" }); +} +function useTransform(ref, x2, y2, scale, rotate, additionalOffset) { + reactExports.useLayoutEffect(() => { + const elm = ref.current; + if (!elm) return; + if (x2 === void 0) return; + let trans = `translate(${x2}px, ${y2}px)`; + if (scale !== void 0) { + trans += ` scale(${scale})`; } - } -} -function checkLibraryVersions(info) { - if (!info.versions.length) return; - if (info.didWarn) return; - const sorted = info.versions.sort((a2, b2) => compareVersions(a2.version, b2.version)); - const latestVersion = sorted[sorted.length - 1].version; - const matchingVersions = /* @__PURE__ */ new Set(); - const nonMatchingVersions = /* @__PURE__ */ new Map(); - for (const lib of sorted) { - if (nonMatchingVersions.has(lib.name)) { - matchingVersions.delete(lib.name); - entry(nonMatchingVersions, lib.name, /* @__PURE__ */ new Set()).add(lib.version); - continue; + if (rotate !== void 0) { + trans += ` rotate(${rotate}rad)`; } - if (lib.version === latestVersion) { - matchingVersions.add(lib.name); - } else { - matchingVersions.delete(lib.name); - entry(nonMatchingVersions, lib.name, /* @__PURE__ */ new Set()).add(lib.version); + if (additionalOffset) { + trans += ` translate(${additionalOffset.x}px, ${additionalOffset.y}px)`; } + elm.style.transform = trans; + }); +} +const EASINGS = { + linear: (t2) => t2, + easeInQuad: (t2) => t2 * t2, + easeOutQuad: (t2) => t2 * (2 - t2), + easeInOutQuad: (t2) => t2 < 0.5 ? 2 * t2 * t2 : -1 + (4 - 2 * t2) * t2, + easeInCubic: (t2) => t2 * t2 * t2, + easeOutCubic: (t2) => --t2 * t2 * t2 + 1, + easeInOutCubic: (t2) => t2 < 0.5 ? 4 * t2 * t2 * t2 : (t2 - 1) * (2 * t2 - 2) * (2 * t2 - 2) + 1, + easeInQuart: (t2) => t2 * t2 * t2 * t2, + easeOutQuart: (t2) => 1 - --t2 * t2 * t2 * t2, + easeInOutQuart: (t2) => t2 < 0.5 ? 8 * t2 * t2 * t2 * t2 : 1 - 8 * --t2 * t2 * t2 * t2, + easeInQuint: (t2) => t2 * t2 * t2 * t2 * t2, + easeOutQuint: (t2) => 1 + --t2 * t2 * t2 * t2 * t2, + easeInOutQuint: (t2) => t2 < 0.5 ? 16 * t2 * t2 * t2 * t2 * t2 : 1 + 16 * --t2 * t2 * t2 * t2 * t2, + easeInSine: (t2) => 1 - Math.cos(t2 * Math.PI / 2), + easeOutSine: (t2) => Math.sin(t2 * Math.PI / 2), + easeInOutSine: (t2) => -(Math.cos(Math.PI * t2) - 1) / 2, + easeInExpo: (t2) => t2 <= 0 ? 0 : Math.pow(2, 10 * t2 - 10), + easeOutExpo: (t2) => t2 >= 1 ? 1 : 1 - Math.pow(2, -10 * t2), + easeInOutExpo: (t2) => t2 <= 0 ? 0 : t2 >= 1 ? 1 : t2 < 0.5 ? Math.pow(2, 20 * t2 - 10) / 2 : (2 - Math.pow(2, -20 * t2 + 10)) / 2 +}; +class Vec { + constructor(x2 = 0, y2 = 0, z = 1) { + this.x = x2; + this.y = y2; + this.z = z; } - if (nonMatchingVersions.size > 0) { - const message = [ - `${format("[tldraw]", ["bold", "bgRed", "textWhite"])} ${format("You have multiple versions of tldraw libraries installed. This can lead to bugs and unexpected behavior.", ["textRed", "bold"])}`, - "", - `The latest version you have installed is ${format(`v${latestVersion}`, ["bold", "textBlue"])}. The following libraries are on the latest version:`, - ...Array.from(matchingVersions, (name) => ` • ✅ ${format(name, ["bold"])}`), - "", - `The following libraries are not on the latest version, or have multiple versions installed:`, - ...Array.from(nonMatchingVersions, ([name, versions2]) => { - const sortedVersions = Array.from(versions2).sort(compareVersions).map((v2) => format(`v${v2}`, v2 === latestVersion ? ["textGreen"] : ["textRed"])); - return ` • ❌ ${format(name, ["bold"])} (${sortedVersions.join(", ")})`; - }) - ]; - console.log(message.join("\n")); - info.didWarn = true; - return; + // eslint-disable-next-line no-restricted-syntax + get pressure() { + return this.z; } - const potentialDuplicates = /* @__PURE__ */ new Map(); - for (const lib of sorted) { - entry(potentialDuplicates, lib.name, { version: lib.version, modules: [] }).modules.push( - lib.modules - ); + set(x2 = this.x, y2 = this.y, z = this.z) { + this.x = x2; + this.y = y2; + this.z = z; + return this; } - const duplicates = /* @__PURE__ */ new Map(); - for (const [name, lib] of potentialDuplicates) { - if (lib.modules.length > 1) duplicates.set(name, lib); + setTo({ x: x2 = 0, y: y2 = 0, z = 1 }) { + this.x = x2; + this.y = y2; + this.z = z; + return this; } - if (duplicates.size > 0) { - const message = [ - `${format("[tldraw]", ["bold", "bgRed", "textWhite"])} ${format("You have multiple instances of some tldraw libraries active. This can lead to bugs and unexpected behavior. ", ["textRed", "bold"])}`, - "", - "This usually means that your bundler is misconfigured, and is importing the same library multiple times - usually once as an ES Module, and once as a CommonJS module.", - "", - "The following libraries have been imported multiple times:", - ...Array.from(duplicates, ([name, lib]) => { - const modules = lib.modules.map((m2, i2) => m2 === "esm" ? ` ${i2 + 1}. ES Modules` : ` ${i2 + 1}. CommonJS`).join("\n"); - return ` • ❌ ${format(name, ["bold"])} v${lib.version}: -${modules}`; - }), - "", - "You should configure your bundler to only import one version of each library." - ]; - console.log(message.join("\n")); - info.didWarn = true; - return; + rot(r) { + if (r === 0) return this; + const { x: x2, y: y2 } = this; + const s2 = Math.sin(r); + const c2 = Math.cos(r); + this.x = x2 * c2 - y2 * s2; + this.y = x2 * s2 + y2 * c2; + return this; } -} -function compareVersions(a2, b2) { - const aMatch = a2.match(/^(\d+)\.(\d+)\.(\d+)(?:-(\w+))?$/); - const bMatch = b2.match(/^(\d+)\.(\d+)\.(\d+)(?:-(\w+))?$/); - if (!aMatch || !bMatch) return a2.localeCompare(b2); - if (aMatch[1] !== bMatch[1]) return Number(aMatch[1]) - Number(bMatch[1]); - if (aMatch[2] !== bMatch[2]) return Number(aMatch[2]) - Number(bMatch[2]); - if (aMatch[3] !== bMatch[3]) return Number(aMatch[3]) - Number(bMatch[3]); - if (aMatch[4] && bMatch[4]) return aMatch[4].localeCompare(bMatch[4]); - if (aMatch[4]) return 1; - if (bMatch[4]) return -1; - return 0; -} -const formats = { - bold: "1", - textBlue: "94", - textRed: "31", - textGreen: "32", - bgRed: "41", - textWhite: "97" -}; -function format(value, formatters = []) { - return `\x1B[${formatters.map((f2) => formats[f2]).join(";")}m${value}\x1B[m`; -} -function entry(map, key, defaultValue) { - if (map.has(key)) { - return map.get(key); + rotWith(C2, r) { + if (r === 0) return this; + const x2 = this.x - C2.x; + const y2 = this.y - C2.y; + const s2 = Math.sin(r); + const c2 = Math.cos(r); + this.x = C2.x + (x2 * c2 - y2 * s2); + this.y = C2.y + (x2 * s2 + y2 * c2); + return this; } - map.set(key, defaultValue); - return defaultValue; -} -var FUNC_ERROR_TEXT = "Expected a function"; -var NAN = 0 / 0; -var symbolTag = "[object Symbol]"; -var reTrim = /^\s+|\s+$/g; -var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; -var reIsBinary = /^0b[01]+$/i; -var reIsOctal = /^0o[0-7]+$/i; -var freeParseInt = parseInt; -var freeGlobal$1 = typeof commonjsGlobal == "object" && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; -var freeSelf$1 = typeof self == "object" && self && self.Object === Object && self; -var root$1 = freeGlobal$1 || freeSelf$1 || Function("return this")(); -var objectProto$1 = Object.prototype; -var objectToString$1 = objectProto$1.toString; -var nativeMax = Math.max, nativeMin = Math.min; -var now = function() { - return root$1.Date.now(); -}; -function debounce$1(func, wait, options) { - var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true; - if (typeof func != "function") { - throw new TypeError(FUNC_ERROR_TEXT); + clone() { + const { x: x2, y: y2, z } = this; + return new Vec(x2, y2, z); } - wait = toNumber(wait) || 0; - if (isObject$9(options)) { - leading = !!options.leading; - maxing = "maxWait" in options; - maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; - trailing = "trailing" in options ? !!options.trailing : trailing; + sub(V2) { + this.x -= V2.x; + this.y -= V2.y; + return this; } - function invokeFunc(time2) { - var args = lastArgs, thisArg = lastThis; - lastArgs = lastThis = void 0; - lastInvokeTime = time2; - result = func.apply(thisArg, args); - return result; + subXY(x2, y2) { + this.x -= x2; + this.y -= y2; + return this; } - function leadingEdge(time2) { - lastInvokeTime = time2; - timerId = setTimeout(timerExpired, wait); - return leading ? invokeFunc(time2) : result; + subScalar(n) { + this.x -= n; + this.y -= n; + return this; } - function remainingWait(time2) { - var timeSinceLastCall = time2 - lastCallTime, timeSinceLastInvoke = time2 - lastInvokeTime, result2 = wait - timeSinceLastCall; - return maxing ? nativeMin(result2, maxWait - timeSinceLastInvoke) : result2; + add(V2) { + this.x += V2.x; + this.y += V2.y; + return this; } - function shouldInvoke(time2) { - var timeSinceLastCall = time2 - lastCallTime, timeSinceLastInvoke = time2 - lastInvokeTime; - return lastCallTime === void 0 || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait; + addXY(x2, y2) { + this.x += x2; + this.y += y2; + return this; } - function timerExpired() { - var time2 = now(); - if (shouldInvoke(time2)) { - return trailingEdge(time2); - } - timerId = setTimeout(timerExpired, remainingWait(time2)); + addScalar(n) { + this.x += n; + this.y += n; + return this; } - function trailingEdge(time2) { - timerId = void 0; - if (trailing && lastArgs) { - return invokeFunc(time2); + clamp(min2, max2) { + this.x = Math.max(this.x, min2); + this.y = Math.max(this.y, min2); + if (max2 !== void 0) { + this.x = Math.min(this.x, max2); + this.y = Math.min(this.y, max2); } - lastArgs = lastThis = void 0; - return result; + return this; } - function cancel() { - if (timerId !== void 0) { - clearTimeout(timerId); - } - lastInvokeTime = 0; - lastArgs = lastCallTime = lastThis = timerId = void 0; + div(t2) { + this.x /= t2; + this.y /= t2; + return this; } - function flush2() { - return timerId === void 0 ? result : trailingEdge(now()); + divV(V2) { + this.x /= V2.x; + this.y /= V2.y; + return this; } - function debounced() { - var time2 = now(), isInvoking = shouldInvoke(time2); - lastArgs = arguments; - lastThis = this; - lastCallTime = time2; - if (isInvoking) { - if (timerId === void 0) { - return leadingEdge(lastCallTime); - } - if (maxing) { - timerId = setTimeout(timerExpired, wait); - return invokeFunc(lastCallTime); - } - } - if (timerId === void 0) { - timerId = setTimeout(timerExpired, wait); - } - return result; + mul(t2) { + this.x *= t2; + this.y *= t2; + return this; } - debounced.cancel = cancel; - debounced.flush = flush2; - return debounced; -} -function throttle(func, wait, options) { - var leading = true, trailing = true; - if (typeof func != "function") { - throw new TypeError(FUNC_ERROR_TEXT); + mulV(V2) { + this.x *= V2.x; + this.y *= V2.y; + return this; } - if (isObject$9(options)) { - leading = "leading" in options ? !!options.leading : leading; - trailing = "trailing" in options ? !!options.trailing : trailing; + abs() { + this.x = Math.abs(this.x); + this.y = Math.abs(this.y); + return this; } - return debounce$1(func, wait, { - "leading": leading, - "maxWait": wait, - "trailing": trailing - }); -} -function isObject$9(value) { - var type = typeof value; - return !!value && (type == "object" || type == "function"); -} -function isObjectLike(value) { - return !!value && typeof value == "object"; -} -function isSymbol$3(value) { - return typeof value == "symbol" || isObjectLike(value) && objectToString$1.call(value) == symbolTag; -} -function toNumber(value) { - if (typeof value == "number") { - return value; + nudge(B2, distance) { + const tan = Vec.Tan(B2, this); + return this.add(tan.mul(distance)); } - if (isSymbol$3(value)) { - return NAN; + neg() { + this.x *= -1; + this.y *= -1; + return this; } - if (isObject$9(value)) { - var other = typeof value.valueOf == "function" ? value.valueOf() : value; - value = isObject$9(other) ? other + "" : other; + cross(V2) { + this.x = this.y * V2.z - this.z * V2.y; + this.y = this.z * V2.x - this.x * V2.z; + return this; } - if (typeof value != "string") { - return value === 0 ? value : +value; + dpr(V2) { + return Vec.Dpr(this, V2); } - value = value.replace(reTrim, ""); - var isBinary = reIsBinary.test(value); - return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value; -} -var lodash_throttle = throttle; -const throttle$1 = /* @__PURE__ */ getDefaultExportFromCjs(lodash_throttle); -var LARGE_ARRAY_SIZE = 200; -var HASH_UNDEFINED = "__lodash_hash_undefined__"; -var INFINITY = 1 / 0; -var funcTag = "[object Function]", genTag = "[object GeneratorFunction]"; -var reRegExpChar = /[\\^$.*+?()[\]{}|]/g; -var reIsHostCtor = /^\[object .+?Constructor\]$/; -var freeGlobal = typeof commonjsGlobal == "object" && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; -var freeSelf = typeof self == "object" && self && self.Object === Object && self; -var root = freeGlobal || freeSelf || Function("return this")(); -function arrayIncludes$1(array2, value) { - var length = array2 ? array2.length : 0; - return !!length && baseIndexOf(array2, value, 0) > -1; -} -function baseFindIndex(array2, predicate, fromIndex, fromRight) { - var length = array2.length, index2 = fromIndex + -1; - while (++index2 < length) { - if (predicate(array2[index2], index2, array2)) { - return index2; - } + cpr(V2) { + return Vec.Cpr(this, V2); } - return -1; -} -function baseIndexOf(array2, value, fromIndex) { - if (value !== value) { - return baseFindIndex(array2, baseIsNaN, fromIndex); + len2() { + return Vec.Len2(this); } - var index2 = fromIndex - 1, length = array2.length; - while (++index2 < length) { - if (array2[index2] === value) { - return index2; - } + len() { + return Vec.Len(this); } - return -1; -} -function baseIsNaN(value) { - return value !== value; -} -function cacheHas(cache, key) { - return cache.has(key); -} -function getValue(object2, key) { - return object2 == null ? void 0 : object2[key]; -} -function isHostObject(value) { - var result = false; - if (value != null && typeof value.toString != "function") { - try { - result = !!(value + ""); - } catch (e2) { - } + pry(V2) { + return Vec.Pry(this, V2); } - return result; -} -function setToArray(set2) { - var index2 = -1, result = Array(set2.size); - set2.forEach(function(value) { - result[++index2] = value; - }); - return result; -} -var arrayProto = Array.prototype, funcProto = Function.prototype, objectProto = Object.prototype; -var coreJsData = root["__core-js_shared__"]; -var maskSrcKey = function() { - var uid2 = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || ""); - return uid2 ? "Symbol(src)_1." + uid2 : ""; -}(); -var funcToString = funcProto.toString; -var hasOwnProperty$2 = objectProto.hasOwnProperty; -var objectToString = objectProto.toString; -var reIsNative = RegExp( - "^" + funcToString.call(hasOwnProperty$2).replace(reRegExpChar, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$" -); -var splice = arrayProto.splice; -var Map$1 = getNative(root, "Map"), Set$1 = getNative(root, "Set"), nativeCreate = getNative(Object, "create"); -function Hash(entries) { - var index2 = -1, length = entries ? entries.length : 0; - this.clear(); - while (++index2 < length) { - var entry2 = entries[index2]; - this.set(entry2[0], entry2[1]); + per() { + const { x: x2, y: y2 } = this; + this.x = y2; + this.y = -x2; + return this; } -} -function hashClear() { - this.__data__ = nativeCreate ? nativeCreate(null) : {}; -} -function hashDelete(key) { - return this.has(key) && delete this.__data__[key]; -} -function hashGet(key) { - var data2 = this.__data__; - if (nativeCreate) { - var result = data2[key]; - return result === HASH_UNDEFINED ? void 0 : result; + uni() { + return Vec.Uni(this); } - return hasOwnProperty$2.call(data2, key) ? data2[key] : void 0; -} -function hashHas(key) { - var data2 = this.__data__; - return nativeCreate ? data2[key] !== void 0 : hasOwnProperty$2.call(data2, key); -} -function hashSet(key, value) { - var data2 = this.__data__; - data2[key] = nativeCreate && value === void 0 ? HASH_UNDEFINED : value; - return this; -} -Hash.prototype.clear = hashClear; -Hash.prototype["delete"] = hashDelete; -Hash.prototype.get = hashGet; -Hash.prototype.has = hashHas; -Hash.prototype.set = hashSet; -function ListCache(entries) { - var index2 = -1, length = entries ? entries.length : 0; - this.clear(); - while (++index2 < length) { - var entry2 = entries[index2]; - this.set(entry2[0], entry2[1]); + tan(V2) { + return Vec.Tan(this, V2); } -} -function listCacheClear() { - this.__data__ = []; -} -function listCacheDelete(key) { - var data2 = this.__data__, index2 = assocIndexOf(data2, key); - if (index2 < 0) { - return false; + dist(V2) { + return Vec.Dist(this, V2); } - var lastIndex = data2.length - 1; - if (index2 == lastIndex) { - data2.pop(); - } else { - splice.call(data2, index2, 1); + distanceToLineSegment(A, B2) { + return Vec.DistanceToLineSegment(A, B2, this); } - return true; -} -function listCacheGet(key) { - var data2 = this.__data__, index2 = assocIndexOf(data2, key); - return index2 < 0 ? void 0 : data2[index2][1]; -} -function listCacheHas(key) { - return assocIndexOf(this.__data__, key) > -1; -} -function listCacheSet(key, value) { - var data2 = this.__data__, index2 = assocIndexOf(data2, key); - if (index2 < 0) { - data2.push([key, value]); - } else { - data2[index2][1] = value; + slope(B2) { + return Vec.Slope(this, B2); + } + snapToGrid(gridSize) { + this.x = Math.round(this.x / gridSize) * gridSize; + this.y = Math.round(this.y / gridSize) * gridSize; + return this; + } + angle(B2) { + return Vec.Angle(this, B2); + } + toAngle() { + return Vec.ToAngle(this); + } + lrp(B2, t2) { + this.x = this.x + (B2.x - this.x) * t2; + this.y = this.y + (B2.y - this.y) * t2; + return this; + } + equals(B2) { + return Vec.Equals(this, B2); + } + equalsXY(x2, y2) { + return Vec.EqualsXY(this, x2, y2); + } + norm() { + const l2 = this.len(); + this.x = l2 === 0 ? 0 : this.x / l2; + this.y = l2 === 0 ? 0 : this.y / l2; + return this; } - return this; -} -ListCache.prototype.clear = listCacheClear; -ListCache.prototype["delete"] = listCacheDelete; -ListCache.prototype.get = listCacheGet; -ListCache.prototype.has = listCacheHas; -ListCache.prototype.set = listCacheSet; -function MapCache(entries) { - var index2 = -1, length = entries ? entries.length : 0; - this.clear(); - while (++index2 < length) { - var entry2 = entries[index2]; - this.set(entry2[0], entry2[1]); + toFixed() { + return Vec.ToFixed(this); } -} -function mapCacheClear() { - this.__data__ = { - "hash": new Hash(), - "map": new (Map$1 || ListCache)(), - "string": new Hash() - }; -} -function mapCacheDelete(key) { - return getMapData(this, key)["delete"](key); -} -function mapCacheGet(key) { - return getMapData(this, key).get(key); -} -function mapCacheHas(key) { - return getMapData(this, key).has(key); -} -function mapCacheSet(key, value) { - getMapData(this, key).set(key, value); - return this; -} -MapCache.prototype.clear = mapCacheClear; -MapCache.prototype["delete"] = mapCacheDelete; -MapCache.prototype.get = mapCacheGet; -MapCache.prototype.has = mapCacheHas; -MapCache.prototype.set = mapCacheSet; -function SetCache(values) { - var index2 = -1, length = values ? values.length : 0; - this.__data__ = new MapCache(); - while (++index2 < length) { - this.add(values[index2]); + toString() { + return Vec.ToString(Vec.ToFixed(this)); } -} -function setCacheAdd(value) { - this.__data__.set(value, HASH_UNDEFINED); - return this; -} -function setCacheHas(value) { - return this.__data__.has(value); -} -SetCache.prototype.add = SetCache.prototype.push = setCacheAdd; -SetCache.prototype.has = setCacheHas; -function assocIndexOf(array2, key) { - var length = array2.length; - while (length--) { - if (eq(array2[length][0], key)) { - return length; - } + toJson() { + return Vec.ToJson(this); } - return -1; -} -function baseIsNative(value) { - if (!isObject$8(value) || isMasked(value)) { - return false; + toArray() { + return Vec.ToArray(this); } - var pattern = isFunction(value) || isHostObject(value) ? reIsNative : reIsHostCtor; - return pattern.test(toSource(value)); -} -function baseUniq(array2, iteratee, comparator) { - var index2 = -1, includes = arrayIncludes$1, length = array2.length, isCommon = true, result = [], seen = result; - if (length >= LARGE_ARRAY_SIZE) { - var set2 = createSet(array2); - if (set2) { - return setToArray(set2); - } - isCommon = false; - includes = cacheHas; - seen = new SetCache(); - } else { - seen = result; + static Add(A, B2) { + return new Vec(A.x + B2.x, A.y + B2.y); } - outer: - while (++index2 < length) { - var value = array2[index2], computed2 = value; - value = value !== 0 ? value : 0; - if (isCommon && computed2 === computed2) { - var seenIndex = seen.length; - while (seenIndex--) { - if (seen[seenIndex] === computed2) { - continue outer; - } - } - result.push(value); - } else if (!includes(seen, computed2, comparator)) { - if (seen !== result) { - seen.push(computed2); - } - result.push(value); - } - } - return result; -} -var createSet = !(Set$1 && 1 / setToArray(new Set$1([, -0]))[1] == INFINITY) ? noop$3 : function(values) { - return new Set$1(values); -}; -function getMapData(map, key) { - var data2 = map.__data__; - return isKeyable(key) ? data2[typeof key == "string" ? "string" : "hash"] : data2.map; -} -function getNative(object2, key) { - var value = getValue(object2, key); - return baseIsNative(value) ? value : void 0; -} -function isKeyable(value) { - var type = typeof value; - return type == "string" || type == "number" || type == "symbol" || type == "boolean" ? value !== "__proto__" : value === null; -} -function isMasked(func) { - return !!maskSrcKey && maskSrcKey in func; -} -function toSource(func) { - if (func != null) { - try { - return funcToString.call(func); - } catch (e2) { - } - try { - return func + ""; - } catch (e2) { - } + static AddXY(A, x2, y2) { + return new Vec(A.x + x2, A.y + y2); } - return ""; -} -function uniq$1(array2) { - return array2 && array2.length ? baseUniq(array2) : []; -} -function eq(value, other) { - return value === other || value !== value && other !== other; -} -function isFunction(value) { - var tag = isObject$8(value) ? objectToString.call(value) : ""; - return tag == funcTag || tag == genTag; -} -function isObject$8(value) { - var type = typeof value; - return !!value && (type == "object" || type == "function"); -} -function noop$3() { -} -var lodash_uniq = uniq$1; -const _uniq = /* @__PURE__ */ getDefaultExportFromCjs(lodash_uniq); -const PERFORMANCE_COLORS = { - Good: "#40C057", - Mid: "#FFC078", - Poor: "#E03131" -}; -const PERFORMANCE_PREFIX_COLOR = PERFORMANCE_COLORS.Good; -class PerformanceTracker { - constructor() { - __publicField(this, "startTime", 0); - __publicField(this, "name", ""); - __publicField(this, "frames", 0); - __publicField(this, "started", false); - __publicField(this, "frame", null); - // eslint-disable-next-line local/prefer-class-methods - __publicField(this, "recordFrame", () => { - this.frames++; - if (!this.started) return; - this.frame = requestAnimationFrame(this.recordFrame); - }); + static Sub(A, B2) { + return new Vec(A.x - B2.x, A.y - B2.y); } - start(name) { - this.name = name; - this.frames = 0; - this.started = true; - if (this.frame !== null) cancelAnimationFrame(this.frame); - this.frame = requestAnimationFrame(this.recordFrame); - this.startTime = performance.now(); + static SubXY(A, x2, y2) { + return new Vec(A.x - x2, A.y - y2); } - stop() { - this.started = false; - if (this.frame !== null) cancelAnimationFrame(this.frame); - const duration = (performance.now() - this.startTime) / 1e3; - const fps = duration === 0 ? 0 : Math.floor(this.frames / duration); - const background = fps > 55 ? PERFORMANCE_COLORS.Good : fps > 30 ? PERFORMANCE_COLORS.Mid : PERFORMANCE_COLORS.Poor; - const color = background === PERFORMANCE_COLORS.Mid ? "black" : "white"; - const capitalized = this.name[0].toUpperCase() + this.name.slice(1); - console.debug( - `%cPerf%c ${capitalized} %c${fps}%c fps`, - `color: white; background: ${PERFORMANCE_PREFIX_COLOR};padding: 2px;border-radius: 3px;`, - "font-weight: normal", - `font-weight: bold; padding: 2px; background: ${background};color: ${color};`, - "font-weight: normal" - ); + static AddScalar(A, n) { + return new Vec(A.x + n, A.y + n); } - isStarted() { - return this.started; + static SubScalar(A, n) { + return new Vec(A.x - n, A.y - n); } -} -function dedupe(input, equals2) { - const result = []; - mainLoop: for (const item of input) { - for (const existing of result) { - if (equals2 ? equals2(item, existing) : item === existing) { - continue mainLoop; - } - } - result.push(item); + static Div(A, t2) { + return new Vec(A.x / t2, A.y / t2); } - return result; -} -function compact(arr) { - return arr.filter((i2) => i2 !== void 0 && i2 !== null); -} -function last$1(arr) { - return arr[arr.length - 1]; -} -function minBy(arr, fn) { - let min2; - let minVal = Infinity; - for (const item of arr) { - const val = fn(item); - if (val < minVal) { - min2 = item; - minVal = val; - } + static Mul(A, t2) { + return new Vec(A.x * t2, A.y * t2); } - return min2; -} -function areArraysShallowEqual(arr1, arr2) { - if (arr1 === arr2) return true; - if (arr1.length !== arr2.length) return false; - for (let i2 = 0; i2 < arr1.length; i2++) { - if (!Object.is(arr1[i2], arr2[i2])) { - return false; - } + static DivV(A, B2) { + return new Vec(A.x / B2.x, A.y / B2.y); } - return true; -} -function omitFromStackTrace(fn) { - const wrappedFn = (...args) => { - try { - return fn(...args); - } catch (error) { - if (error instanceof Error && Error.captureStackTrace) { - Error.captureStackTrace(error, wrappedFn); - } - throw error; - } - }; - return wrappedFn; -} -const noop$2 = () => { -}; -const Result = { - ok(value) { - return { ok: true, value }; - }, - err(error) { - return { ok: false, error }; + static MulV(A, B2) { + return new Vec(A.x * B2.x, A.y * B2.y); } -}; -function exhaustiveSwitchError(value, property) { - const debugValue = property && value && typeof value === "object" && property in value ? value[property] : value; - throw new Error(`Unknown switch case ${debugValue}`); -} -const assert = omitFromStackTrace( - (value, message) => { - if (!value) { - throw new Error(message || "Assertion Error"); - } + static Neg(A) { + return new Vec(-A.x, -A.y); } -); -const assertExists = omitFromStackTrace((value, message) => { - if (value == null) { - throw new Error(message ?? "value must be defined"); + /** + * Get the perpendicular vector to A. + */ + static Per(A) { + return new Vec(A.y, -A.x); } - return value; -}); -function promiseWithResolve() { - let resolve; - let reject; - const promise = new Promise((res, rej) => { - resolve = res; - reject = rej; - }); - return Object.assign(promise, { - resolve, - reject - }); -} -function sleep(ms) { - return new Promise((resolve) => setTimeout(resolve, ms)); -} -function bind$2(...args) { - if (args.length === 2) { - const [originalMethod, context] = args; - context.addInitializer(function initializeMethod() { - assert(Reflect.isExtensible(this), "Cannot bind to a non-extensible class."); - const value = originalMethod.bind(this); - const ok2 = Reflect.defineProperty(this, context.name, { - value, - writable: true, - configurable: true - }); - assert(ok2, "Cannot bind a non-configurable class method."); - }); - } else { - const [_target, propertyKey, descriptor] = args; - if (!descriptor || typeof descriptor.value !== "function") { - throw new TypeError( - `Only methods can be decorated with @bind. <${propertyKey}> is not a method!` - ); - } - return { - configurable: true, - get() { - const bound = descriptor.value.bind(this); - Object.defineProperty(this, propertyKey, { - value: bound, - configurable: true, - writable: true - }); - return bound; - } - }; + static Abs(A) { + return new Vec(Math.abs(A.x), Math.abs(A.y)); } -} -class WeakCache { - constructor() { - /** The map of items to their cached values. */ - __publicField(this, "items", /* @__PURE__ */ new WeakMap()); + // Get the distance between two points. + static Dist(A, B2) { + return ((A.y - B2.y) ** 2 + (A.x - B2.x) ** 2) ** 0.5; + } + // Get whether a distance between two points is less than a number. This is faster to calulate than using `Vec.Dist(a, b) < n`. + static DistMin(A, B2, n) { + return (A.x - B2.x) * (A.x - B2.x) + (A.y - B2.y) * (A.y - B2.y) < n ** 2; + } + // Get the squared distance between two points. This is faster to calculate (no square root) so useful for "minimum distance" checks where the actual measurement does not matter. + static Dist2(A, B2) { + return (A.x - B2.x) * (A.x - B2.x) + (A.y - B2.y) * (A.y - B2.y); } /** - * Get the cached value for a given record. If the record is not present in the map, the callback - * will be used to create the value (with the result being stored in the cache for next time). - * - * @param item - The item to get. - * @param cb - The callback to use to create the value when a cached value is not found. + * Dot product of two vectors which is used to calculate the angle between them. */ - get(item, cb2) { - if (!this.items.has(item)) { - this.items.set(item, cb2(item)); - } - return this.items.get(item); + static Dpr(A, B2) { + return A.x * B2.x + A.y * B2.y; } -} -function debounce(callback, wait) { - let state = void 0; - const fn = (...args) => { - if (!state) { - state = {}; - state.promise = new Promise((resolve, reject) => { - state.resolve = resolve; - state.reject = reject; - }); - } - clearTimeout(state.timeout); - state.latestArgs = args; - state.timeout = setTimeout(() => { - const s2 = state; - state = void 0; - try { - s2.resolve(callback(...s2.latestArgs)); - } catch (e2) { - s2.reject(e2); - } - }, wait); - return state.promise; - }; - fn.cancel = () => { - if (!state) return; - clearTimeout(state.timeout); - }; - return fn; -} -const annotationsByError = /* @__PURE__ */ new WeakMap(); -function annotateError(error, annotations) { - if (typeof error !== "object" || error === null) return; - let currentAnnotations = annotationsByError.get(error); - if (!currentAnnotations) { - currentAnnotations = { tags: {}, extras: {} }; - annotationsByError.set(error, currentAnnotations); + static Cross(A, V2) { + return new Vec( + A.y * V2.z - A.z * V2.y, + A.z * V2.x - A.x * V2.z + // A.z = A.x * V.y - A.y * V.x + ); } - if (annotations.tags) { - currentAnnotations.tags = { - ...currentAnnotations.tags, - ...annotations.tags - }; + /** + * Cross product of two vectors which is used to calculate the area of a parallelogram. + */ + static Cpr(A, B2) { + return A.x * B2.y - B2.x * A.y; } - if (annotations.extras) { - currentAnnotations.extras = { - ...currentAnnotations.extras, - ...annotations.extras - }; + static Len2(A) { + return A.x * A.x + A.y * A.y; + } + static Len(A) { + return (A.x * A.x + A.y * A.y) ** 0.5; } -} -async function fetch(input, init) { - return window.fetch(input, { - // We want to make sure that the referrer is not sent to other domains. - referrerPolicy: "strict-origin-when-cross-origin", - ...init - }); -} -const Image = (width, height) => { - const img = new window.Image(width, height); - img.referrerPolicy = "strict-origin-when-cross-origin"; - return img; -}; -class FileHelpers { /** - * @param dataURL - The file as a string. - * - * from https://stackoverflow.com/a/53817185 + * Get the projection of A onto B. */ - static async dataUrlToArrayBuffer(dataURL) { - return fetch(dataURL).then(function(result) { - return result.arrayBuffer(); - }); + static Pry(A, B2) { + return Vec.Dpr(A, B2) / Vec.Len(B2); } /** - * Convert a file to a base64 encoded data url. - * - * @example - * - * ```ts - * const A = FileHelpers.toDataUrl(myImageFile) - * ``` - * - * @param file - The file as a blob. + * Get the unit vector of A. */ - static async blobToDataUrl(file) { - return await new Promise((resolve, reject) => { - if (file) { - const reader = new FileReader(); - reader.onload = () => resolve(reader.result); - reader.onerror = (error) => reject(error); - reader.onabort = (error) => reject(error); - reader.readAsDataURL(file); - } - }); + static Uni(A) { + return Vec.Div(A, Vec.Len(A)); + } + static Tan(A, B2) { + return Vec.Uni(Vec.Sub(A, B2)); + } + static Min(A, B2) { + return new Vec(Math.min(A.x, B2.x), Math.min(A.y, B2.y)); + } + static Max(A, B2) { + return new Vec(Math.max(A.x, B2.x), Math.max(A.y, B2.y)); + } + static From({ x: x2, y: y2, z = 1 }) { + return new Vec(x2, y2, z); + } + static FromArray(v2) { + return new Vec(v2[0], v2[1]); + } + static Rot(A, r = 0) { + const s2 = Math.sin(r); + const c2 = Math.cos(r); + return new Vec(A.x * c2 - A.y * s2, A.x * s2 + A.y * c2); + } + static RotWith(A, C2, r) { + const x2 = A.x - C2.x; + const y2 = A.y - C2.y; + const s2 = Math.sin(r); + const c2 = Math.cos(r); + return new Vec(C2.x + (x2 * c2 - y2 * s2), C2.y + (x2 * s2 + y2 * c2)); } /** - * Convert a file to a unicode text string. - * - * @example + * Get the nearest point on a line with a known unit vector that passes through point A * * ```ts - * const A = FileHelpers.fileToDataUrl(myTextFile) + * Vec.nearestPointOnLineThroughPoint(A, u, Point) * ``` * - * @param file - The file as a blob. + * @param A - Any point on the line + * @param u - The unit vector for the line. + * @param P - A point not on the line to test. */ - static async blobToText(file) { - return await new Promise((resolve, reject) => { - if (file) { - const reader = new FileReader(); - reader.onload = () => resolve(reader.result); - reader.onerror = (error) => reject(error); - reader.onabort = (error) => reject(error); - reader.readAsText(file); - } - }); + static NearestPointOnLineThroughPoint(A, u2, P2) { + return Vec.Mul(u2, Vec.Sub(P2, A).pry(u2)).add(A); } -} -function getHashForString(string2) { - let hash = 0; - for (let i2 = 0; i2 < string2.length; i2++) { - hash = (hash << 5) - hash + string2.charCodeAt(i2); - hash |= 0; + static NearestPointOnLineSegment(A, B2, P2, clamp2 = true) { + if (Vec.Equals(A, P2)) return Vec.From(P2); + if (Vec.Equals(B2, P2)) return Vec.From(P2); + const u2 = Vec.Tan(B2, A); + const C2 = Vec.Add(A, Vec.Mul(u2, Vec.Sub(P2, A).pry(u2))); + if (clamp2) { + if (C2.x < Math.min(A.x, B2.x)) return Vec.Cast(A.x < B2.x ? A : B2); + if (C2.x > Math.max(A.x, B2.x)) return Vec.Cast(A.x > B2.x ? A : B2); + if (C2.y < Math.min(A.y, B2.y)) return Vec.Cast(A.y < B2.y ? A : B2); + if (C2.y > Math.max(A.y, B2.y)) return Vec.Cast(A.y > B2.y ? A : B2); + } + return C2; } - return hash + ""; -} -function getHashForBuffer(buffer) { - const view = new DataView(buffer); - let hash = 0; - for (let i2 = 0; i2 < view.byteLength; i2++) { - hash = (hash << 5) - hash + view.getUint8(i2); - hash |= 0; + static DistanceToLineThroughPoint(A, u2, P2) { + return Vec.Dist(P2, Vec.NearestPointOnLineThroughPoint(A, u2, P2)); + } + static DistanceToLineSegment(A, B2, P2, clamp2 = true) { + return Vec.Dist(P2, Vec.NearestPointOnLineSegment(A, B2, P2, clamp2)); + } + static Snap(A, step = 1) { + return new Vec(Math.round(A.x / step) * step, Math.round(A.y / step) * step); + } + static Cast(A) { + if (A instanceof Vec) return A; + return Vec.From(A); + } + static Slope(A, B2) { + if (A.x === B2.y) return NaN; + return (A.y - B2.y) / (A.x - B2.x); + } + static IsNaN(A) { + return isNaN(A.x) || isNaN(A.y); + } + static Angle(A, B2) { + return Math.atan2(B2.y - A.y, B2.x - A.x); + } + /** + * Linearly interpolate between two points. + * @param A - The first point. + * @param B - The second point. + * @param t - The interpolation value between 0 and 1. + * @returns The interpolated point. + */ + static Lrp(A, B2, t2) { + return Vec.Sub(B2, A).mul(t2).add(A); + } + static Med(A, B2) { + return new Vec((A.x + B2.x) / 2, (A.y + B2.y) / 2); + } + static Equals(A, B2) { + return Math.abs(A.x - B2.x) < 1e-4 && Math.abs(A.y - B2.y) < 1e-4; + } + static EqualsXY(A, x2, y2) { + return A.x === x2 && A.y === y2; + } + static Clockwise(A, B2, C2) { + return (C2.x - A.x) * (B2.y - A.y) - (B2.x - A.x) * (C2.y - A.y) < 0; + } + static Rescale(A, n) { + const l2 = Vec.Len(A); + return new Vec(n * A.x / l2, n * A.y / l2); + } + static ScaleWithOrigin(A, scale, origin) { + return Vec.Sub(A, origin).mul(scale).add(origin); + } + static ToFixed(A) { + return new Vec(toFixed(A.x), toFixed(A.y)); + } + static ToInt(A) { + return new Vec( + parseInt(A.x.toFixed(0)), + parseInt(A.y.toFixed(0)), + parseInt((A.z ?? 0).toFixed(0)) + ); + } + static ToCss(A) { + return `${A.x},${A.y}`; } - return hash + ""; -} -/*! - * MIT License: https://github.com/ai/nanoid/blob/main/LICENSE - * Modified code originally from - * Copyright 2017 Andrey Sitnik - * - * `nanoid` is currently only distributed as an ES module. Some tools (jest, playwright) don't - * properly support ESM-only code yet, and tldraw itself is distributed as both an ES module and a - * CommonJS module. By including nanoid here, we can make sure it works well in every environment - * where tldraw is used. We can also remove some unused features like custom alphabets. - */ -const crypto$1 = globalThis.crypto; -const urlAlphabet = "useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"; -const POOL_SIZE_MULTIPLIER = 128; -let pool, poolOffset; -function fillPool(bytes) { - if (!pool || pool.length < bytes) { - pool = new Uint8Array(bytes * POOL_SIZE_MULTIPLIER); - crypto$1.getRandomValues(pool); - poolOffset = 0; - } else if (poolOffset + bytes > pool.length) { - crypto$1.getRandomValues(pool); - poolOffset = 0; + static Nudge(A, B2, distance) { + return Vec.Add(A, Vec.Tan(B2, A).mul(distance)); } - poolOffset += bytes; -} -function nanoid(size2 = 21) { - fillPool(size2 -= 0); - let id2 = ""; - for (let i2 = poolOffset - size2; i2 < poolOffset; i2++) { - id2 += urlAlphabet[pool[i2] & 63]; + static ToString(A) { + return `${A.x}, ${A.y}`; } - return id2; -} -let impl = nanoid; -function uniqueId(size2) { - return impl(size2); -} -/*! - * MIT License: https://github.com/vHeemstra/is-apng/blob/main/license - * Copyright (c) Philip van Heemstra - */ -function isApngAnimated(buffer) { - const view = new Uint8Array(buffer); - if (!view || !(typeof Buffer !== "undefined" && Buffer.isBuffer(view) || view instanceof Uint8Array) || view.length < 16) { - return false; + static ToAngle(A) { + let r = Math.atan2(A.y, A.x); + if (r < 0) r += Math.PI * 2; + return r; } - const isPNG = view[0] === 137 && view[1] === 80 && view[2] === 78 && view[3] === 71 && view[4] === 13 && view[5] === 10 && view[6] === 26 && view[7] === 10; - if (!isPNG) { - return false; + static FromAngle(r, length = 1) { + return new Vec(Math.cos(r) * length, Math.sin(r) * length); } - function indexOfSubstring(haystack, needle, fromIndex, upToIndex, chunksize = 1024) { - if (!needle) { - return -1; - } - needle = new RegExp(needle, "g"); - const needle_length = needle.source.length; - const decoder = new TextDecoder(); - const full_haystack_length = haystack.length; - if (typeof upToIndex === "undefined") { - upToIndex = full_haystack_length; + static ToArray(A) { + return [A.x, A.y, A.z]; + } + static ToJson(A) { + const { x: x2, y: y2, z } = A; + return { x: x2, y: y2, z }; + } + static Average(arr) { + const len = arr.length; + const avg = new Vec(0, 0); + if (len === 0) { + return avg; } - if (fromIndex >= full_haystack_length || upToIndex <= 0 || fromIndex >= upToIndex) { - return -1; + for (let i2 = 0; i2 < len; i2++) { + avg.add(arr[i2]); } - haystack = haystack.subarray(fromIndex, upToIndex); - let position = -1; - let current_index = 0; - let full_length = 0; - let needle_buffer = ""; - outer: while (current_index < haystack.length) { - const next_index = current_index + chunksize; - const chunk = haystack.subarray(current_index, next_index); - const decoded = decoder.decode(chunk, { stream: true }); - const text = needle_buffer + decoded; - let match2; - let last_index = -1; - while ((match2 = needle.exec(text)) !== null) { - last_index = match2.index - needle_buffer.length; - position = full_length + last_index; - break outer; - } - current_index = next_index; - full_length += decoded.length; - const needle_index = last_index > -1 ? last_index + needle_length : decoded.length - needle_length; - needle_buffer = decoded.slice(needle_index); + return avg.div(len); + } + static Clamp(A, min2, max2) { + if (max2 === void 0) { + return new Vec(Math.min(Math.max(A.x, min2)), Math.min(Math.max(A.y, min2))); } - if (position >= 0) { - position += fromIndex >= 0 ? fromIndex : full_haystack_length + fromIndex; + return new Vec(Math.min(Math.max(A.x, min2), max2), Math.min(Math.max(A.y, min2), max2)); + } + /** + * Get an array of points (with simulated pressure) between two points. + * + * @param A - The first point. + * @param B - The second point. + * @param steps - The number of points to return. + */ + static PointsBetween(A, B2, steps = 6) { + const results = []; + for (let i2 = 0; i2 < steps; i2++) { + const t2 = EASINGS.easeInQuad(i2 / (steps - 1)); + const point = Vec.Lrp(A, B2, t2); + point.z = Math.min(1, 0.5 + Math.abs(0.5 - ease(t2)) * 0.65); + results.push(point); } - return position; + return results; } - const idatIdx = indexOfSubstring(view, "IDAT", 12); - if (idatIdx >= 12) { - const actlIdx = indexOfSubstring(view, "acTL", 8, idatIdx); - return actlIdx >= 8; + static SnapToGrid(A, gridSize = 8) { + return new Vec(Math.round(A.x / gridSize) * gridSize, Math.round(A.y / gridSize) * gridSize); } - return false; } -const isAvifAnimated = (buffer) => { - const view = new Uint8Array(buffer); - return view[3] === 44; -}; -/*! - * MIT License - * Modified code originally from - * Copyright (c) 2016 Józef Sokołowski - */ -function getDataBlocksLength(buffer, offset2) { - let length = 0; - while (buffer[offset2 + length]) { - length += buffer[offset2 + length] + 1; +const ease = (t2) => t2 < 0.5 ? 2 * t2 * t2 : -1 + (4 - 2 * t2) * t2; +function precise(A) { + return `${toDomPrecision(A.x)},${toDomPrecision(A.y)} `; +} +function average(A, B2) { + return `${toDomPrecision((A.x + B2.x) / 2)},${toDomPrecision((A.y + B2.y) / 2)} `; +} +const PI$1 = Math.PI; +const HALF_PI = PI$1 / 2; +const PI2 = PI$1 * 2; +const SIN = Math.sin; +function clamp$3(n, min2, max2) { + return Math.max(min2, typeof max2 !== "undefined" ? Math.min(n, max2) : n); +} +function toPrecision(n, precision = 1e10) { + if (!n) return 0; + return Math.round(n * precision) / precision; +} +function approximately(a2, b2, precision = 1e-6) { + return Math.abs(a2 - b2) <= precision; +} +function perimeterOfEllipse(rx, ry) { + const h2 = Math.pow(rx - ry, 2) / Math.pow(rx + ry, 2); + return PI$1 * (rx + ry) * (1 + 3 * h2 / (10 + Math.sqrt(4 - 3 * h2))); +} +function canonicalizeRotation(a2) { + a2 = a2 % PI2; + if (a2 < 0) { + a2 = a2 + PI2; + } else if (a2 === 0) { + a2 = 0; } - return length + 1; + return a2; } -function isGIF(buffer) { - const enc = new TextDecoder("ascii"); - const header = enc.decode(buffer.slice(0, 3)); - return header === "GIF"; +function clockwiseAngleDist(a0, a1) { + a0 = canonicalizeRotation(a0); + a1 = canonicalizeRotation(a1); + if (a0 > a1) { + a1 += PI2; + } + return a1 - a0; } -function isGifAnimated(buffer) { - const view = new Uint8Array(buffer); - let hasColorTable, colorTableSize; - let offset2 = 0; - let imagesCount = 0; - if (!isGIF(buffer)) { - return false; +function counterClockwiseAngleDist(a0, a1) { + return PI2 - clockwiseAngleDist(a0, a1); +} +function shortAngleDist(a0, a1) { + const da = (a1 - a0) % PI2; + return 2 * da % PI2 - da; +} +function clampRadians(r) { + return (PI2 + r) % PI2; +} +function snapAngle(r, segments) { + const seg = PI2 / segments; + let ang = Math.floor((clampRadians(r) + seg / 2) / seg) * seg % PI2; + if (ang < PI$1) ang += PI2; + if (ang > PI$1) ang -= PI2; + return ang; +} +function areAnglesCompatible(a2, b2) { + return a2 === b2 || approximately(a2 % (Math.PI / 2) - b2 % (Math.PI / 2), 0); +} +function degreesToRadians(d2) { + return d2 * PI$1 / 180; +} +function radiansToDegrees(r) { + return r * 180 / PI$1; +} +function getPointOnCircle(center, r, a2) { + return new Vec(center.x, center.y).add(Vec.FromAngle(a2, r)); +} +function getPolygonVertices(width, height, sides2) { + const cx = width / 2; + const cy = height / 2; + const pointsOnPerimeter = []; + let minX = Infinity; + let maxX = -Infinity; + let minY = Infinity; + let maxY = -Infinity; + for (let i2 = 0; i2 < sides2; i2++) { + const step = PI2 / sides2; + const t2 = -HALF_PI + i2 * step; + const x2 = cx + cx * Math.cos(t2); + const y2 = cy + cy * Math.sin(t2); + if (x2 < minX) minX = x2; + if (y2 < minY) minY = y2; + if (x2 > maxX) maxX = x2; + if (y2 > maxY) maxY = y2; + pointsOnPerimeter.push(new Vec(x2, y2)); } - hasColorTable = view[10] & 128; - colorTableSize = view[10] & 7; - offset2 += 6; - offset2 += 7; - offset2 += hasColorTable ? 3 * Math.pow(2, colorTableSize + 1) : 0; - while (imagesCount < 2 && offset2 < view.length) { - switch (view[offset2]) { - case 44: - imagesCount += 1; - hasColorTable = view[offset2 + 9] & 128; - colorTableSize = view[offset2 + 9] & 7; - offset2 += 10; - offset2 += hasColorTable ? 3 * Math.pow(2, colorTableSize + 1) : 0; - offset2 += getDataBlocksLength(view, offset2 + 1) + 1; - break; - case 33: - offset2 += 2; - offset2 += getDataBlocksLength(view, offset2); - break; - case 59: - offset2 = view.length; - break; - default: - offset2 = view.length; - break; + const w2 = maxX - minX; + const h2 = maxY - minY; + const dx = width - w2; + const dy = height - h2; + if (dx !== 0 || dy !== 0) { + for (let i2 = 0; i2 < pointsOnPerimeter.length; i2++) { + const pt = pointsOnPerimeter[i2]; + pt.x = (pt.x - minX) / w2 * width; + pt.y = (pt.y - minY) / h2 * height; } } - return imagesCount > 1; + return pointsOnPerimeter; } -/*! - * MIT License: https://github.com/alexgorbatchev/crc/blob/master/LICENSE - * Copyright: 2014 Alex Gorbatchev - * Code: crc32, https://github.com/alexgorbatchev/crc/blob/master/src/calculators/crc32.ts - */ -let TABLE = [ - 0, - 1996959894, - 3993919788, - 2567524794, - 124634137, - 1886057615, - 3915621685, - 2657392035, - 249268274, - 2044508324, - 3772115230, - 2547177864, - 162941995, - 2125561021, - 3887607047, - 2428444049, - 498536548, - 1789927666, - 4089016648, - 2227061214, - 450548861, - 1843258603, - 4107580753, - 2211677639, - 325883990, - 1684777152, - 4251122042, - 2321926636, - 335633487, - 1661365465, - 4195302755, - 2366115317, - 997073096, - 1281953886, - 3579855332, - 2724688242, - 1006888145, - 1258607687, - 3524101629, - 2768942443, - 901097722, - 1119000684, - 3686517206, - 2898065728, - 853044451, - 1172266101, - 3705015759, - 2882616665, - 651767980, - 1373503546, - 3369554304, - 3218104598, - 565507253, - 1454621731, - 3485111705, - 3099436303, - 671266974, - 1594198024, - 3322730930, - 2970347812, - 795835527, - 1483230225, - 3244367275, - 3060149565, - 1994146192, - 31158534, - 2563907772, - 4023717930, - 1907459465, - 112637215, - 2680153253, - 3904427059, - 2013776290, - 251722036, - 2517215374, - 3775830040, - 2137656763, - 141376813, - 2439277719, - 3865271297, - 1802195444, - 476864866, - 2238001368, - 4066508878, - 1812370925, - 453092731, - 2181625025, - 4111451223, - 1706088902, - 314042704, - 2344532202, - 4240017532, - 1658658271, - 366619977, - 2362670323, - 4224994405, - 1303535960, - 984961486, - 2747007092, - 3569037538, - 1256170817, - 1037604311, - 2765210733, - 3554079995, - 1131014506, - 879679996, - 2909243462, - 3663771856, - 1141124467, - 855842277, - 2852801631, - 3708648649, - 1342533948, - 654459306, - 3188396048, - 3373015174, - 1466479909, - 544179635, - 3110523913, - 3462522015, - 1591671054, - 702138776, - 2966460450, - 3352799412, - 1504918807, - 783551873, - 3082640443, - 3233442989, - 3988292384, - 2596254646, - 62317068, - 1957810842, - 3939845945, - 2647816111, - 81470997, - 1943803523, - 3814918930, - 2489596804, - 225274430, - 2053790376, - 3826175755, - 2466906013, - 167816743, - 2097651377, - 4027552580, - 2265490386, - 503444072, - 1762050814, - 4150417245, - 2154129355, - 426522225, - 1852507879, - 4275313526, - 2312317920, - 282753626, - 1742555852, - 4189708143, - 2394877945, - 397917763, - 1622183637, - 3604390888, - 2714866558, - 953729732, - 1340076626, - 3518719985, - 2797360999, - 1068828381, - 1219638859, - 3624741850, - 2936675148, - 906185462, - 1090812512, - 3747672003, - 2825379669, - 829329135, - 1181335161, - 3412177804, - 3160834842, - 628085408, - 1382605366, - 3423369109, - 3138078467, - 570562233, - 1426400815, - 3317316542, - 2998733608, - 733239954, - 1555261956, - 3268935591, - 3050360625, - 752459403, - 1541320221, - 2607071920, - 3965973030, - 1969922972, - 40735498, - 2617837225, - 3943577151, - 1913087877, - 83908371, - 2512341634, - 3803740692, - 2075208622, - 213261112, - 2463272603, - 3855990285, - 2094854071, - 198958881, - 2262029012, - 4057260610, - 1759359992, - 534414190, - 2176718541, - 4139329115, - 1873836001, - 414664567, - 2282248934, - 4279200368, - 1711684554, - 285281116, - 2405801727, - 4167216745, - 1634467795, - 376229701, - 2685067896, - 3608007406, - 1308918612, - 956543938, - 2808555105, - 3495958263, - 1231636301, - 1047427035, - 2932959818, - 3654703836, - 1088359270, - 936918e3, - 2847714899, - 3736837829, - 1202900863, - 817233897, - 3183342108, - 3401237130, - 1404277552, - 615818150, - 3134207493, - 3453421203, - 1423857449, - 601450431, - 3009837614, - 3294710456, - 1567103746, - 711928724, - 3020668471, - 3272380065, - 1510334235, - 755167117 -]; -if (typeof Int32Array !== "undefined") { - TABLE = new Int32Array(TABLE); +function rangesOverlap(a0, a1, b0, b1) { + return a0 < b1 && b0 < a1; +} +function rangeIntersection(a0, a1, b0, b1) { + const min2 = Math.max(a0, b0); + const max2 = Math.min(a1, b1); + if (min2 <= max2) { + return [min2, max2]; + } + return null; } -const crc = (current, previous) => { - let crc2 = ~~previous ^ -1; - for (let index2 = 0; index2 < current.length; index2++) { - crc2 = TABLE[(crc2 ^ current[index2]) & 255] ^ crc2 >>> 8; +function cross(x2, y2, z) { + return (y2.x - x2.x) * (z.y - x2.y) - (z.x - x2.x) * (y2.y - x2.y); +} +function pointInPolygon(A, points) { + let windingNumber = 0; + let a2; + let b2; + for (let i2 = 0; i2 < points.length; i2++) { + a2 = points[i2]; + if (a2.x === A.x && a2.y === A.y) return true; + b2 = points[(i2 + 1) % points.length]; + if (Vec.Dist(A, a2) + Vec.Dist(A, b2) === Vec.Dist(a2, b2)) return true; + if (a2.y <= A.y) { + if (b2.y > A.y && cross(a2, b2, A) > 0) { + windingNumber += 1; + } + } else if (b2.y <= A.y && cross(a2, b2, A) < 0) { + windingNumber -= 1; + } } - return crc2 ^ -1; + return windingNumber !== 0; +} +function toDomPrecision(v2) { + return Math.round(v2 * 1e4) / 1e4; +} +function toFixed(v2) { + return Math.round(v2 * 100) / 100; +} +const isSafeFloat = (n) => { + return Math.abs(n) < Number.MAX_SAFE_INTEGER; }; -const LEN_SIZE = 4; -const CRC_SIZE = 4; -class PngHelpers { - static isPng(view, offset2) { - if (view.getUint8(offset2 + 0) === 137 && view.getUint8(offset2 + 1) === 80 && view.getUint8(offset2 + 2) === 78 && view.getUint8(offset2 + 3) === 71 && view.getUint8(offset2 + 4) === 13 && view.getUint8(offset2 + 5) === 10 && view.getUint8(offset2 + 6) === 26 && view.getUint8(offset2 + 7) === 10) { - return true; +function angleDistance(fromAngle, toAngle, direction) { + const dist = direction < 0 ? clockwiseAngleDist(fromAngle, toAngle) : counterClockwiseAngleDist(fromAngle, toAngle); + return dist; +} +function getPointInArcT(mAB, A, B2, P2) { + let mAP; + if (Math.abs(mAB) > PI$1) { + mAP = shortAngleDist(A, P2); + const mPB = shortAngleDist(P2, B2); + if (Math.abs(mAP) < Math.abs(mPB)) { + return mAP / mAB; + } else { + return (mAB - mPB) / mAB; } - return false; + } else { + mAP = shortAngleDist(A, P2); + const t2 = mAP / mAB; + if (Math.sign(mAP) !== Math.sign(mAB)) { + return Math.abs(t2) > 0.5 ? 1 : 0; + } + return t2; } - static getChunkType(view, offset2) { - return [ - String.fromCharCode(view.getUint8(offset2)), - String.fromCharCode(view.getUint8(offset2 + 1)), - String.fromCharCode(view.getUint8(offset2 + 2)), - String.fromCharCode(view.getUint8(offset2 + 3)) - ].join(""); +} +function getArcMeasure(A, B2, sweepFlag, largeArcFlag) { + const m2 = 2 * ((B2 - A) % PI2) % PI2 - (B2 - A) % PI2; + if (!largeArcFlag) return m2; + return (PI2 - Math.abs(m2)) * (sweepFlag ? 1 : -1); +} +function centerOfCircleFromThreePoints(a2, b2, c2) { + const u2 = -2 * (a2.x * (b2.y - c2.y) - a2.y * (b2.x - c2.x) + b2.x * c2.y - c2.x * b2.y); + const x2 = ((a2.x * a2.x + a2.y * a2.y) * (c2.y - b2.y) + (b2.x * b2.x + b2.y * b2.y) * (a2.y - c2.y) + (c2.x * c2.x + c2.y * c2.y) * (b2.y - a2.y)) / u2; + const y2 = ((a2.x * a2.x + a2.y * a2.y) * (b2.x - c2.x) + (b2.x * b2.x + b2.y * b2.y) * (c2.x - a2.x) + (c2.x * c2.x + c2.y * c2.y) * (a2.x - b2.x)) / u2; + if (!Number.isFinite(x2) || !Number.isFinite(y2)) { + return null; } - static readChunks(view, offset2 = 0) { - const chunks = {}; - if (!PngHelpers.isPng(view, offset2)) { - throw new Error("Not a PNG"); - } - offset2 += 8; - while (offset2 <= view.buffer.byteLength) { - const start = offset2; - const len = view.getInt32(offset2); - offset2 += 4; - const chunkType = PngHelpers.getChunkType(view, offset2); - if (chunkType === "IDAT" && chunks[chunkType]) { - offset2 += len + LEN_SIZE + CRC_SIZE; - continue; - } - if (chunkType === "IEND") { - break; - } - chunks[chunkType] = { - start, - dataOffset: offset2 + 4, - size: len + return new Vec(x2, y2); +} +function getPointsOnArc(startPoint, endPoint, center, radius, numPoints) { + if (center === null) { + return [Vec.From(startPoint), Vec.From(endPoint)]; + } + const results = []; + const startAngle = Vec.Angle(center, startPoint); + const endAngle = Vec.Angle(center, endPoint); + const l2 = clockwiseAngleDist(startAngle, endAngle); + for (let i2 = 0; i2 < numPoints; i2++) { + const t2 = i2 / (numPoints - 1); + const angle = startAngle + l2 * t2; + const point = getPointOnCircle(center, radius, angle); + results.push(point); + } + return results; +} +const DefaultBrush = ({ brush, color, opacity, className }) => { + const rSvg = reactExports.useRef(null); + useTransform(rSvg, brush.x, brush.y); + const w2 = toDomPrecision(Math.max(1, brush.w)); + const h2 = toDomPrecision(Math.max(1, brush.h)); + return /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { className: "tl-overlays__item", ref: rSvg, children: color ? /* @__PURE__ */ jsxRuntimeExports.jsxs("g", { className: "tl-brush", opacity, children: [ + /* @__PURE__ */ jsxRuntimeExports.jsx("rect", { width: w2, height: h2, fill: color, opacity: 0.75 }), + /* @__PURE__ */ jsxRuntimeExports.jsx("rect", { width: w2, height: h2, fill: "none", stroke: color, opacity: 0.1 }) + ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("rect", { className: `tl-brush tl-brush__default ${className}`, width: w2, height: h2 }) }); +}; +const tlenv = { + isSafari: false, + isIos: false, + isChromeForIos: false, + isFirefox: false, + isAndroid: false, + isWebview: false, + isDarwin: false +}; +if (typeof window !== "undefined" && "navigator" in window) { + tlenv.isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent); + tlenv.isIos = !!navigator.userAgent.match(/iPad/i) || !!navigator.userAgent.match(/iPhone/i); + tlenv.isChromeForIos = /crios.*safari/i.test(navigator.userAgent); + tlenv.isFirefox = /firefox/i.test(navigator.userAgent); + tlenv.isAndroid = /android/i.test(navigator.userAgent); + tlenv.isDarwin = window.navigator.userAgent.toLowerCase().indexOf("mac") > -1; +} +const DEFAULT_CAMERA_OPTIONS = { + isLocked: false, + wheelBehavior: "pan", + panSpeed: 1, + zoomSpeed: 1, + zoomSteps: [0.1, 0.25, 0.5, 1, 2, 4, 8] +}; +const DEFAULT_ANIMATION_OPTIONS = { + duration: 0, + easing: EASINGS.easeInOutCubic +}; +const INTERNAL_POINTER_IDS = { + CAMERA_MOVE: -10 +}; +const SIDES = ["top", "right", "bottom", "left"]; +const LEFT_MOUSE_BUTTON = 0; +const RIGHT_MOUSE_BUTTON = 2; +const MIDDLE_MOUSE_BUTTON = 1; +const STYLUS_ERASER_BUTTON = 5; +const ZOOM_TO_FIT_PADDING = 128; +var define_process_env_default$1 = {}; +const featureFlags = {}; +const pointerCaptureTrackingObject = createDebugValue( + "pointerCaptureTrackingObject", + // ideally we wouldn't store this mutable value in an atom but it's not + // a big deal for debug values + { + defaults: { all: /* @__PURE__ */ new Map() }, + shouldStoreForSession: false + } +); +const debugFlags = { + // --- DEBUG VALUES --- + logPreventDefaults: createDebugValue("logPreventDefaults", { + defaults: { all: false } + }), + logPointerCaptures: createDebugValue("logPointerCaptures", { + defaults: { all: false } + }), + logElementRemoves: createDebugValue("logElementRemoves", { + defaults: { all: false } + }), + debugSvg: createDebugValue("debugSvg", { + defaults: { all: false } + }), + showFps: createDebugValue("showFps", { + defaults: { all: false } + }), + measurePerformance: createDebugValue("measurePerformance", { defaults: { all: false } }), + throwToBlob: createDebugValue("throwToBlob", { + defaults: { all: false } + }), + reconnectOnPing: createDebugValue("reconnectOnPing", { + defaults: { all: false } + }), + debugCursors: createDebugValue("debugCursors", { + defaults: { all: false } + }), + forceSrgb: createDebugValue("forceSrgbColors", { defaults: { all: false } }), + debugGeometry: createDebugValue("debugGeometry", { defaults: { all: false } }), + hideShapes: createDebugValue("hideShapes", { defaults: { all: false } }), + editOnType: createDebugValue("editOnType", { defaults: { all: false } }) +}; +if (typeof Element !== "undefined") { + const nativeElementRemoveChild = Element.prototype.removeChild; + react("element removal logging", () => { + if (debugFlags.logElementRemoves.get()) { + Element.prototype.removeChild = function(child) { + console.warn("[tldraw] removing child:", child); + return nativeElementRemoveChild.call(this, child); }; - offset2 += len + LEN_SIZE + CRC_SIZE; + } else { + Element.prototype.removeChild = nativeElementRemoveChild; } - return chunks; + }); +} +function createDebugValue(name, { + defaults: defaults2, + shouldStoreForSession = true +}) { + return createDebugValueBase({ + name, + defaults: defaults2, + shouldStoreForSession + }); +} +function createDebugValueBase(def) { + const defaultValue = getDefaultValue(def); + const storedValue = def.shouldStoreForSession ? getStoredInitialValue(def.name) : null; + const valueAtom = atom(`debug:${def.name}`, storedValue ?? defaultValue); + if (typeof window !== "undefined") { + if (def.shouldStoreForSession) { + react(`debug:${def.name}`, () => { + const currentValue = valueAtom.get(); + if (currentValue === defaultValue) { + deleteFromSessionStorage(`tldraw_debug:${def.name}`); + } else { + setInSessionStorage(`tldraw_debug:${def.name}`, JSON.stringify(currentValue)); + } + }); + } + Object.defineProperty(window, `tldraw${def.name.replace(/^[a-z]/, (l2) => l2.toUpperCase())}`, { + get() { + return valueAtom.get(); + }, + set(newValue) { + valueAtom.set(newValue); + }, + configurable: true + }); } - static parsePhys(view, offset2) { - return { - ppux: view.getUint32(offset2), - ppuy: view.getUint32(offset2 + 4), - unit: view.getUint8(offset2 + 4) - }; + return Object.assign(valueAtom, def); +} +function getStoredInitialValue(name) { + try { + return JSON.parse(getFromSessionStorage(`tldraw_debug:${name}`) ?? "null"); + } catch { + return null; } - static findChunk(view, type) { - const chunks = PngHelpers.readChunks(view); - return chunks[type]; +} +function readEnv(fn) { + try { + return fn(); + } catch { + return null; } - static setPhysChunk(view, dpr = 1, options) { - let offset2 = 46; - let size2 = 0; - const res1 = PngHelpers.findChunk(view, "pHYs"); - if (res1) { - offset2 = res1.start; - size2 = res1.size; - } - const res2 = PngHelpers.findChunk(view, "IDAT"); - if (res2) { - offset2 = res2.start; - size2 = 0; +} +function getDefaultValue(def) { + const env = readEnv(() => define_process_env_default$1.TLDRAW_ENV) ?? readEnv(() => define_process_env_default$1.VERCEL_PUBLIC_TLDRAW_ENV) ?? readEnv(() => define_process_env_default$1.NEXT_PUBLIC_TLDRAW_ENV) ?? // default to production because if we don't have one of these, this is probably a library use + "production"; + switch (env) { + case "production": + return def.defaults.production ?? def.defaults.all; + case "preview": + case "staging": + return def.defaults.staging ?? def.defaults.all; + default: + return def.defaults.development ?? def.defaults.all; + } +} +function loopToHtmlElement(elm) { + if (elm instanceof HTMLElement) return elm; + if (elm.parentElement) return loopToHtmlElement(elm.parentElement); + else throw Error("Could not find a parent element of an HTML type!"); +} +function preventDefault(event) { + event.preventDefault(); + if (debugFlags.logPreventDefaults.get()) { + console.warn("preventDefault called on event:", event); + } +} +function setPointerCapture(element, event) { + element.setPointerCapture(event.pointerId); + if (debugFlags.logPointerCaptures.get()) { + const trackingObj = pointerCaptureTrackingObject.get(); + trackingObj.set(element, (trackingObj.get(element) ?? 0) + 1); + console.warn("setPointerCapture called on element:", element, event); + } +} +function releasePointerCapture(element, event) { + if (!element.hasPointerCapture(event.pointerId)) { + return; + } + element.releasePointerCapture(event.pointerId); + if (debugFlags.logPointerCaptures.get()) { + const trackingObj = pointerCaptureTrackingObject.get(); + if (trackingObj.get(element) === 1) { + trackingObj.delete(element); + } else if (trackingObj.has(element)) { + trackingObj.set(element, trackingObj.get(element) - 1); + } else { + console.warn("Release without capture"); } - const pHYsData = new ArrayBuffer(21); - const pHYsDataView = new DataView(pHYsData); - pHYsDataView.setUint32(0, 9); - pHYsDataView.setUint8(4, "p".charCodeAt(0)); - pHYsDataView.setUint8(5, "H".charCodeAt(0)); - pHYsDataView.setUint8(6, "Y".charCodeAt(0)); - pHYsDataView.setUint8(7, "s".charCodeAt(0)); - const DPI_96 = 2835.5; - pHYsDataView.setInt32(8, DPI_96 * dpr); - pHYsDataView.setInt32(12, DPI_96 * dpr); - pHYsDataView.setInt8(16, 1); - const crcBit = new Uint8Array(pHYsData.slice(4, 17)); - pHYsDataView.setInt32(17, crc(crcBit)); - const startBuf = view.buffer.slice(0, offset2); - const endBuf = view.buffer.slice(offset2 + size2); - return new Blob([startBuf, pHYsData, endBuf], options); + console.warn("releasePointerCapture called on element:", element, event); } } -/*! - * MIT License: https://github.com/sindresorhus/is-webp/blob/main/license - * Copyright (c) Sindre Sorhus (https://sindresorhus.com) - */ -function isWebp(view) { - if (!view || view.length < 12) { - return false; - } - return view[8] === 87 && view[9] === 69 && view[10] === 66 && view[11] === 80; +const stopEventPropagation = (e2) => e2.stopPropagation(); +const setStyleProperty = (elm, property, value) => { + if (!elm) return; + elm.style.setProperty(property, value); +}; +const isAccelKey = (e2) => { + return tlenv.isDarwin ? e2.metaKey : e2.ctrlKey || e2.metaKey; +}; +function getPointerInfo(e2) { + e2.isKilled = true; + return { + point: { + x: e2.clientX, + y: e2.clientY, + z: e2.pressure + }, + shiftKey: e2.shiftKey, + altKey: e2.altKey, + ctrlKey: e2.metaKey || e2.ctrlKey, + metaKey: e2.metaKey, + accelKey: isAccelKey(e2), + pointerId: e2.pointerId, + button: e2.button, + isPen: e2.pointerType === "pen" + }; +} +function useCanvasEvents() { + const editor = useEditor(); + const events = reactExports.useMemo( + function canvasEvents() { + let lastX, lastY; + function onPointerDown(e2) { + if (e2.isKilled) return; + if (e2.button === RIGHT_MOUSE_BUTTON) { + editor.dispatch({ + type: "pointer", + target: "canvas", + name: "right_click", + ...getPointerInfo(e2) + }); + return; + } + if (e2.button !== 0 && e2.button !== 1 && e2.button !== 5) return; + setPointerCapture(e2.currentTarget, e2); + editor.dispatch({ + type: "pointer", + target: "canvas", + name: "pointer_down", + ...getPointerInfo(e2) + }); + } + function onPointerMove(e2) { + if (e2.isKilled) return; + if (e2.clientX === lastX && e2.clientY === lastY) return; + lastX = e2.clientX; + lastY = e2.clientY; + editor.dispatch({ + type: "pointer", + target: "canvas", + name: "pointer_move", + ...getPointerInfo(e2) + }); + } + function onPointerUp(e2) { + if (e2.isKilled) return; + if (e2.button !== 0 && e2.button !== 1 && e2.button !== 2 && e2.button !== 5) return; + lastX = e2.clientX; + lastY = e2.clientY; + releasePointerCapture(e2.currentTarget, e2); + editor.dispatch({ + type: "pointer", + target: "canvas", + name: "pointer_up", + ...getPointerInfo(e2) + }); + } + function onPointerEnter(e2) { + if (e2.isKilled) return; + if (editor.getInstanceState().isPenMode && e2.pointerType !== "pen") return; + const canHover = e2.pointerType === "mouse" || e2.pointerType === "pen"; + editor.updateInstanceState({ isHoveringCanvas: canHover ? true : null }); + } + function onPointerLeave(e2) { + if (e2.isKilled) return; + if (editor.getInstanceState().isPenMode && e2.pointerType !== "pen") return; + const canHover = e2.pointerType === "mouse" || e2.pointerType === "pen"; + editor.updateInstanceState({ isHoveringCanvas: canHover ? false : null }); + } + function onTouchStart(e2) { + e2.isKilled = true; + preventDefault(e2); + } + function onTouchEnd(e2) { + e2.isKilled = true; + if (!(e2.target instanceof HTMLElement)) return; + if (e2.target.tagName !== "A" && e2.target.tagName !== "TEXTAREA" && // When in EditingShape state, we are actually clicking on a 'DIV' + // not A/TEXTAREA element yet. So, to preserve cursor position + // for edit mode on mobile we need to not preventDefault. + // TODO: Find out if we still need this preventDefault in general though. + !(editor.getEditingShape() && e2.target.className.includes("tl-text-content"))) { + preventDefault(e2); + } + } + function onDragOver(e2) { + preventDefault(e2); + } + async function onDrop(e2) { + var _a3, _b2; + preventDefault(e2); + stopEventPropagation(e2); + if (!((_b2 = (_a3 = e2.dataTransfer) == null ? void 0 : _a3.files) == null ? void 0 : _b2.length)) return; + const files = Array.from(e2.dataTransfer.files); + await editor.putExternalContent({ + type: "files", + files, + point: editor.screenToPage({ x: e2.clientX, y: e2.clientY }), + ignoreParent: false + }); + } + function onClick(e2) { + stopEventPropagation(e2); + } + return { + onPointerDown, + onPointerMove, + onPointerUp, + onPointerEnter, + onPointerLeave, + onDragOver, + onDrop, + onTouchStart, + onTouchEnd, + onClick + }; + }, + [editor] + ); + return events; +} +function useCoarsePointer() { + const editor = useEditor(); + reactExports.useEffect(() => { + let isCoarse = editor.getInstanceState().isCoarsePointer; + const handlePointerDown = (e2) => { + const isCoarseEvent = e2.pointerType !== "mouse"; + if (isCoarse === isCoarseEvent) return; + isCoarse = isCoarseEvent; + editor.updateInstanceState({ isCoarsePointer: isCoarseEvent }); + }; + window.addEventListener("pointerdown", handlePointerDown, { capture: true }); + const mql = window.matchMedia && window.matchMedia("(any-pointer: coarse)"); + const isForcedFinePointer = tlenv.isFirefox && !tlenv.isAndroid && !tlenv.isIos; + const handleMediaQueryChange = () => { + const next = isForcedFinePointer ? false : mql.matches; + if (isCoarse !== next) return; + isCoarse = next; + editor.updateInstanceState({ isCoarsePointer: next }); + }; + if (mql) { + mql.addEventListener("change", handleMediaQueryChange); + handleMediaQueryChange(); + } + return () => { + window.removeEventListener("pointerdown", handlePointerDown, { capture: true }); + if (mql) { + mql.removeEventListener("change", handleMediaQueryChange); + } + }; + }, [editor]); +} +const ContainerContext = reactExports.createContext(null); +function ContainerProvider({ container, children }) { + return /* @__PURE__ */ jsxRuntimeExports.jsx(ContainerContext.Provider, { value: container, children }); } -function isWebpAnimated(buffer) { - const view = new Uint8Array(buffer); - if (!isWebp(view)) { - return false; - } - if (!view || view.length < 21) { - return false; - } - return (view[20] >> 1 & 1) === 1; +function useContainer() { + return assertExists(reactExports.useContext(ContainerContext), "useContainer used outside of "); } -const DEFAULT_SUPPORTED_VECTOR_IMAGE_TYPES = Object.freeze(["image/svg+xml"]); -const DEFAULT_SUPPORTED_STATIC_IMAGE_TYPES = Object.freeze([ - "image/jpeg", - "image/png", - "image/webp" -]); -const DEFAULT_SUPPORTED_ANIMATED_IMAGE_TYPES = Object.freeze([ - "image/gif", - "image/apng", - "image/avif" -]); -const DEFAULT_SUPPORTED_IMAGE_TYPES = Object.freeze([ - ...DEFAULT_SUPPORTED_STATIC_IMAGE_TYPES, - ...DEFAULT_SUPPORTED_VECTOR_IMAGE_TYPES, - ...DEFAULT_SUPPORTED_ANIMATED_IMAGE_TYPES -]); -const DEFAULT_SUPPORT_VIDEO_TYPES = Object.freeze([ - "video/mp4", - "video/webm", - "video/quicktime" -]); -const DEFAULT_SUPPORTED_MEDIA_TYPE_LIST = [ - ...DEFAULT_SUPPORTED_IMAGE_TYPES, - ...DEFAULT_SUPPORT_VIDEO_TYPES -].join(","); -class MediaHelpers { - /** - * Load a video from a url. - * @public - */ - static loadVideo(src) { - return new Promise((resolve, reject) => { - const video = document.createElement("video"); - video.onloadeddata = () => resolve(video); - video.onerror = (e2) => { - console.error(e2); - reject(new Error("Could not load video")); +function useDocumentEvents() { + const editor = useEditor(); + const container = useContainer(); + const isAppFocused = useValue("isFocused", () => editor.getIsFocused(), [editor]); + reactExports.useEffect(() => { + if (!container) return; + function onDrop(e2) { + if (e2.isSpecialRedispatchedEvent) return; + preventDefault(e2); + stopEventPropagation(e2); + const cvs = container.querySelector(".tl-canvas"); + if (!cvs) return; + const newEvent = new DragEvent(e2.type, e2); + newEvent.isSpecialRedispatchedEvent = true; + cvs.dispatchEvent(newEvent); + } + container.addEventListener("dragover", onDrop); + container.addEventListener("drop", onDrop); + return () => { + container.removeEventListener("dragover", onDrop); + container.removeEventListener("drop", onDrop); + }; + }, [container]); + reactExports.useEffect(() => { + if (typeof window === "undefined" || !("matchMedia" in window)) return; + let remove2 = null; + const updatePixelRatio = () => { + if (remove2 != null) { + remove2(); + } + const mqString = `(resolution: ${window.devicePixelRatio}dppx)`; + const media = matchMedia(mqString); + const safariCb = (ev) => { + if (ev.type === "change") { + updatePixelRatio(); + } }; - video.crossOrigin = "anonymous"; - video.src = src; - }); - } - static async getVideoFrameAsDataUrl(video, time2 = 0) { - const promise = promiseWithResolve(); - let didSetTime = false; - const onReadyStateChanged = () => { - if (!didSetTime) { - if (video.readyState >= video.HAVE_METADATA) { - didSetTime = true; - video.currentTime = time2; - } else { - return; + if (media.addEventListener) { + media.addEventListener("change", updatePixelRatio); + } else if (media.addListener) { + media.addListener(safariCb); + } + remove2 = () => { + if (media.removeEventListener) { + media.removeEventListener("change", updatePixelRatio); + } else if (media.removeListener) { + media.removeListener(safariCb); } + }; + editor.updateInstanceState({ devicePixelRatio: window.devicePixelRatio }); + }; + updatePixelRatio(); + return () => { + remove2 == null ? void 0 : remove2(); + }; + }, [editor]); + reactExports.useEffect(() => { + if (!isAppFocused) return; + const handleKeyDown = (e2) => { + if (e2.altKey && // todo: When should we allow the alt key to be used? Perhaps states should declare which keys matter to them? + (editor.isIn("zoom") || !editor.getPath().endsWith(".idle")) && !areShortcutsDisabled$2(editor)) { + preventDefault(e2); } - if (video.readyState >= video.HAVE_CURRENT_DATA) { - const canvas = document.createElement("canvas"); - canvas.width = video.videoWidth; - canvas.height = video.videoHeight; - const ctx = canvas.getContext("2d"); - if (!ctx) { - throw new Error("Could not get 2d context"); + if (e2.isKilled) return; + e2.isKilled = true; + switch (e2.key) { + case "=": + case "-": + case "0": { + if (e2.metaKey || e2.ctrlKey) { + preventDefault(e2); + return; + } + break; + } + case "Tab": { + if (areShortcutsDisabled$2(editor)) { + return; + } + break; + } + case ",": { + return; + } + case "Escape": { + if (editor.getEditingShape() || editor.getSelectedShapeIds().length > 0) { + preventDefault(e2); + } + if (editor.menus.getOpenMenus().length > 0) return; + if (editor.inputs.keys.has("Escape")) ; + else { + editor.inputs.keys.add("Escape"); + editor.cancel(); + container.focus(); + } + return; + } + default: { + if (areShortcutsDisabled$2(editor)) { + return; + } } - ctx.drawImage(video, 0, 0); - promise.resolve(canvas.toDataURL()); } + const info = { + type: "keyboard", + name: e2.repeat ? "key_repeat" : "key_down", + key: e2.key, + code: e2.code, + shiftKey: e2.shiftKey, + altKey: e2.altKey, + ctrlKey: e2.metaKey || e2.ctrlKey, + metaKey: e2.metaKey, + accelKey: isAccelKey(e2) + }; + editor.dispatch(info); }; - const onError = (e2) => { - console.error(e2); - promise.reject(new Error("Could not get video frame")); - }; - video.addEventListener("loadedmetadata", onReadyStateChanged); - video.addEventListener("loadeddata", onReadyStateChanged); - video.addEventListener("canplay", onReadyStateChanged); - video.addEventListener("seeked", onReadyStateChanged); - video.addEventListener("error", onError); - video.addEventListener("stalled", onError); - onReadyStateChanged(); - try { - return await promise; - } finally { - video.removeEventListener("loadedmetadata", onReadyStateChanged); - video.removeEventListener("loadeddata", onReadyStateChanged); - video.removeEventListener("canplay", onReadyStateChanged); - video.removeEventListener("seeked", onReadyStateChanged); - video.removeEventListener("error", onError); - video.removeEventListener("stalled", onError); - } - } - /** - * Load an image from a url. - * @public - */ - static loadImage(src) { - return new Promise((resolve, reject) => { - const img = Image(); - img.onload = () => resolve(img); - img.onerror = (e2) => { - console.error(e2); - reject(new Error("Could not load image")); + const handleKeyUp = (e2) => { + if (e2.isKilled) return; + e2.isKilled = true; + if (areShortcutsDisabled$2(editor)) { + return; + } + if (e2.key === ",") { + return; + } + const info = { + type: "keyboard", + name: "key_up", + key: e2.key, + code: e2.code, + shiftKey: e2.shiftKey, + altKey: e2.altKey, + ctrlKey: e2.metaKey || e2.ctrlKey, + metaKey: e2.metaKey, + accelKey: isAccelKey(e2) }; - img.crossOrigin = "anonymous"; - img.referrerPolicy = "strict-origin-when-cross-origin"; - img.src = src; - }); - } - /** - * Get the size of a video blob - * - * @param blob - A SharedBlob containing the video - * @public - */ - static async getVideoSize(blob) { - return MediaHelpers.usingObjectURL(blob, async (url) => { - const video = await MediaHelpers.loadVideo(url); - return { w: video.videoWidth, h: video.videoHeight }; - }); - } - /** - * Get the size of an image blob - * - * @param blob - A Blob containing the image. - * @public - */ - static async getImageSize(blob) { - const image = await MediaHelpers.usingObjectURL(blob, MediaHelpers.loadImage); - try { - if (blob.type === "image/png") { - const view = new DataView(await blob.arrayBuffer()); - if (PngHelpers.isPng(view, 0)) { - const physChunk = PngHelpers.findChunk(view, "pHYs"); - if (physChunk) { - const physData = PngHelpers.parsePhys(view, physChunk.dataOffset); - if (physData.unit === 0 && physData.ppux === physData.ppuy) { - const pixelRatio = Math.max(physData.ppux / 2834.5, 1); - return { - w: Math.round(image.naturalWidth / pixelRatio), - h: Math.round(image.naturalHeight / pixelRatio) - }; - } + editor.dispatch(info); + }; + function handleTouchStart(e2) { + var _a3, _b2; + if (container.contains(e2.target)) { + const touchXPosition = e2.touches[0].pageX; + const touchXRadius = e2.touches[0].radiusX || 0; + if (touchXPosition - touchXRadius < 10 || touchXPosition + touchXRadius > editor.getViewportScreenBounds().width - 10) { + if (((_a3 = e2.target) == null ? void 0 : _a3.tagName) === "BUTTON") { + (_b2 = e2.target) == null ? void 0 : _b2.click(); } + preventDefault(e2); } } - } catch (err) { - console.error(err); - return { w: image.naturalWidth, h: image.naturalHeight }; - } - return { w: image.naturalWidth, h: image.naturalHeight }; - } - static async isAnimated(file) { - if (file.type === "image/gif") { - return isGifAnimated(await file.arrayBuffer()); - } - if (file.type === "image/avif") { - return isAvifAnimated(await file.arrayBuffer()); - } - if (file.type === "image/webp") { - return isWebpAnimated(await file.arrayBuffer()); - } - if (file.type === "image/apng") { - return isApngAnimated(await file.arrayBuffer()); } - return false; + const handleWheel = (e2) => { + if (container.contains(e2.target) && (e2.ctrlKey || e2.metaKey)) { + preventDefault(e2); + } + }; + container.addEventListener("touchstart", handleTouchStart, { passive: false }); + container.addEventListener("wheel", handleWheel, { passive: false }); + document.addEventListener("gesturestart", preventDefault); + document.addEventListener("gesturechange", preventDefault); + document.addEventListener("gestureend", preventDefault); + container.addEventListener("keydown", handleKeyDown); + container.addEventListener("keyup", handleKeyUp); + return () => { + container.removeEventListener("touchstart", handleTouchStart); + container.removeEventListener("wheel", handleWheel); + document.removeEventListener("gesturestart", preventDefault); + document.removeEventListener("gesturechange", preventDefault); + document.removeEventListener("gestureend", preventDefault); + container.removeEventListener("keydown", handleKeyDown); + container.removeEventListener("keyup", handleKeyUp); + }; + }, [editor, container, isAppFocused]); +} +const INPUTS$1 = ["input", "select", "button", "textarea"]; +function areShortcutsDisabled$2(editor) { + const { activeElement } = document; + return editor.menus.hasOpenMenus() || activeElement && (activeElement.getAttribute("contenteditable") || INPUTS$1.indexOf(activeElement.tagName.toLowerCase()) > -1); +} +const IGNORED_TAGS = ["textarea", "input"]; +function useFixSafariDoubleTapZoomPencilEvents(ref) { + const editor = useEditor(); + reactExports.useEffect(() => { + const elm = ref.current; + if (!elm) return; + const handleEvent = (e2) => { + var _a3; + if (e2 instanceof PointerEvent && e2.pointerType === "pen") { + e2.isKilled = true; + const { target } = e2; + if (IGNORED_TAGS.includes((_a3 = target.tagName) == null ? void 0 : _a3.toLocaleLowerCase()) || editor.isIn("select.editing_shape")) { + return; + } + preventDefault(e2); + } + }; + elm.addEventListener("touchstart", handleEvent); + elm.addEventListener("touchend", handleEvent); + return () => { + elm.removeEventListener("touchstart", handleEvent); + elm.removeEventListener("touchend", handleEvent); + }; + }, [editor, ref]); +} +function clamp$2(v2, min2, max2) { + return Math.max(min2, Math.min(v2, max2)); +} +const V = { + toVector(v2, fallback) { + if (v2 === void 0) v2 = fallback; + return Array.isArray(v2) ? v2 : [v2, v2]; + }, + add(v1, v2) { + return [v1[0] + v2[0], v1[1] + v2[1]]; + }, + sub(v1, v2) { + return [v1[0] - v2[0], v1[1] - v2[1]]; + }, + addTo(v1, v2) { + v1[0] += v2[0]; + v1[1] += v2[1]; + }, + subTo(v1, v2) { + v1[0] -= v2[0]; + v1[1] -= v2[1]; } - static isAnimatedImageType(mimeType) { - return DEFAULT_SUPPORTED_ANIMATED_IMAGE_TYPES.includes(mimeType || ""); +}; +function rubberband(distance, dimension, constant) { + if (dimension === 0 || Math.abs(dimension) === Infinity) return Math.pow(distance, constant * 5); + return distance * dimension * constant / (dimension + constant * distance); +} +function rubberbandIfOutOfBounds(position, min2, max2, constant = 0.15) { + if (constant === 0) return clamp$2(position, min2, max2); + if (position < min2) return -rubberband(min2 - position, max2 - min2, constant) + min2; + if (position > max2) return +rubberband(position - max2, max2 - min2, constant) + max2; + return position; +} +function computeRubberband(bounds, [Vx, Vy], [Rx, Ry]) { + const [[X0, X1], [Y0, Y1]] = bounds; + return [rubberbandIfOutOfBounds(Vx, X0, X1, Rx), rubberbandIfOutOfBounds(Vy, Y0, Y1, Ry)]; +} +function _toPrimitive$1(input, hint) { + if (typeof input !== "object" || input === null) return input; + var prim = input[Symbol.toPrimitive]; + if (prim !== void 0) { + var res = prim.call(input, hint || "default"); + if (typeof res !== "object") return res; + throw new TypeError("@@toPrimitive must return a primitive value."); } - static isStaticImageType(mimeType) { - return DEFAULT_SUPPORTED_STATIC_IMAGE_TYPES.includes(mimeType || ""); + return (hint === "string" ? String : Number)(input); +} +function _toPropertyKey$1(arg) { + var key = _toPrimitive$1(arg, "string"); + return typeof key === "symbol" ? key : String(key); +} +function _defineProperty$1(obj, key, value) { + key = _toPropertyKey$1(key); + if (key in obj) { + Object.defineProperty(obj, key, { + value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; } - static isVectorImageType(mimeType) { - return DEFAULT_SUPPORTED_VECTOR_IMAGE_TYPES.includes(mimeType || ""); + return obj; +} +function ownKeys$1(e2, r) { + var t2 = Object.keys(e2); + if (Object.getOwnPropertySymbols) { + var o2 = Object.getOwnPropertySymbols(e2); + r && (o2 = o2.filter(function(r2) { + return Object.getOwnPropertyDescriptor(e2, r2).enumerable; + })), t2.push.apply(t2, o2); } - static isImageType(mimeType) { - return DEFAULT_SUPPORTED_IMAGE_TYPES.includes(mimeType); + return t2; +} +function _objectSpread2$1(e2) { + for (var r = 1; r < arguments.length; r++) { + var t2 = null != arguments[r] ? arguments[r] : {}; + r % 2 ? ownKeys$1(Object(t2), true).forEach(function(r2) { + _defineProperty$1(e2, r2, t2[r2]); + }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e2, Object.getOwnPropertyDescriptors(t2)) : ownKeys$1(Object(t2)).forEach(function(r2) { + Object.defineProperty(e2, r2, Object.getOwnPropertyDescriptor(t2, r2)); + }); } - static async usingObjectURL(blob, fn) { - const url = URL.createObjectURL(blob); - try { - return await fn(url); - } finally { - URL.revokeObjectURL(url); - } + return e2; +} +const EVENT_TYPE_MAP = { + pointer: { + start: "down", + change: "move", + end: "up" + }, + mouse: { + start: "down", + change: "move", + end: "up" + }, + touch: { + start: "start", + change: "move", + end: "end" + }, + gesture: { + start: "start", + change: "change", + end: "end" } +}; +function capitalize(string2) { + if (!string2) return ""; + return string2[0].toUpperCase() + string2.slice(1); } -function lerp(a2, b2, t2) { - return a2 + (b2 - a2) * t2; +const actionsWithoutCaptureSupported = ["enter", "leave"]; +function hasCapture(capture = false, actionKey) { + return capture && !actionsWithoutCaptureSupported.includes(actionKey); } -function rng(seed = "") { - let x2 = 0; - let y2 = 0; - let z2 = 0; - let w2 = 0; - function next() { - const t2 = x2 ^ x2 << 11; - x2 = y2; - y2 = z2; - z2 = w2; - w2 ^= (w2 >>> 19 ^ t2 ^ t2 >>> 8) >>> 0; - return w2 / 4294967296 * 2; - } - for (let k2 = 0; k2 < seed.length + 64; k2++) { - x2 ^= seed.charCodeAt(k2) | 0; - next(); - } - return next; +function toHandlerProp(device, action = "", capture = false) { + const deviceProps = EVENT_TYPE_MAP[device]; + const actionKey = deviceProps ? deviceProps[action] || action : action; + return "on" + capitalize(device) + capitalize(actionKey) + (hasCapture(capture, actionKey) ? "Capture" : ""); +} +const pointerCaptureEvents = ["gotpointercapture", "lostpointercapture"]; +function parseProp(prop) { + let eventKey = prop.substring(2).toLowerCase(); + const passive = !!~eventKey.indexOf("passive"); + if (passive) eventKey = eventKey.replace("passive", ""); + const captureKey = pointerCaptureEvents.includes(eventKey) ? "capturecapture" : "capture"; + const capture = !!~eventKey.indexOf(captureKey); + if (capture) eventKey = eventKey.replace("capture", ""); + return { + device: eventKey, + capture, + passive + }; } -function modulate(value, rangeA, rangeB, clamp2 = false) { - const [fromLow, fromHigh] = rangeA; - const [v0, v1] = rangeB; - const result = v0 + (value - fromLow) / (fromHigh - fromLow) * (v1 - v0); - return clamp2 ? v0 < v1 ? Math.max(Math.min(result, v1), v0) : Math.max(Math.min(result, v0), v1) : result; +function toDomEventType(device, action = "") { + const deviceProps = EVENT_TYPE_MAP[device]; + const actionKey = deviceProps ? deviceProps[action] || action : action; + return device + actionKey; } -function hasOwnProperty$1(obj, key) { - return Object.prototype.hasOwnProperty.call(obj, key); +function isTouch(event) { + return "touches" in event; } -function getOwnProperty(obj, key) { - if (!hasOwnProperty$1(obj, key)) { - return void 0; - } - return obj[key]; +function getPointerType(event) { + if (isTouch(event)) return "touch"; + if ("pointerType" in event) return event.pointerType; + return "mouse"; } -function objectMapKeys(object2) { - return Object.keys(object2); +function getCurrentTargetTouchList(event) { + return Array.from(event.touches).filter((e2) => { + var _event$currentTarget, _event$currentTarget$; + return e2.target === event.currentTarget || ((_event$currentTarget = event.currentTarget) === null || _event$currentTarget === void 0 || (_event$currentTarget$ = _event$currentTarget.contains) === null || _event$currentTarget$ === void 0 ? void 0 : _event$currentTarget$.call(_event$currentTarget, e2.target)); + }); } -function objectMapValues(object2) { - return Object.values(object2); +function distanceAngle(P1, P2) { + try { + const dx = P2.clientX - P1.clientX; + const dy = P2.clientY - P1.clientY; + const cx = (P2.clientX + P1.clientX) / 2; + const cy = (P2.clientY + P1.clientY) / 2; + const distance = Math.hypot(dx, dy); + const angle = -(Math.atan2(dx, dy) * 180) / Math.PI; + const origin = [cx, cy]; + return { + angle, + distance, + origin + }; + } catch (_unused) { + } + return null; } -function objectMapEntries(object2) { - return Object.entries(object2); +function touchIds(event) { + return getCurrentTargetTouchList(event).map((touch) => touch.identifier); } -function objectMapFromEntries(entries) { - return Object.fromEntries(entries); +function touchDistanceAngle(event, ids) { + const [P1, P2] = Array.from(event.touches).filter((touch) => ids.includes(touch.identifier)); + return distanceAngle(P1, P2); } -function filterEntries(object2, predicate) { - const result = {}; - let didChange = false; - for (const [key, value] of objectMapEntries(object2)) { - if (predicate(key, value)) { - result[key] = value; - } else { - didChange = true; - } +const LINE_HEIGHT = 40; +const PAGE_HEIGHT = 800; +function wheelValues(event) { + let { + deltaX, + deltaY, + deltaMode + } = event; + if (deltaMode === 1) { + deltaX *= LINE_HEIGHT; + deltaY *= LINE_HEIGHT; + } else if (deltaMode === 2) { + deltaX *= PAGE_HEIGHT; + deltaY *= PAGE_HEIGHT; } - return didChange ? result : object2; + return [deltaX, deltaY]; } -function mapObjectMapValues(object2, mapper) { - const result = {}; - for (const [key, value] of objectMapEntries(object2)) { - const newValue = mapper(key, value); - result[key] = newValue; +function getEventDetails(event) { + const payload = {}; + if ("buttons" in event) payload.buttons = event.buttons; + if ("shiftKey" in event) { + const { + shiftKey, + altKey: altKey2, + metaKey, + ctrlKey + } = event; + Object.assign(payload, { + shiftKey, + altKey: altKey2, + metaKey, + ctrlKey + }); } - return result; + return payload; } -function areObjectsShallowEqual(obj1, obj2) { - if (obj1 === obj2) return true; - const keys1 = new Set(Object.keys(obj1)); - const keys22 = new Set(Object.keys(obj2)); - if (keys1.size !== keys22.size) return false; - for (const key of keys1) { - if (!keys22.has(key)) return false; - if (!Object.is(obj1[key], obj2[key])) return false; +function call(v2, ...args) { + if (typeof v2 === "function") { + return v2(...args); + } else { + return v2; } - return true; } -function indexCharacterSet(options) { - const dicts = createCharSetDicts(options.chars); - const limits = integerLimits( - dicts, - options.firstPositive, - options.mostPositive, - options.mostNegative - ); - const jitterRange = options.jitterRange ?? Math.floor(Math.pow(dicts.length, 3) / 5); - const paddingRange = paddingDict(jitterRange, dicts.length); - return { - chars: options.chars, - byChar: dicts.byChar, - byCode: dicts.byCode, - length: dicts.length, - first: dicts.byCode[0], - last: dicts.byCode[dicts.length - 1], - firstPositive: limits.firstPositive, - mostPositive: limits.mostPositive, - firstNegative: limits.firstNegative, - mostNegative: limits.mostNegative, - jitterRange, - paddingDict: paddingRange - }; +function noop() { } -function createCharSetDicts(charSet) { - const byCode = {}; - const byChar = {}; - const length = charSet.length; - for (let i2 = 0; i2 < length; i2++) { - const char = charSet[i2]; - byCode[i2] = char; - byChar[char] = i2; - } - return { - byCode, - byChar, - length +function chain(...fns) { + if (fns.length === 0) return noop; + if (fns.length === 1) return fns[0]; + return function() { + let result; + for (const fn of fns) { + result = fn.apply(this, arguments) || result; + } + return result; }; } -function integerLimits(dicts, firstPositive, mostPositive, mostNegative) { - const firstPositiveIndex = firstPositive ? dicts.byChar[firstPositive] : Math.ceil(dicts.length / 2); - const mostPositiveIndex = mostPositive ? dicts.byChar[mostPositive] : dicts.length - 1; - const mostNegativeIndex = mostNegative ? dicts.byChar[mostNegative] : 0; - if (firstPositiveIndex === void 0 || mostPositiveIndex === void 0 || mostNegativeIndex === void 0) { - throw new Error("invalid charSet"); +function assignDefault(value, fallback) { + return Object.assign({}, fallback, value || {}); +} +const BEFORE_LAST_KINEMATICS_DELAY = 32; +class Engine { + constructor(ctrl, args, key) { + this.ctrl = ctrl; + this.args = args; + this.key = key; + if (!this.state) { + this.state = {}; + this.computeValues([0, 0]); + this.computeInitial(); + if (this.init) this.init(); + this.reset(); + } } - if (mostPositiveIndex - firstPositiveIndex < 3) { - throw new Error( - "mostPositive must be at least 3 characters away from neutral" - ); + get state() { + return this.ctrl.state[this.key]; } - if (firstPositiveIndex - mostNegativeIndex < 3) { - throw new Error( - "mostNegative must be at least 3 characters away from neutral" - ); + set state(state) { + this.ctrl.state[this.key] = state; } - return { - firstPositive: dicts.byCode[firstPositiveIndex], - mostPositive: dicts.byCode[mostPositiveIndex], - firstNegative: dicts.byCode[firstPositiveIndex - 1], - mostNegative: dicts.byCode[mostNegativeIndex] - }; -} -function paddingDict(jitterRange, charSetLength) { - const paddingDict2 = {}; - for (let i2 = 0; i2 < 100; i2++) { - paddingDict2[i2] = Math.pow(charSetLength, i2); - if (paddingDict2[i2] > jitterRange) { - break; + get shared() { + return this.ctrl.state.shared; + } + get eventStore() { + return this.ctrl.gestureEventStores[this.key]; + } + get timeoutStore() { + return this.ctrl.gestureTimeoutStores[this.key]; + } + get config() { + return this.ctrl.config[this.key]; + } + get sharedConfig() { + return this.ctrl.config.shared; + } + get handler() { + return this.ctrl.handlers[this.key]; + } + reset() { + const { + state, + shared: shared2, + ingKey, + args + } = this; + shared2[ingKey] = state._active = state.active = state._blocked = state._force = false; + state._step = [false, false]; + state.intentional = false; + state._movement = [0, 0]; + state._distance = [0, 0]; + state._direction = [0, 0]; + state._delta = [0, 0]; + state._bounds = [[-Infinity, Infinity], [-Infinity, Infinity]]; + state.args = args; + state.axis = void 0; + state.memo = void 0; + state.elapsedTime = state.timeDelta = 0; + state.direction = [0, 0]; + state.distance = [0, 0]; + state.overflow = [0, 0]; + state._movementBound = [false, false]; + state.velocity = [0, 0]; + state.movement = [0, 0]; + state.delta = [0, 0]; + state.timeStamp = 0; + } + start(event) { + const state = this.state; + const config = this.config; + if (!state._active) { + this.reset(); + this.computeInitial(); + state._active = true; + state.target = event.target; + state.currentTarget = event.currentTarget; + state.lastOffset = config.from ? call(config.from, state) : state.offset; + state.offset = state.lastOffset; + state.startTime = state.timeStamp = event.timeStamp; } } - return paddingDict2; -} -var _base62CharSet = null; -function base62CharSet() { - if (_base62CharSet) - return _base62CharSet; - return _base62CharSet = indexCharacterSet({ - // Base62 are all the alphanumeric characters, database and user friendly - // For shorter strings and more room you could opt for more characters - chars: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", - // This gives us nice human readable keys to start with a0 a1 etc - firstPositive: "a", - mostPositive: "z", - mostNegative: "A" - }); -} -function distanceBetween(a2, b2, charSet) { - const indexA = charSet.byChar[a2]; - const indexB = charSet.byChar[b2]; - return Math.abs(indexA - indexB); -} -function integerLength(head, charSet) { - const firstChar = head[0]; - if (firstChar > charSet.mostPositive || firstChar < charSet.mostNegative) { - throw new Error("invalid firstChar on key"); + computeValues(values) { + const state = this.state; + state._values = values; + state.values = this.config.transform(values); } - if (firstChar === charSet.mostPositive) { - const firstLevel = distanceBetween(firstChar, charSet.firstPositive, charSet) + 1; - return firstLevel + integerLengthFromSecondLevel(head.slice(1), "positive", charSet); + computeInitial() { + const state = this.state; + state._initial = state._values; + state.initial = state.values; } - if (firstChar === charSet.mostNegative) { - const firstLevel = distanceBetween(firstChar, charSet.firstNegative, charSet) + 1; - return firstLevel + integerLengthFromSecondLevel(head.slice(1), "negative", charSet); + compute(event) { + const { + state, + config, + shared: shared2 + } = this; + state.args = this.args; + let dt = 0; + if (event) { + state.event = event; + if (config.preventDefault && event.cancelable) state.event.preventDefault(); + state.type = event.type; + shared2.touches = this.ctrl.pointerIds.size || this.ctrl.touchIds.size; + shared2.locked = !!document.pointerLockElement; + Object.assign(shared2, getEventDetails(event)); + shared2.down = shared2.pressed = shared2.buttons % 2 === 1 || shared2.touches > 0; + dt = event.timeStamp - state.timeStamp; + state.timeStamp = event.timeStamp; + state.elapsedTime = state.timeStamp - state.startTime; + } + if (state._active) { + const _absoluteDelta = state._delta.map(Math.abs); + V.addTo(state._distance, _absoluteDelta); + } + if (this.axisIntent) this.axisIntent(event); + const [_m0, _m1] = state._movement; + const [t0, t1] = config.threshold; + const { + _step, + values + } = state; + if (config.hasCustomTransform) { + if (_step[0] === false) _step[0] = Math.abs(_m0) >= t0 && values[0]; + if (_step[1] === false) _step[1] = Math.abs(_m1) >= t1 && values[1]; + } else { + if (_step[0] === false) _step[0] = Math.abs(_m0) >= t0 && Math.sign(_m0) * t0; + if (_step[1] === false) _step[1] = Math.abs(_m1) >= t1 && Math.sign(_m1) * t1; + } + state.intentional = _step[0] !== false || _step[1] !== false; + if (!state.intentional) return; + const movement = [0, 0]; + if (config.hasCustomTransform) { + const [v0, v1] = values; + movement[0] = _step[0] !== false ? v0 - _step[0] : 0; + movement[1] = _step[1] !== false ? v1 - _step[1] : 0; + } else { + movement[0] = _step[0] !== false ? _m0 - _step[0] : 0; + movement[1] = _step[1] !== false ? _m1 - _step[1] : 0; + } + if (this.restrictToAxis && !state._blocked) this.restrictToAxis(movement); + const previousOffset = state.offset; + const gestureIsActive = state._active && !state._blocked || state.active; + if (gestureIsActive) { + state.first = state._active && !state.active; + state.last = !state._active && state.active; + state.active = shared2[this.ingKey] = state._active; + if (event) { + if (state.first) { + if ("bounds" in config) state._bounds = call(config.bounds, state); + if (this.setup) this.setup(); + } + state.movement = movement; + this.computeOffset(); + } + } + const [ox, oy] = state.offset; + const [[x0, x1], [y0, y1]] = state._bounds; + state.overflow = [ox < x0 ? -1 : ox > x1 ? 1 : 0, oy < y0 ? -1 : oy > y1 ? 1 : 0]; + state._movementBound[0] = state.overflow[0] ? state._movementBound[0] === false ? state._movement[0] : state._movementBound[0] : false; + state._movementBound[1] = state.overflow[1] ? state._movementBound[1] === false ? state._movement[1] : state._movementBound[1] : false; + const rubberband2 = state._active ? config.rubberband || [0, 0] : [0, 0]; + state.offset = computeRubberband(state._bounds, state.offset, rubberband2); + state.delta = V.sub(state.offset, previousOffset); + this.computeMovement(); + if (gestureIsActive && (!state.last || dt > BEFORE_LAST_KINEMATICS_DELAY)) { + state.delta = V.sub(state.offset, previousOffset); + const absoluteDelta = state.delta.map(Math.abs); + V.addTo(state.distance, absoluteDelta); + state.direction = state.delta.map(Math.sign); + state._direction = state._delta.map(Math.sign); + if (!state.first && dt > 0) { + state.velocity = [absoluteDelta[0] / dt, absoluteDelta[1] / dt]; + state.timeDelta = dt; + } + } } - const isPositiveRange = firstChar >= charSet.firstPositive; - if (isPositiveRange) { - return distanceBetween(firstChar, charSet.firstPositive, charSet) + 2; - } else { - return distanceBetween(firstChar, charSet.firstNegative, charSet) + 2; + emit() { + const state = this.state; + const shared2 = this.shared; + const config = this.config; + if (!state._active) this.clean(); + if ((state._blocked || !state.intentional) && !state._force && !config.triggerAllEvents) return; + const memo2 = this.handler(_objectSpread2$1(_objectSpread2$1(_objectSpread2$1({}, shared2), state), {}, { + [this.aliasKey]: state.values + })); + if (memo2 !== void 0) state.memo = memo2; + } + clean() { + this.eventStore.clean(); + this.timeoutStore.clean(); } } -function integerLengthFromSecondLevel(key, direction, charSet) { - const firstChar = key[0]; - if (firstChar > charSet.mostPositive || firstChar < charSet.mostNegative) { - throw new Error("invalid firstChar on key"); +function selectAxis([dx, dy], threshold) { + const absDx = Math.abs(dx); + const absDy = Math.abs(dy); + if (absDx > absDy && absDx > threshold) { + return "x"; } - if (firstChar === charSet.mostPositive && direction === "positive") { - const totalPositiveRoom = distanceBetween(firstChar, charSet.mostNegative, charSet) + 1; - return totalPositiveRoom + integerLengthFromSecondLevel(key.slice(1), direction, charSet); + if (absDy > absDx && absDy > threshold) { + return "y"; } - if (firstChar === charSet.mostNegative && direction === "negative") { - const totalNegativeRoom = distanceBetween(firstChar, charSet.mostPositive, charSet) + 1; - return totalNegativeRoom + integerLengthFromSecondLevel(key.slice(1), direction, charSet); + return void 0; +} +class CoordinatesEngine extends Engine { + constructor(...args) { + super(...args); + _defineProperty$1(this, "aliasKey", "xy"); } - if (direction === "positive") { - return distanceBetween(firstChar, charSet.mostNegative, charSet) + 2; - } else { - return distanceBetween(firstChar, charSet.mostPositive, charSet) + 2; + reset() { + super.reset(); + this.state.axis = void 0; + } + init() { + this.state.offset = [0, 0]; + this.state.lastOffset = [0, 0]; + } + computeOffset() { + this.state.offset = V.add(this.state.lastOffset, this.state.movement); + } + computeMovement() { + this.state.movement = V.sub(this.state.offset, this.state.lastOffset); + } + axisIntent(event) { + const state = this.state; + const config = this.config; + if (!state.axis && event) { + const threshold = typeof config.axisThreshold === "object" ? config.axisThreshold[getPointerType(event)] : config.axisThreshold; + state.axis = selectAxis(state._movement, threshold); + } + state._blocked = (config.lockDirection || !!config.axis) && !state.axis || !!config.axis && config.axis !== state.axis; + } + restrictToAxis(v2) { + if (this.config.axis || this.config.lockDirection) { + switch (this.state.axis) { + case "x": + v2[1] = 0; + break; + case "y": + v2[0] = 0; + break; + } + } } } -function makeSameLength(a2, b2, pad, fillChar, forceLength) { - const max2 = Math.max(a2.length, b2.length); - if (pad === "start") { - return [a2.padStart(max2, fillChar), b2.padStart(max2, fillChar)]; +const identity = (v2) => v2; +const DEFAULT_RUBBERBAND = 0.15; +const commonConfigResolver = { + enabled(value = true) { + return value; + }, + eventOptions(value, _k2, config) { + return _objectSpread2$1(_objectSpread2$1({}, config.shared.eventOptions), value); + }, + preventDefault(value = false) { + return value; + }, + triggerAllEvents(value = false) { + return value; + }, + rubberband(value = 0) { + switch (value) { + case true: + return [DEFAULT_RUBBERBAND, DEFAULT_RUBBERBAND]; + case false: + return [0, 0]; + default: + return V.toVector(value); + } + }, + from(value) { + if (typeof value === "function") return value; + if (value != null) return V.toVector(value); + }, + transform(value, _k2, config) { + const transform = value || config.shared.transform; + this.hasCustomTransform = !!transform; + { + const originalTransform = transform || identity; + return (v2) => { + const r = originalTransform(v2); + if (!isFinite(r[0]) || !isFinite(r[1])) { + console.warn(`[@use-gesture]: config.transform() must produce a valid result, but it was: [${r[0]},${[1]}]`); + } + return r; + }; + } + }, + threshold(value) { + return V.toVector(value, 0); } - return [a2.padEnd(max2, fillChar), b2.padEnd(max2, fillChar)]; +}; +{ + Object.assign(commonConfigResolver, { + domTarget(value) { + if (value !== void 0) { + throw Error(`[@use-gesture]: \`domTarget\` option has been renamed to \`target\`.`); + } + return NaN; + }, + lockDirection(value) { + if (value !== void 0) { + throw Error(`[@use-gesture]: \`lockDirection\` option has been merged with \`axis\`. Use it as in \`{ axis: 'lock' }\``); + } + return NaN; + }, + initial(value) { + if (value !== void 0) { + throw Error(`[@use-gesture]: \`initial\` option has been renamed to \`from\`.`); + } + return NaN; + } + }); } -function midPoint(lower, upper, charSet) { - let [paddedLower, paddedUpper] = makeSameLength( - lower, - upper, - "end", - charSet.first - ); - let distance = lexicalDistance(paddedLower, paddedUpper, charSet); - if (distance === 1) { - paddedLower = paddedLower.padEnd(paddedLower.length + 1, charSet.first); - distance = charSet.length; +const DEFAULT_AXIS_THRESHOLD = 0; +const coordinatesConfigResolver = _objectSpread2$1(_objectSpread2$1({}, commonConfigResolver), {}, { + axis(_v, _k2, { + axis + }) { + this.lockDirection = axis === "lock"; + if (!this.lockDirection) return axis; + }, + axisThreshold(value = DEFAULT_AXIS_THRESHOLD) { + return value; + }, + bounds(value = {}) { + if (typeof value === "function") { + return (state) => coordinatesConfigResolver.bounds(value(state)); + } + if ("current" in value) { + return () => value.current; + } + if (typeof HTMLElement === "function" && value instanceof HTMLElement) { + return value; + } + const { + left = -Infinity, + right = Infinity, + top = -Infinity, + bottom = Infinity + } = value; + return [[left, right], [top, bottom]]; } - const mid = encodeToCharSet(Math.floor(distance / 2), charSet); - return addCharSetKeys(paddedLower, mid, charSet); +}); +const isBrowser = typeof window !== "undefined" && window.document && window.document.createElement; +function supportsTouchEvents() { + return isBrowser && "ontouchstart" in window; } -function lexicalDistance(a2, b2, charSet) { - const [lower, upper] = makeSameLength(a2, b2, "end", charSet.first).sort(); - const distance = subtractCharSetKeys(upper, lower, charSet); - return decodeCharSetToNumber(distance, charSet); +function isTouchScreen() { + return supportsTouchEvents() || isBrowser && window.navigator.maxTouchPoints > 1; } -function addCharSetKeys(a2, b2, charSet) { - const base = charSet.length; - const [paddedA, paddedB] = makeSameLength(a2, b2, "start", charSet.first); - const result = []; - let carry = 0; - for (let i2 = paddedA.length - 1; i2 >= 0; i2--) { - const digitA = charSet.byChar[paddedA[i2]]; - const digitB = charSet.byChar[paddedB[i2]]; - const sum = digitA + digitB + carry; - carry = Math.floor(sum / base); - const remainder = sum % base; - result.unshift(charSet.byCode[remainder]); - } - if (carry > 0) { - result.unshift(charSet.byCode[carry]); +function supportsPointerEvents() { + return isBrowser && "onpointerdown" in window; +} +function supportsPointerLock() { + return isBrowser && "exitPointerLock" in window.document; +} +function supportsGestureEvents() { + try { + return "constructor" in GestureEvent; + } catch (e2) { + return false; } - return result.join(""); } -function subtractCharSetKeys(a2, b2, charSet) { - const base = charSet.length; - const [paddedA, paddedB] = makeSameLength(a2, b2, "start", charSet.first); - const result = []; - let borrow = 0; - for (let i2 = paddedA.length - 1; i2 >= 0; i2--) { - let digitA = charSet.byChar[paddedA[i2]]; - const digitB = charSet.byChar[paddedB[i2]] + borrow; - if (digitA < digitB) { - borrow = 1; - digitA += base; - } else { - borrow = 0; +const SUPPORT = { + isBrowser, + gesture: supportsGestureEvents(), + touch: supportsTouchEvents(), + touchscreen: isTouchScreen(), + pointer: supportsPointerEvents(), + pointerLock: supportsPointerLock() +}; +const DEFAULT_PREVENT_SCROLL_DELAY = 250; +const DEFAULT_DRAG_DELAY = 180; +const DEFAULT_SWIPE_VELOCITY = 0.5; +const DEFAULT_SWIPE_DISTANCE = 50; +const DEFAULT_SWIPE_DURATION = 250; +const DEFAULT_KEYBOARD_DISPLACEMENT = 10; +const DEFAULT_DRAG_AXIS_THRESHOLD = { + mouse: 0, + touch: 0, + pen: 8 +}; +const dragConfigResolver = _objectSpread2$1(_objectSpread2$1({}, coordinatesConfigResolver), {}, { + device(_v, _k2, { + pointer: { + touch = false, + lock = false, + mouse = false + } = {} + }) { + this.pointerLock = lock && SUPPORT.pointerLock; + if (SUPPORT.touch && touch) return "touch"; + if (this.pointerLock) return "mouse"; + if (SUPPORT.pointer && !mouse) return "pointer"; + if (SUPPORT.touch) return "touch"; + return "mouse"; + }, + preventScrollAxis(value, _k2, { + preventScroll + }) { + this.preventScrollDelay = typeof preventScroll === "number" ? preventScroll : preventScroll || preventScroll === void 0 && value ? DEFAULT_PREVENT_SCROLL_DELAY : void 0; + if (!SUPPORT.touchscreen || preventScroll === false) return void 0; + return value ? value : preventScroll !== void 0 ? "y" : void 0; + }, + pointerCapture(_v, _k2, { + pointer: { + capture = true, + buttons = 1, + keys: keys3 = true + } = {} + }) { + this.pointerButtons = buttons; + this.keys = keys3; + return !this.pointerLock && this.device === "pointer" && capture; + }, + threshold(value, _k2, { + filterTaps = false, + tapsThreshold = 3, + axis = void 0 + }) { + const threshold = V.toVector(value, filterTaps ? tapsThreshold : axis ? 1 : 0); + this.filterTaps = filterTaps; + this.tapsThreshold = tapsThreshold; + return threshold; + }, + swipe({ + velocity = DEFAULT_SWIPE_VELOCITY, + distance = DEFAULT_SWIPE_DISTANCE, + duration = DEFAULT_SWIPE_DURATION + } = {}) { + return { + velocity: this.transform(V.toVector(velocity)), + distance: this.transform(V.toVector(distance)), + duration + }; + }, + delay(value = 0) { + switch (value) { + case true: + return DEFAULT_DRAG_DELAY; + case false: + return 0; + default: + return value; } - const difference = digitA - digitB; - result.unshift(charSet.byCode[difference]); + }, + axisThreshold(value) { + if (!value) return DEFAULT_DRAG_AXIS_THRESHOLD; + return _objectSpread2$1(_objectSpread2$1({}, DEFAULT_DRAG_AXIS_THRESHOLD), value); + }, + keyboardDisplacement(value = DEFAULT_KEYBOARD_DISPLACEMENT) { + return value; } - if (borrow > 0) { - throw new Error( - "Subtraction result is negative. Ensure a is greater than or equal to b." - ); +}); +{ + Object.assign(dragConfigResolver, { + useTouch(value) { + if (value !== void 0) { + throw Error(`[@use-gesture]: \`useTouch\` option has been renamed to \`pointer.touch\`. Use it as in \`{ pointer: { touch: true } }\`.`); + } + return NaN; + }, + experimental_preventWindowScrollY(value) { + if (value !== void 0) { + throw Error(`[@use-gesture]: \`experimental_preventWindowScrollY\` option has been renamed to \`preventScroll\`.`); + } + return NaN; + }, + swipeVelocity(value) { + if (value !== void 0) { + throw Error(`[@use-gesture]: \`swipeVelocity\` option has been renamed to \`swipe.velocity\`. Use it as in \`{ swipe: { velocity: 0.5 } }\`.`); + } + return NaN; + }, + swipeDistance(value) { + if (value !== void 0) { + throw Error(`[@use-gesture]: \`swipeDistance\` option has been renamed to \`swipe.distance\`. Use it as in \`{ swipe: { distance: 50 } }\`.`); + } + return NaN; + }, + swipeDuration(value) { + if (value !== void 0) { + throw Error(`[@use-gesture]: \`swipeDuration\` option has been renamed to \`swipe.duration\`. Use it as in \`{ swipe: { duration: 250 } }\`.`); + } + return NaN; + } + }); +} +function clampStateInternalMovementToBounds(state) { + const [ox, oy] = state.overflow; + const [dx, dy] = state._delta; + const [dirx, diry] = state._direction; + if (ox < 0 && dx > 0 && dirx < 0 || ox > 0 && dx < 0 && dirx > 0) { + state._movement[0] = state._movementBound[0]; } - while (result.length > 1 && result[0] === charSet.byCode[0]) { - result.shift(); + if (oy < 0 && dy > 0 && diry < 0 || oy > 0 && dy < 0 && diry > 0) { + state._movement[1] = state._movementBound[1]; } - return result.join(""); -} -function incrementKey(key, charSet) { - return addCharSetKeys(key, charSet.byCode[1], charSet); } -function decrementKey(key, charSet) { - return subtractCharSetKeys(key, charSet.byCode[1], charSet); -} -function encodeToCharSet(int, charSet) { - if (int === 0) { - return charSet.byCode[0]; +const SCALE_ANGLE_RATIO_INTENT_DEG = 30; +const PINCH_WHEEL_RATIO = 100; +class PinchEngine extends Engine { + constructor(...args) { + super(...args); + _defineProperty$1(this, "ingKey", "pinching"); + _defineProperty$1(this, "aliasKey", "da"); } - let res = ""; - const max2 = charSet.length; - while (int > 0) { - res = charSet.byCode[int % max2] + res; - int = Math.floor(int / max2); + init() { + this.state.offset = [1, 0]; + this.state.lastOffset = [1, 0]; + this.state._pointerEvents = /* @__PURE__ */ new Map(); } - return res; -} -function decodeCharSetToNumber(key, charSet) { - let res = 0; - const length = key.length; - const max2 = charSet.length; - for (let i2 = 0; i2 < length; i2++) { - res += charSet.byChar[key[i2]] * Math.pow(max2, length - i2 - 1); + reset() { + super.reset(); + const state = this.state; + state._touchIds = []; + state.canceled = false; + state.cancel = this.cancel.bind(this); + state.turns = 0; } - return res; -} -function startKey(charSet) { - return charSet.firstPositive + charSet.byCode[0]; -} -function validInteger(integer2, charSet) { - const length = integerLength(integer2, charSet); - return length === integer2.length; -} -function validateOrderKey(orderKey, charSet) { - getIntegerPart(orderKey, charSet); -} -function getIntegerPart(orderKey, charSet) { - const head = integerHead(orderKey, charSet); - const integerPartLength = integerLength(head, charSet); - if (integerPartLength > orderKey.length) { - throw new Error("invalid order key length: " + orderKey); + computeOffset() { + const { + type, + movement, + lastOffset + } = this.state; + if (type === "wheel") { + this.state.offset = V.add(movement, lastOffset); + } else { + this.state.offset = [(1 + movement[0]) * lastOffset[0], movement[1] + lastOffset[1]]; + } } - return orderKey.slice(0, integerPartLength); -} -function validateInteger(integer2, charSet) { - if (!validInteger(integer2, charSet)) { - throw new Error("invalid integer length: " + integer2); + computeMovement() { + const { + offset: offset2, + lastOffset + } = this.state; + this.state.movement = [offset2[0] / lastOffset[0], offset2[1] - lastOffset[1]]; } -} -function incrementInteger(integer2, charSet) { - validateInteger(integer2, charSet); - const [head, digs] = splitInteger(integer2, charSet); - const anyNonMaxedDigit = digs.split("").some((d2) => d2 !== charSet.byCode[charSet.length - 1]); - if (anyNonMaxedDigit) { - const newDigits = incrementKey(digs, charSet); - return head + newDigits; + axisIntent() { + const state = this.state; + const [_m0, _m1] = state._movement; + if (!state.axis) { + const axisMovementDifference = Math.abs(_m0) * SCALE_ANGLE_RATIO_INTENT_DEG - Math.abs(_m1); + if (axisMovementDifference < 0) state.axis = "angle"; + else if (axisMovementDifference > 0) state.axis = "scale"; + } } - const nextHead = incrementIntegerHead(head, charSet); - return startOnNewHead(nextHead, "lower", charSet); -} -function decrementInteger(integer2, charSet) { - validateInteger(integer2, charSet); - const [head, digs] = splitInteger(integer2, charSet); - const anyNonLimitDigit = digs.split("").some((d2) => d2 !== charSet.byCode[0]); - if (anyNonLimitDigit) { - const newDigits = decrementKey(digs, charSet); - return head + newDigits; + restrictToAxis(v2) { + if (this.config.lockDirection) { + if (this.state.axis === "scale") v2[1] = 0; + else if (this.state.axis === "angle") v2[0] = 0; + } } - const nextHead = decrementIntegerHead(head, charSet); - return startOnNewHead(nextHead, "upper", charSet); -} -function integerHead(integer2, charSet) { - let i2 = 0; - if (integer2[0] === charSet.mostPositive) { - while (integer2[i2] === charSet.mostPositive) { - i2 = i2 + 1; + cancel() { + const state = this.state; + if (state.canceled) return; + setTimeout(() => { + state.canceled = true; + state._active = false; + this.compute(); + this.emit(); + }, 0); + } + touchStart(event) { + this.ctrl.setEventIds(event); + const state = this.state; + const ctrlTouchIds = this.ctrl.touchIds; + if (state._active) { + if (state._touchIds.every((id2) => ctrlTouchIds.has(id2))) return; } + if (ctrlTouchIds.size < 2) return; + this.start(event); + state._touchIds = Array.from(ctrlTouchIds).slice(0, 2); + const payload = touchDistanceAngle(event, state._touchIds); + if (!payload) return; + this.pinchStart(event, payload); } - if (integer2[0] === charSet.mostNegative) { - while (integer2[i2] === charSet.mostNegative) { - i2 = i2 + 1; + pointerStart(event) { + if (event.buttons != null && event.buttons % 2 !== 1) return; + this.ctrl.setEventIds(event); + event.target.setPointerCapture(event.pointerId); + const state = this.state; + const _pointerEvents = state._pointerEvents; + const ctrlPointerIds = this.ctrl.pointerIds; + if (state._active) { + if (Array.from(_pointerEvents.keys()).every((id2) => ctrlPointerIds.has(id2))) return; } + if (_pointerEvents.size < 2) { + _pointerEvents.set(event.pointerId, event); + } + if (state._pointerEvents.size < 2) return; + this.start(event); + const payload = distanceAngle(...Array.from(_pointerEvents.values())); + if (!payload) return; + this.pinchStart(event, payload); } - return integer2.slice(0, i2 + 1); -} -function splitInteger(integer2, charSet) { - const head = integerHead(integer2, charSet); - const tail = integer2.slice(head.length); - return [head, tail]; -} -function incrementIntegerHead(head, charSet) { - const inPositiveRange = head >= charSet.firstPositive; - const nextHead = incrementKey(head, charSet); - const headIsLimitMax = head[head.length - 1] === charSet.mostPositive; - const nextHeadIsLimitMax = nextHead[nextHead.length - 1] === charSet.mostPositive; - if (inPositiveRange && nextHeadIsLimitMax) { - return nextHead + charSet.mostNegative; + pinchStart(event, payload) { + const state = this.state; + state.origin = payload.origin; + this.computeValues([payload.distance, payload.angle]); + this.computeInitial(); + this.compute(event); + this.emit(); } - if (!inPositiveRange && headIsLimitMax) { - return head.slice(0, head.length - 1); + touchMove(event) { + if (!this.state._active) return; + const payload = touchDistanceAngle(event, this.state._touchIds); + if (!payload) return; + this.pinchMove(event, payload); } - return nextHead; -} -function decrementIntegerHead(head, charSet) { - const inPositiveRange = head >= charSet.firstPositive; - const headIsLimitMin = head[head.length - 1] === charSet.mostNegative; - if (inPositiveRange && headIsLimitMin) { - const nextLevel = head.slice(0, head.length - 1); - return decrementKey(nextLevel, charSet); + pointerMove(event) { + const _pointerEvents = this.state._pointerEvents; + if (_pointerEvents.has(event.pointerId)) { + _pointerEvents.set(event.pointerId, event); + } + if (!this.state._active) return; + const payload = distanceAngle(...Array.from(_pointerEvents.values())); + if (!payload) return; + this.pinchMove(event, payload); } - if (!inPositiveRange && headIsLimitMin) { - return head + charSet.mostPositive; + pinchMove(event, payload) { + const state = this.state; + const prev_a = state._values[1]; + const delta_a = payload.angle - prev_a; + let delta_turns = 0; + if (Math.abs(delta_a) > 270) delta_turns += Math.sign(delta_a); + this.computeValues([payload.distance, payload.angle - 360 * delta_turns]); + state.origin = payload.origin; + state.turns = delta_turns; + state._movement = [state._values[0] / state._initial[0] - 1, state._values[1] - state._initial[1]]; + this.compute(event); + this.emit(); } - return decrementKey(head, charSet); -} -function startOnNewHead(head, limit, charSet) { - const newLength = integerLength(head, charSet); - const fillChar = limit === "upper" ? charSet.byCode[charSet.length - 1] : charSet.byCode[0]; - return head + fillChar.repeat(newLength - head.length); -} -function jitterString(orderKey, charSet) { - const shift2 = encodeToCharSet( - Math.floor(Math.random() * charSet.jitterRange), - charSet - ); - return addCharSetKeys(orderKey, shift2, charSet); -} -function padAndJitterString(orderKey, numberOfChars, charSet) { - const paddedKey = orderKey.padEnd( - orderKey.length + numberOfChars, - charSet.first - ); - return jitterString(paddedKey, charSet); -} -function paddingNeededForJitter(orderKey, b2, charSet) { - const integer2 = getIntegerPart(orderKey, charSet); - const nextInteger = incrementInteger(integer2, charSet); - let needed = 0; - if (b2 !== null) { - const distanceToB = lexicalDistance(orderKey, b2, charSet); - if (distanceToB < charSet.jitterRange + 1) { - needed = Math.max(needed, paddingNeededForDistance(distanceToB, charSet)); + touchEnd(event) { + this.ctrl.setEventIds(event); + if (!this.state._active) return; + if (this.state._touchIds.some((id2) => !this.ctrl.touchIds.has(id2))) { + this.state._active = false; + this.compute(event); + this.emit(); } } - const distanceToNextInteger = lexicalDistance(orderKey, nextInteger, charSet); - if (distanceToNextInteger < charSet.jitterRange + 1) { - needed = Math.max( - needed, - paddingNeededForDistance(distanceToNextInteger, charSet) - ); + pointerEnd(event) { + const state = this.state; + this.ctrl.setEventIds(event); + try { + event.target.releasePointerCapture(event.pointerId); + } catch (_unused) { + } + if (state._pointerEvents.has(event.pointerId)) { + state._pointerEvents.delete(event.pointerId); + } + if (!state._active) return; + if (state._pointerEvents.size < 2) { + state._active = false; + this.compute(event); + this.emit(); + } + } + gestureStart(event) { + if (event.cancelable) event.preventDefault(); + const state = this.state; + if (state._active) return; + this.start(event); + this.computeValues([event.scale, event.rotation]); + state.origin = [event.clientX, event.clientY]; + this.compute(event); + this.emit(); + } + gestureMove(event) { + if (event.cancelable) event.preventDefault(); + if (!this.state._active) return; + const state = this.state; + this.computeValues([event.scale, event.rotation]); + state.origin = [event.clientX, event.clientY]; + const _previousMovement = state._movement; + state._movement = [event.scale - 1, event.rotation]; + state._delta = V.sub(state._movement, _previousMovement); + this.compute(event); + this.emit(); } - return needed; -} -function paddingNeededForDistance(distance, charSet) { - const gap = charSet.jitterRange - distance; - const firstBigger = Object.entries(charSet.paddingDict).find( - ([_key, value]) => { - return value > gap; - } - ); - return firstBigger ? parseInt(firstBigger[0]) : 0; -} -function generateKeyBetween(lower, upper, charSet = base62CharSet()) { - if (lower !== null) { - validateOrderKey(lower, charSet); + gestureEnd(event) { + if (!this.state._active) return; + this.state._active = false; + this.compute(event); + this.emit(); } - if (upper !== null) { - validateOrderKey(upper, charSet); + wheel(event) { + const modifierKey = this.config.modifierKey; + if (modifierKey && (Array.isArray(modifierKey) ? !modifierKey.find((k) => event[k]) : !event[modifierKey])) return; + if (!this.state._active) this.wheelStart(event); + else this.wheelChange(event); + this.timeoutStore.add("wheelEnd", this.wheelEnd.bind(this)); } - if (lower === null && upper === null) { - return startKey(charSet); + wheelStart(event) { + this.start(event); + this.wheelChange(event); } - if (lower === null) { - const integer2 = getIntegerPart(upper, charSet); - return decrementInteger(integer2, charSet); + wheelChange(event) { + const isR3f = "uv" in event; + if (!isR3f) { + if (event.cancelable) { + event.preventDefault(); + } + if (!event.defaultPrevented) { + console.warn(`[@use-gesture]: To properly support zoom on trackpads, try using the \`target\` option. + +This message will only appear in development mode.`); + } + } + const state = this.state; + state._delta = [-wheelValues(event)[1] / PINCH_WHEEL_RATIO * state.offset[0], 0]; + V.addTo(state._movement, state._delta); + clampStateInternalMovementToBounds(state); + this.state.origin = [event.clientX, event.clientY]; + this.compute(event); + this.emit(); } - if (upper === null) { - const integer2 = getIntegerPart(lower, charSet); - return incrementInteger(integer2, charSet); + wheelEnd() { + if (!this.state._active) return; + this.state._active = false; + this.compute(); + this.emit(); } - if (lower >= upper) { - throw new Error(lower + " >= " + upper); + bind(bindFunction) { + const device = this.config.device; + if (!!device) { + bindFunction(device, "start", this[device + "Start"].bind(this)); + bindFunction(device, "change", this[device + "Move"].bind(this)); + bindFunction(device, "end", this[device + "End"].bind(this)); + bindFunction(device, "cancel", this[device + "End"].bind(this)); + bindFunction("lostPointerCapture", "", this[device + "End"].bind(this)); + } + if (this.config.pinchOnWheel) { + bindFunction("wheel", "", this.wheel.bind(this), { + passive: false + }); + } } - return midPoint(lower, upper, charSet); } -function generateJitteredKeyBetween(lower, upper, charSet = base62CharSet()) { - const key = generateKeyBetween(lower, upper, charSet); - const paddingNeeded = paddingNeededForJitter(key, upper, charSet); - if (paddingNeeded) { - return padAndJitterString(key, paddingNeeded, charSet); +const pinchConfigResolver = _objectSpread2$1(_objectSpread2$1({}, commonConfigResolver), {}, { + device(_v, _k2, { + shared: shared2, + pointer: { + touch = false + } = {} + }) { + const sharedConfig = shared2; + if (sharedConfig.target && !SUPPORT.touch && SUPPORT.gesture) return "gesture"; + if (SUPPORT.touch && touch) return "touch"; + if (SUPPORT.touchscreen) { + if (SUPPORT.pointer) return "pointer"; + if (SUPPORT.touch) return "touch"; + } + }, + bounds(_v, _k2, { + scaleBounds = {}, + angleBounds = {} + }) { + const _scaleBounds = (state) => { + const D = assignDefault(call(scaleBounds, state), { + min: -Infinity, + max: Infinity + }); + return [D.min, D.max]; + }; + const _angleBounds = (state) => { + const A = assignDefault(call(angleBounds, state), { + min: -Infinity, + max: Infinity + }); + return [A.min, A.max]; + }; + if (typeof scaleBounds !== "function" && typeof angleBounds !== "function") return [_scaleBounds(), _angleBounds()]; + return (state) => [_scaleBounds(state), _angleBounds(state)]; + }, + threshold(value, _k2, config) { + this.lockDirection = config.axis === "lock"; + const threshold = V.toVector(value, this.lockDirection ? [0.1, 3] : 0); + return threshold; + }, + modifierKey(value) { + if (value === void 0) return "ctrlKey"; + return value; + }, + pinchOnWheel(value = true) { + return value; } - return jitterString(key, charSet); -} -function generateNJitteredKeysBetween(lower, upper, n2, charSet = base62CharSet()) { - return spreadGeneratorResults( - lower, - upper, - n2, - charSet, - generateJitteredKeyBetween, - generateNJitteredKeysBetween - ); -} -function spreadGeneratorResults(lower, upper, n2, charSet, generateKey, generateNKeys) { - if (n2 === 0) { - return []; +}); +_objectSpread2$1(_objectSpread2$1({}, coordinatesConfigResolver), {}, { + mouseOnly: (value = true) => value +}); +class WheelEngine extends CoordinatesEngine { + constructor(...args) { + super(...args); + _defineProperty$1(this, "ingKey", "wheeling"); } - if (n2 === 1) { - return [generateKey(lower, upper, charSet)]; + wheel(event) { + if (!this.state._active) this.start(event); + this.wheelChange(event); + this.timeoutStore.add("wheelEnd", this.wheelEnd.bind(this)); } - if (upper == null) { - let newUpper = generateKey(lower, upper, charSet); - const result = [newUpper]; - for (let i2 = 0; i2 < n2 - 1; i2++) { - newUpper = generateKey(newUpper, upper, charSet); - result.push(newUpper); - } - return result; + wheelChange(event) { + const state = this.state; + state._delta = wheelValues(event); + V.addTo(state._movement, state._delta); + clampStateInternalMovementToBounds(state); + this.compute(event); + this.emit(); } - if (lower == null) { - let newLower = generateKey(lower, upper, charSet); - const result = [newLower]; - for (let i2 = 0; i2 < n2 - 1; i2++) { - newLower = generateKey(lower, newLower, charSet); - result.push(newLower); - } - result.reverse(); - return result; + wheelEnd() { + if (!this.state._active) return; + this.state._active = false; + this.compute(); + this.emit(); } - const mid = Math.floor(n2 / 2); - const midOrderKey = generateKey(lower, upper, charSet); - return [ - ...generateNKeys(lower, midOrderKey, mid, charSet), - midOrderKey, - ...generateNKeys(midOrderKey, upper, n2 - mid - 1, charSet) - ]; -} -const generateKeysFn = generateNJitteredKeysBetween; -const ZERO_INDEX_KEY = "a0"; -function validateIndexKey(index2) { - try { - generateJitteredKeyBetween(index2, null); - } catch { - throw new Error("invalid index: " + index2); + bind(bindFunction) { + bindFunction("wheel", "", this.wheel.bind(this)); } } -function getIndicesBetween(below, above, n2) { - return generateKeysFn(below ?? null, above ?? null, n2); -} -function getIndicesAbove(below, n2) { - return generateKeysFn(below ?? null, null, n2); -} -function getIndexBetween(below, above) { - return generateKeysFn(below ?? null, above ?? null, 1)[0]; -} -function getIndexAbove(below = null) { - return generateKeysFn(below, null, 1)[0]; -} -function getIndexBelow(above = null) { - return generateKeysFn(null, above, 1)[0]; -} -function getIndices(n2, start = "a1") { - return [start, ...generateKeysFn(start, null, n2)]; +const wheelConfigResolver = coordinatesConfigResolver; +_objectSpread2$1(_objectSpread2$1({}, coordinatesConfigResolver), {}, { + mouseOnly: (value = true) => value +}); +const EngineMap = /* @__PURE__ */ new Map(); +const ConfigResolverMap = /* @__PURE__ */ new Map(); +function registerAction(action) { + EngineMap.set(action.key, action.engine); + ConfigResolverMap.set(action.key, action.resolver); } -function sortByIndex$1(a2, b2) { - if (a2.index < b2.index) { - return -1; - } else if (a2.index > b2.index) { - return 1; +const pinchAction = { + key: "pinch", + engine: PinchEngine, + resolver: pinchConfigResolver +}; +const wheelAction = { + key: "wheel", + engine: WheelEngine, + resolver: wheelConfigResolver +}; +function _objectWithoutPropertiesLoose$1(source, excluded) { + if (source == null) return {}; + var target = {}; + var sourceKeys = Object.keys(source); + var key, i2; + for (i2 = 0; i2 < sourceKeys.length; i2++) { + key = sourceKeys[i2]; + if (excluded.indexOf(key) >= 0) continue; + target[key] = source[key]; } - return 0; -} -function sortById(a2, b2) { - return a2.id > b2.id ? 1 : -1; + return target; } -function getFromLocalStorage(key) { - try { - return localStorage.getItem(key); - } catch { - return null; +function _objectWithoutProperties$1(source, excluded) { + if (source == null) return {}; + var target = _objectWithoutPropertiesLoose$1(source, excluded); + var key, i2; + if (Object.getOwnPropertySymbols) { + var sourceSymbolKeys = Object.getOwnPropertySymbols(source); + for (i2 = 0; i2 < sourceSymbolKeys.length; i2++) { + key = sourceSymbolKeys[i2]; + if (excluded.indexOf(key) >= 0) continue; + if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; + target[key] = source[key]; + } } + return target; } -function setInLocalStorage(key, value) { - try { - localStorage.setItem(key, value); - } catch { +const sharedConfigResolver = { + target(value) { + if (value) { + return () => "current" in value ? value.current : value; + } + return void 0; + }, + enabled(value = true) { + return value; + }, + window(value = SUPPORT.isBrowser ? window : void 0) { + return value; + }, + eventOptions({ + passive = true, + capture = false + } = {}) { + return { + passive, + capture + }; + }, + transform(value) { + return value; } -} -function clearLocalStorage() { - try { - localStorage.clear(); - } catch { +}; +const _excluded$1 = ["target", "eventOptions", "window", "enabled", "transform"]; +function resolveWith(config = {}, resolvers) { + const result = {}; + for (const [key, resolver] of Object.entries(resolvers)) { + switch (typeof resolver) { + case "function": + { + const r = resolver.call(result, config[key], key, config); + if (!Number.isNaN(r)) result[key] = r; + } + break; + case "object": + result[key] = resolveWith(config[key], resolver); + break; + case "boolean": + if (resolver) result[key] = config[key]; + break; + } } + return result; } -function getFromSessionStorage(key) { - try { - return sessionStorage.getItem(key); - } catch { - return null; +function parse$1(newConfig, gestureKey, _config = {}) { + const _ref = newConfig, { + target, + eventOptions, + window: window2, + enabled, + transform + } = _ref, rest = _objectWithoutProperties$1(_ref, _excluded$1); + _config.shared = resolveWith({ + target, + eventOptions, + window: window2, + enabled, + transform + }, sharedConfigResolver); + if (gestureKey) { + const resolver = ConfigResolverMap.get(gestureKey); + _config[gestureKey] = resolveWith(_objectSpread2$1({ + shared: _config.shared + }, rest), resolver); + } else { + for (const key in rest) { + const resolver = ConfigResolverMap.get(key); + if (resolver) { + _config[key] = resolveWith(_objectSpread2$1({ + shared: _config.shared + }, rest[key]), resolver); + } else { + if (!["drag", "pinch", "scroll", "wheel", "move", "hover"].includes(key)) { + if (key === "domTarget") { + throw Error(`[@use-gesture]: \`domTarget\` option has been renamed to \`target\`.`); + } + console.warn(`[@use-gesture]: Unknown config key \`${key}\` was used. Please read the documentation for further information.`); + } + } + } } + return _config; } -function setInSessionStorage(key, value) { - try { - sessionStorage.setItem(key, value); - } catch { +class EventStore { + constructor(ctrl, gestureKey) { + _defineProperty$1(this, "_listeners", /* @__PURE__ */ new Set()); + this._ctrl = ctrl; + this._gestureKey = gestureKey; } -} -function deleteFromSessionStorage(key) { - try { - sessionStorage.removeItem(key); - } catch { + add(element, device, action, handler, options) { + const listeners = this._listeners; + const type = toDomEventType(device, action); + const _options = this._gestureKey ? this._ctrl.config[this._gestureKey].eventOptions : {}; + const eventOptions = _objectSpread2$1(_objectSpread2$1({}, _options), options); + element.addEventListener(type, handler, eventOptions); + const remove2 = () => { + element.removeEventListener(type, handler, eventOptions); + listeners.delete(remove2); + }; + listeners.add(remove2); + return remove2; } -} -function clearSessionStorage() { - try { - sessionStorage.clear(); - } catch { + clean() { + this._listeners.forEach((remove2) => remove2()); + this._listeners.clear(); } } -const isTest$1 = () => typeof process !== "undefined" && false; -const fpsQueue = []; -const targetFps = 60; -const targetTimePerFrame = Math.ceil(1e3 / targetFps); -let frame; -let time = 0; -let last = 0; -const flush = () => { - const queue = fpsQueue.splice(0, fpsQueue.length); - for (const fn of queue) { - fn(); - } -}; -function tick() { - if (frame) { - return; +class TimeoutStore { + constructor() { + _defineProperty$1(this, "_timeouts", /* @__PURE__ */ new Map()); } - const now2 = Date.now(); - const elapsed = now2 - last; - if (time + elapsed < targetTimePerFrame) { - frame = requestAnimationFrame(() => { - frame = void 0; - tick(); - }); - return; + add(key, callback, ms = 140, ...args) { + this.remove(key); + this._timeouts.set(key, window.setTimeout(callback, ms, ...args)); } - frame = requestAnimationFrame(() => { - frame = void 0; - last = now2; - time = Math.min(time + elapsed - targetTimePerFrame, targetTimePerFrame * 10); - flush(); - }); -} -let started = false; -function throttleToNextFrame$1(fn) { - if (isTest$1()) { - fn(); - return () => { - }; + remove(key) { + const timeout = this._timeouts.get(key); + if (timeout) window.clearTimeout(timeout); } - if (!fpsQueue.includes(fn)) { - fpsQueue.push(fn); - if (!started) { - started = true; - last = Date.now() - targetTimePerFrame - 1; - } - tick(); + clean() { + this._timeouts.forEach((timeout) => void window.clearTimeout(timeout)); + this._timeouts.clear(); } - return () => { - const index2 = fpsQueue.indexOf(fn); - if (index2 > -1) { - fpsQueue.splice(index2, 1); - } - }; } -class Timers { - constructor() { - __publicField(this, "timeouts", /* @__PURE__ */ new Map()); - __publicField(this, "intervals", /* @__PURE__ */ new Map()); - __publicField(this, "rafs", /* @__PURE__ */ new Map()); - this.setTimeout = this.setTimeout.bind(this); - this.setInterval = this.setInterval.bind(this); - this.requestAnimationFrame = this.requestAnimationFrame.bind(this); - this.dispose = this.dispose.bind(this); +class Controller { + constructor(handlers) { + _defineProperty$1(this, "gestures", /* @__PURE__ */ new Set()); + _defineProperty$1(this, "_targetEventStore", new EventStore(this)); + _defineProperty$1(this, "gestureEventStores", {}); + _defineProperty$1(this, "gestureTimeoutStores", {}); + _defineProperty$1(this, "handlers", {}); + _defineProperty$1(this, "config", {}); + _defineProperty$1(this, "pointerIds", /* @__PURE__ */ new Set()); + _defineProperty$1(this, "touchIds", /* @__PURE__ */ new Set()); + _defineProperty$1(this, "state", { + shared: { + shiftKey: false, + metaKey: false, + ctrlKey: false, + altKey: false + } + }); + resolveGestures(this, handlers); } - /** @public */ - setTimeout(contextId, handler, timeout, ...args) { - const id2 = window.setTimeout(handler, timeout, args); - const current = this.timeouts.get(contextId) ?? []; - this.timeouts.set(contextId, [...current, id2]); - return id2; + setEventIds(event) { + if (isTouch(event)) { + this.touchIds = new Set(touchIds(event)); + return this.touchIds; + } else if ("pointerId" in event) { + if (event.type === "pointerup" || event.type === "pointercancel") this.pointerIds.delete(event.pointerId); + else if (event.type === "pointerdown") this.pointerIds.add(event.pointerId); + return this.pointerIds; + } } - /** @public */ - setInterval(contextId, handler, timeout, ...args) { - const id2 = window.setInterval(handler, timeout, args); - const current = this.intervals.get(contextId) ?? []; - this.intervals.set(contextId, [...current, id2]); - return id2; + applyHandlers(handlers, nativeHandlers) { + this.handlers = handlers; + this.nativeHandlers = nativeHandlers; } - /** @public */ - requestAnimationFrame(contextId, callback) { - const id2 = window.requestAnimationFrame(callback); - const current = this.rafs.get(contextId) ?? []; - this.rafs.set(contextId, [...current, id2]); - return id2; + applyConfig(config, gestureKey) { + this.config = parse$1(config, gestureKey, this.config); } - /** @public */ - dispose(contextId) { - var _a3, _b2, _c2; - (_a3 = this.timeouts.get(contextId)) == null ? void 0 : _a3.forEach((id2) => clearTimeout(id2)); - (_b2 = this.intervals.get(contextId)) == null ? void 0 : _b2.forEach((id2) => clearInterval(id2)); - (_c2 = this.rafs.get(contextId)) == null ? void 0 : _c2.forEach((id2) => cancelAnimationFrame(id2)); - this.timeouts.delete(contextId); - this.intervals.delete(contextId); - this.rafs.delete(contextId); + clean() { + this._targetEventStore.clean(); + for (const key of this.gestures) { + this.gestureEventStores[key].clean(); + this.gestureTimeoutStores[key].clean(); + } } - disposeAll() { - for (const contextId of this.timeouts.keys()) { - this.dispose(contextId); + effect() { + if (this.config.shared.target) this.bind(); + return () => this._targetEventStore.clean(); + } + bind(...args) { + const sharedConfig = this.config.shared; + const props = {}; + let target; + if (sharedConfig.target) { + target = sharedConfig.target(); + if (!target) return; + } + if (sharedConfig.enabled) { + for (const gestureKey of this.gestures) { + const gestureConfig = this.config[gestureKey]; + const bindFunction = bindToProps(props, gestureConfig.eventOptions, !!target); + if (gestureConfig.enabled) { + const Engine2 = EngineMap.get(gestureKey); + new Engine2(this, args, gestureKey).bind(bindFunction); + } + } + const nativeBindFunction = bindToProps(props, sharedConfig.eventOptions, !!target); + for (const eventKey in this.nativeHandlers) { + nativeBindFunction(eventKey, "", (event) => this.nativeHandlers[eventKey](_objectSpread2$1(_objectSpread2$1({}, this.state.shared), {}, { + event, + args + })), void 0, true); + } + } + for (const handlerProp in props) { + props[handlerProp] = chain(...props[handlerProp]); + } + if (!target) return props; + for (const handlerProp in props) { + const { + device, + capture, + passive + } = parseProp(handlerProp); + this._targetEventStore.add(target, device, "", props[handlerProp], { + capture, + passive + }); } } - forContext(contextId) { - return { - setTimeout: (handler, timeout, ...args) => this.setTimeout(contextId, handler, timeout, args), - setInterval: (handler, timeout, ...args) => this.setInterval(contextId, handler, timeout, args), - requestAnimationFrame: (callback) => this.requestAnimationFrame(contextId, callback), - dispose: () => this.dispose(contextId) - }; +} +function setupGesture(ctrl, gestureKey) { + ctrl.gestures.add(gestureKey); + ctrl.gestureEventStores[gestureKey] = new EventStore(ctrl, gestureKey); + ctrl.gestureTimeoutStores[gestureKey] = new TimeoutStore(); +} +function resolveGestures(ctrl, internalHandlers) { + if (internalHandlers.drag) setupGesture(ctrl, "drag"); + if (internalHandlers.wheel) setupGesture(ctrl, "wheel"); + if (internalHandlers.scroll) setupGesture(ctrl, "scroll"); + if (internalHandlers.move) setupGesture(ctrl, "move"); + if (internalHandlers.pinch) setupGesture(ctrl, "pinch"); + if (internalHandlers.hover) setupGesture(ctrl, "hover"); +} +const bindToProps = (props, eventOptions, withPassiveOption) => (device, action, handler, options = {}, isNative = false) => { + var _options$capture, _options$passive; + const capture = (_options$capture = options.capture) !== null && _options$capture !== void 0 ? _options$capture : eventOptions.capture; + const passive = (_options$passive = options.passive) !== null && _options$passive !== void 0 ? _options$passive : eventOptions.passive; + let handlerProp = isNative ? device : toHandlerProp(device, action, capture); + if (withPassiveOption && passive) handlerProp += "Passive"; + props[handlerProp] = props[handlerProp] || []; + props[handlerProp].push(handler); +}; +const RE_NOT_NATIVE = /^on(Drag|Wheel|Scroll|Move|Pinch|Hover)/; +function sortHandlers(_handlers2) { + const native = {}; + const handlers = {}; + const actions = /* @__PURE__ */ new Set(); + for (let key in _handlers2) { + if (RE_NOT_NATIVE.test(key)) { + actions.add(RegExp.lastMatch); + handlers[key] = _handlers2[key]; + } else { + native[key] = _handlers2[key]; + } } + return [handlers, native, actions]; } -const safeParseUrl = (url, baseUrl) => { - try { - return new URL(url, baseUrl); - } catch { +function registerGesture(actions, handlers, handlerKey, key, internalHandlers, config) { + if (!actions.has(handlerKey)) return; + if (!EngineMap.has(key)) { + { + console.warn(`[@use-gesture]: You've created a custom handler that that uses the \`${key}\` gesture but isn't properly configured. + +Please add \`${key}Action\` when creating your handler.`); + } return; } -}; -function isDefined(value) { - return value !== void 0; + const startKey2 = handlerKey + "Start"; + const endKey = handlerKey + "End"; + const fn = (state) => { + let memo2 = void 0; + if (state.first && startKey2 in handlers) handlers[startKey2](state); + if (handlerKey in handlers) memo2 = handlers[handlerKey](state); + if (state.last && endKey in handlers) handlers[endKey](state); + return memo2; + }; + internalHandlers[key] = fn; + config[key] = config[key] || {}; } -function getStructuredClone() { - if (typeof globalThis !== "undefined" && globalThis.structuredClone) { - return [globalThis.structuredClone, true]; - } - if (typeof global !== "undefined" && global.structuredClone) { - return [global.structuredClone, true]; - } - if (typeof window !== "undefined" && window.structuredClone) { - return [window.structuredClone, true]; +function parseMergedHandlers(mergedHandlers, mergedConfig) { + const [handlers, nativeHandlers, actions] = sortHandlers(mergedHandlers); + const internalHandlers = {}; + registerGesture(actions, handlers, "onDrag", "drag", internalHandlers, mergedConfig); + registerGesture(actions, handlers, "onWheel", "wheel", internalHandlers, mergedConfig); + registerGesture(actions, handlers, "onScroll", "scroll", internalHandlers, mergedConfig); + registerGesture(actions, handlers, "onPinch", "pinch", internalHandlers, mergedConfig); + registerGesture(actions, handlers, "onMove", "move", internalHandlers, mergedConfig); + registerGesture(actions, handlers, "onHover", "hover", internalHandlers, mergedConfig); + return { + handlers: internalHandlers, + config: mergedConfig, + nativeHandlers + }; +} +function useRecognizers(handlers, config = {}, gestureKey, nativeHandlers) { + const ctrl = React.useMemo(() => new Controller(handlers), []); + ctrl.applyHandlers(handlers, nativeHandlers); + ctrl.applyConfig(config, gestureKey); + React.useEffect(ctrl.effect.bind(ctrl)); + React.useEffect(() => { + return ctrl.clean.bind(ctrl); + }, []); + if (config.target === void 0) { + return ctrl.bind.bind(ctrl); } - return [(i2) => i2 ? JSON.parse(JSON.stringify(i2)) : i2, false]; + return void 0; } -const _structuredClone = getStructuredClone(); -const structuredClone = _structuredClone[0]; -_structuredClone[1]; -const STRUCTURED_CLONE_OBJECT_PROTOTYPE = Object.getPrototypeOf(structuredClone({})); -registerTldrawLibraryVersion( - "@tldraw/utils", - "3.4.1", - "esm" -); -var check = function(it) { - return it && it.Math === Math && it; -}; -var globalThis_1 = ( - // eslint-disable-next-line es/no-global-this -- safe - check(typeof globalThis == "object" && globalThis) || check(typeof window == "object" && window) || // eslint-disable-next-line no-restricted-globals -- safe - check(typeof self == "object" && self) || check(typeof commonjsGlobal == "object" && commonjsGlobal) || check(typeof commonjsGlobal == "object" && commonjsGlobal) || // eslint-disable-next-line no-new-func -- fallback - /* @__PURE__ */ function() { - return this; - }() || Function("return this")() +function createUseGesture(actions) { + actions.forEach(registerAction); + return function useGesture2(_handlers2, _config) { + const { + handlers, + nativeHandlers, + config + } = parseMergedHandlers(_handlers2, _config || {}); + return useRecognizers(handlers, config, void 0, nativeHandlers); + }; +} +const MAX_ZOOM_STEP = 10; +const IS_DARWIN = /Mac|iPod|iPhone|iPad/.test( + // eslint-disable-next-line @typescript-eslint/no-deprecated + typeof window === "undefined" ? "node" : window.navigator.platform ); -var objectGetOwnPropertyDescriptor = {}; -var fails$f = function(exec2) { - try { - return !!exec2(); - } catch (error) { +function normalizeWheel(event) { + let { deltaY, deltaX } = event; + let deltaZ = 0; + if (event.ctrlKey || event.altKey || event.metaKey) { + deltaZ = (Math.abs(deltaY) > MAX_ZOOM_STEP ? MAX_ZOOM_STEP * Math.sign(deltaY) : deltaY) / 100; + } else { + if (event.shiftKey && !IS_DARWIN) { + deltaX = deltaY; + deltaY = 0; + } + } + return { x: -deltaX, y: -deltaY, z: -deltaZ }; +} +const useGesture = createUseGesture([wheelAction, pinchAction]); +let lastWheelTime = void 0; +const isWheelEndEvent = (time2) => { + if (lastWheelTime === void 0) { + lastWheelTime = time2; + return false; + } + if (time2 - lastWheelTime > 120 && time2 - lastWheelTime < 160) { + lastWheelTime = time2; return true; } + lastWheelTime = time2; + return false; }; -var fails$e = fails$f; -var descriptors = !fails$e(function() { - return Object.defineProperty({}, 1, { get: function() { - return 7; - } })[1] !== 7; -}); -var fails$d = fails$f; -var functionBindNative = !fails$d(function() { - var test3 = (function() { - }).bind(); - return typeof test3 != "function" || test3.hasOwnProperty("prototype"); -}); -var NATIVE_BIND$3 = functionBindNative; -var call$c = Function.prototype.call; -var functionCall = NATIVE_BIND$3 ? call$c.bind(call$c) : function() { - return call$c.apply(call$c, arguments); -}; -var objectPropertyIsEnumerable = {}; -var $propertyIsEnumerable = {}.propertyIsEnumerable; -var getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor; -var NASHORN_BUG = getOwnPropertyDescriptor$1 && !$propertyIsEnumerable.call({ 1: 2 }, 1); -objectPropertyIsEnumerable.f = NASHORN_BUG ? function propertyIsEnumerable(V2) { - var descriptor = getOwnPropertyDescriptor$1(this, V2); - return !!descriptor && descriptor.enumerable; -} : $propertyIsEnumerable; -var createPropertyDescriptor$2 = function(bitmap, value) { - return { - enumerable: !(bitmap & 1), - configurable: !(bitmap & 2), - writable: !(bitmap & 4), - value - }; -}; -var NATIVE_BIND$2 = functionBindNative; -var FunctionPrototype$2 = Function.prototype; -var call$b = FunctionPrototype$2.call; -var uncurryThisWithBind = NATIVE_BIND$2 && FunctionPrototype$2.bind.bind(call$b, call$b); -var functionUncurryThis = NATIVE_BIND$2 ? uncurryThisWithBind : function(fn) { - return function() { - return call$b.apply(fn, arguments); - }; -}; -var uncurryThis$i = functionUncurryThis; -var toString$7 = uncurryThis$i({}.toString); -var stringSlice$6 = uncurryThis$i("".slice); -var classofRaw$2 = function(it) { - return stringSlice$6(toString$7(it), 8, -1); -}; -var uncurryThis$h = functionUncurryThis; -var fails$c = fails$f; -var classof$6 = classofRaw$2; -var $Object$3 = Object; -var split = uncurryThis$h("".split); -var indexedObject = fails$c(function() { - return !$Object$3("z").propertyIsEnumerable(0); -}) ? function(it) { - return classof$6(it) === "String" ? split(it, "") : $Object$3(it); -} : $Object$3; -var isNullOrUndefined$4 = function(it) { - return it === null || it === void 0; -}; -var isNullOrUndefined$3 = isNullOrUndefined$4; -var $TypeError$8 = TypeError; -var requireObjectCoercible$6 = function(it) { - if (isNullOrUndefined$3(it)) throw new $TypeError$8("Can't call method on " + it); - return it; -}; -var IndexedObject = indexedObject; -var requireObjectCoercible$5 = requireObjectCoercible$6; -var toIndexedObject$4 = function(it) { - return IndexedObject(requireObjectCoercible$5(it)); -}; -var documentAll = typeof document == "object" && document.all; -var isCallable$f = typeof documentAll == "undefined" && documentAll !== void 0 ? function(argument) { - return typeof argument == "function" || argument === documentAll; -} : function(argument) { - return typeof argument == "function"; -}; -var isCallable$e = isCallable$f; -var isObject$7 = function(it) { - return typeof it == "object" ? it !== null : isCallable$e(it); -}; -var globalThis$f = globalThis_1; -var isCallable$d = isCallable$f; -var aFunction = function(argument) { - return isCallable$d(argument) ? argument : void 0; -}; -var getBuiltIn$4 = function(namespace, method) { - return arguments.length < 2 ? aFunction(globalThis$f[namespace]) : globalThis$f[namespace] && globalThis$f[namespace][method]; -}; -var uncurryThis$g = functionUncurryThis; -var objectIsPrototypeOf = uncurryThis$g({}.isPrototypeOf); -var globalThis$e = globalThis_1; -var navigator$1 = globalThis$e.navigator; -var userAgent$1 = navigator$1 && navigator$1.userAgent; -var environmentUserAgent = userAgent$1 ? String(userAgent$1) : ""; -var globalThis$d = globalThis_1; -var userAgent = environmentUserAgent; -var process$1 = globalThis$d.process; -var Deno = globalThis$d.Deno; -var versions = process$1 && process$1.versions || Deno && Deno.version; -var v8 = versions && versions.v8; -var match, version$1; -if (v8) { - match = v8.split("."); - version$1 = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]); +function useGestureEvents(ref) { + const editor = useEditor(); + const events = reactExports.useMemo(() => { + let pinchState = "not sure"; + const onWheel = ({ event }) => { + if (!editor.getInstanceState().isFocused) { + return; + } + pinchState = "not sure"; + if (isWheelEndEvent(Date.now())) { + return; + } + const editingShapeId = editor.getEditingShapeId(); + if (editingShapeId) { + const shape = editor.getShape(editingShapeId); + if (shape) { + const util = editor.getShapeUtil(shape); + if (util.canScroll(shape)) { + const bounds = editor.getShapePageBounds(editingShapeId); + if (bounds == null ? void 0 : bounds.containsPoint(editor.inputs.currentPagePoint)) { + return; + } + } + } + } + preventDefault(event); + stopEventPropagation(event); + const delta = normalizeWheel(event); + if (delta.x === 0 && delta.y === 0) return; + const info = { + type: "wheel", + name: "wheel", + delta, + point: new Vec(event.clientX, event.clientY), + shiftKey: event.shiftKey, + altKey: event.altKey, + ctrlKey: event.metaKey || event.ctrlKey, + metaKey: event.metaKey, + accelKey: isAccelKey(event) + }; + editor.dispatch(info); + }; + let initDistanceBetweenFingers = 1; + let initZoom = 1; + let currZoom = 1; + let currDistanceBetweenFingers = 0; + const initPointBetweenFingers = new Vec(); + const prevPointBetweenFingers = new Vec(); + const onPinchStart = (gesture) => { + const elm = ref.current; + pinchState = "not sure"; + const { event, origin, da } = gesture; + if (event instanceof WheelEvent) return; + if (!(event.target === elm || (elm == null ? void 0 : elm.contains(event.target)))) return; + prevPointBetweenFingers.x = origin[0]; + prevPointBetweenFingers.y = origin[1]; + initPointBetweenFingers.x = origin[0]; + initPointBetweenFingers.y = origin[1]; + initDistanceBetweenFingers = da[0]; + initZoom = editor.getZoomLevel(); + editor.dispatch({ + type: "pinch", + name: "pinch_start", + point: { x: origin[0], y: origin[1], z: editor.getZoomLevel() }, + delta: { x: 0, y: 0 }, + shiftKey: event.shiftKey, + altKey: event.altKey, + ctrlKey: event.metaKey || event.ctrlKey, + metaKey: event.metaKey, + accelKey: isAccelKey(event) + }); + }; + const updatePinchState = (isSafariTrackpadPinch) => { + if (isSafariTrackpadPinch) { + pinchState = "zooming"; + } + if (pinchState === "zooming") { + return; + } + const touchDistance = Math.abs(currDistanceBetweenFingers - initDistanceBetweenFingers); + const originDistance = Vec.Dist(initPointBetweenFingers, prevPointBetweenFingers); + switch (pinchState) { + case "not sure": { + if (touchDistance > 24) { + pinchState = "zooming"; + } else if (originDistance > 16) { + pinchState = "panning"; + } + break; + } + case "panning": { + if (touchDistance > 64) { + pinchState = "zooming"; + } + break; + } + } + }; + const onPinch = (gesture) => { + const elm = ref.current; + const { event, origin, offset: offset2, da } = gesture; + if (event instanceof WheelEvent) return; + if (!(event.target === elm || (elm == null ? void 0 : elm.contains(event.target)))) return; + const isSafariTrackpadPinch = gesture.type === "gesturechange" || gesture.type === "gestureend"; + currDistanceBetweenFingers = da[0]; + const dx = origin[0] - prevPointBetweenFingers.x; + const dy = origin[1] - prevPointBetweenFingers.y; + prevPointBetweenFingers.x = origin[0]; + prevPointBetweenFingers.y = origin[1]; + updatePinchState(isSafariTrackpadPinch); + switch (pinchState) { + case "zooming": { + currZoom = offset2[0]; + editor.dispatch({ + type: "pinch", + name: "pinch", + point: { x: origin[0], y: origin[1], z: currZoom }, + delta: { x: dx, y: dy }, + shiftKey: event.shiftKey, + altKey: event.altKey, + ctrlKey: event.metaKey || event.ctrlKey, + metaKey: event.metaKey, + accelKey: isAccelKey(event) + }); + break; + } + case "panning": { + editor.dispatch({ + type: "pinch", + name: "pinch", + point: { x: origin[0], y: origin[1], z: initZoom }, + delta: { x: dx, y: dy }, + shiftKey: event.shiftKey, + altKey: event.altKey, + ctrlKey: event.metaKey || event.ctrlKey, + metaKey: event.metaKey, + accelKey: isAccelKey(event) + }); + break; + } + } + }; + const onPinchEnd = (gesture) => { + const elm = ref.current; + const { event, origin, offset: offset2 } = gesture; + if (event instanceof WheelEvent) return; + if (!(event.target === elm || (elm == null ? void 0 : elm.contains(event.target)))) return; + const scale = offset2[0]; + pinchState = "not sure"; + editor.timers.requestAnimationFrame(() => { + editor.dispatch({ + type: "pinch", + name: "pinch_end", + point: { x: origin[0], y: origin[1], z: scale }, + delta: { x: origin[0], y: origin[1] }, + shiftKey: event.shiftKey, + altKey: event.altKey, + ctrlKey: event.metaKey || event.ctrlKey, + metaKey: event.metaKey, + accelKey: isAccelKey(event) + }); + }); + }; + return { + onWheel, + onPinchStart, + onPinchEnd, + onPinch + }; + }, [editor, ref]); + useGesture(events, { + target: ref, + eventOptions: { passive: false }, + pinch: { + from: () => [editor.getZoomLevel(), 0], + // Return the camera z to use when pinch starts + scaleBounds: () => { + const baseZoom = editor.getBaseZoom(); + const zoomSteps = editor.getCameraOptions().zoomSteps; + const zoomMin = zoomSteps[0] * baseZoom; + const zoomMax = zoomSteps[zoomSteps.length - 1] * baseZoom; + return { from: editor.getZoomLevel(), max: zoomMax, min: zoomMin }; + } + } + }); +} +function getHandle(editor, id2, handleId) { + const shape = editor.getShape(id2); + const handles = editor.getShapeHandles(shape); + return { shape, handle: handles.find((h2) => h2.id === handleId) }; +} +function useHandleEvents(id2, handleId) { + const editor = useEditor(); + return reactExports.useMemo(() => { + const onPointerDown = (e2) => { + if (e2.isKilled) return; + const target = loopToHtmlElement(e2.currentTarget); + setPointerCapture(target, e2); + const { shape, handle } = getHandle(editor, id2, handleId); + if (!handle) return; + editor.dispatch({ + type: "pointer", + target: "handle", + handle, + shape, + name: "pointer_down", + ...getPointerInfo(e2) + }); + }; + let lastX, lastY; + const onPointerMove = (e2) => { + if (e2.isKilled) return; + if (e2.clientX === lastX && e2.clientY === lastY) return; + lastX = e2.clientX; + lastY = e2.clientY; + const { shape, handle } = getHandle(editor, id2, handleId); + if (!handle) return; + editor.dispatch({ + type: "pointer", + target: "handle", + handle, + shape, + name: "pointer_move", + ...getPointerInfo(e2) + }); + }; + const onPointerUp = (e2) => { + if (e2.isKilled) return; + const target = loopToHtmlElement(e2.currentTarget); + releasePointerCapture(target, e2); + const { shape, handle } = getHandle(editor, id2, handleId); + if (!handle) return; + editor.dispatch({ + type: "pointer", + target: "handle", + handle, + shape, + name: "pointer_up", + ...getPointerInfo(e2) + }); + }; + return { + onPointerDown, + onPointerMove, + onPointerUp + }; + }, [editor, id2, handleId]); } -if (!version$1 && userAgent) { - match = userAgent.match(/Edge\/(\d+)/); - if (!match || match[1] >= 74) { - match = userAgent.match(/Chrome\/(\d+)/); - if (match) version$1 = +match[1]; - } +function useScreenBounds(ref) { + const editor = useEditor(); + reactExports.useLayoutEffect(() => { + const updateBounds = throttle$1( + () => { + if (!ref.current) return; + editor.updateViewportScreenBounds(ref.current); + }, + 200, + { + trailing: true + } + ); + const interval = editor.timers.setInterval(updateBounds, 1e3); + window.addEventListener("resize", updateBounds); + const resizeObserver = new ResizeObserver((entries) => { + if (!entries[0].contentRect) return; + updateBounds(); + }); + const container = ref.current; + let scrollingParent = null; + if (container) { + resizeObserver.observe(container); + scrollingParent = getNearestScrollableContainer(container); + scrollingParent.addEventListener("scroll", updateBounds); + } + return () => { + clearInterval(interval); + window.removeEventListener("resize", updateBounds); + resizeObserver.disconnect(); + scrollingParent == null ? void 0 : scrollingParent.removeEventListener("scroll", updateBounds); + updateBounds.cancel(); + }; + }, [editor, ref]); } -var environmentV8Version = version$1; -var V8_VERSION = environmentV8Version; -var fails$b = fails$f; -var globalThis$c = globalThis_1; -var $String$4 = globalThis$c.String; -var symbolConstructorDetection = !!Object.getOwnPropertySymbols && !fails$b(function() { - var symbol = Symbol("symbol detection"); - return !$String$4(symbol) || !(Object(symbol) instanceof Symbol) || // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances - !Symbol.sham && V8_VERSION && V8_VERSION < 41; -}); -var NATIVE_SYMBOL$1 = symbolConstructorDetection; -var useSymbolAsUid = NATIVE_SYMBOL$1 && !Symbol.sham && typeof Symbol.iterator == "symbol"; -var getBuiltIn$3 = getBuiltIn$4; -var isCallable$c = isCallable$f; -var isPrototypeOf$1 = objectIsPrototypeOf; -var USE_SYMBOL_AS_UID$1 = useSymbolAsUid; -var $Object$2 = Object; -var isSymbol$2 = USE_SYMBOL_AS_UID$1 ? function(it) { - return typeof it == "symbol"; -} : function(it) { - var $Symbol = getBuiltIn$3("Symbol"); - return isCallable$c($Symbol) && isPrototypeOf$1($Symbol.prototype, $Object$2(it)); -}; -var $String$3 = String; -var tryToString$1 = function(argument) { - try { - return $String$3(argument); - } catch (error) { - return "Object"; +/*! + * Author: excalidraw + * MIT License: https://github.com/excalidraw/excalidraw/blob/master/LICENSE + * https://github.com/excalidraw/excalidraw/blob/48c3465b19f10ec755b3eb84e21a01a468e96e43/packages/excalidraw/utils.ts#L600 + */ +const getNearestScrollableContainer = (element) => { + let parent = element.parentElement; + while (parent) { + if (parent === document.body) { + return document; + } + const { overflowY } = window.getComputedStyle(parent); + const hasScrollableContent = parent.scrollHeight > parent.clientHeight; + if (hasScrollableContent && (overflowY === "auto" || overflowY === "scroll" || overflowY === "overlay")) { + return parent; + } + parent = parent.parentElement; } + return document; }; -var isCallable$b = isCallable$f; -var tryToString = tryToString$1; -var $TypeError$7 = TypeError; -var aCallable$3 = function(argument) { - if (isCallable$b(argument)) return argument; - throw new $TypeError$7(tryToString(argument) + " is not a function"); -}; -var aCallable$2 = aCallable$3; -var isNullOrUndefined$2 = isNullOrUndefined$4; -var getMethod$4 = function(V2, P2) { - var func = V2[P2]; - return isNullOrUndefined$2(func) ? void 0 : aCallable$2(func); -}; -var call$a = functionCall; -var isCallable$a = isCallable$f; -var isObject$6 = isObject$7; -var $TypeError$6 = TypeError; -var ordinaryToPrimitive$1 = function(input, pref) { - var fn, val; - if (pref === "string" && isCallable$a(fn = input.toString) && !isObject$6(val = call$a(fn, input))) return val; - if (isCallable$a(fn = input.valueOf) && !isObject$6(val = call$a(fn, input))) return val; - if (pref !== "string" && isCallable$a(fn = input.toString) && !isObject$6(val = call$a(fn, input))) return val; - throw new $TypeError$6("Can't convert object to primitive value"); -}; -var sharedStore = { exports: {} }; -var globalThis$b = globalThis_1; -var defineProperty$2 = Object.defineProperty; -var defineGlobalProperty$3 = function(key, value) { - try { - defineProperty$2(globalThis$b, key, { value, configurable: true, writable: true }); - } catch (error) { - globalThis$b[key] = value; +class Box { + constructor(x2 = 0, y2 = 0, w2 = 0, h2 = 0) { + __publicField(this, "x", 0); + __publicField(this, "y", 0); + __publicField(this, "w", 0); + __publicField(this, "h", 0); + this.x = x2; + this.y = y2; + this.w = w2; + this.h = h2; } - return value; -}; -var globalThis$a = globalThis_1; -var defineGlobalProperty$2 = defineGlobalProperty$3; -var SHARED = "__core-js_shared__"; -var store$3 = sharedStore.exports = globalThis$a[SHARED] || defineGlobalProperty$2(SHARED, {}); -(store$3.versions || (store$3.versions = [])).push({ - version: "3.39.0", - mode: "global", - copyright: "© 2014-2024 Denis Pushkarev (zloirock.ru)", - license: "https://github.com/zloirock/core-js/blob/v3.39.0/LICENSE", - source: "https://github.com/zloirock/core-js" -}); -var sharedStoreExports = sharedStore.exports; -var store$2 = sharedStoreExports; -var shared$4 = function(key, value) { - return store$2[key] || (store$2[key] = value || {}); -}; -var requireObjectCoercible$4 = requireObjectCoercible$6; -var $Object$1 = Object; -var toObject$5 = function(argument) { - return $Object$1(requireObjectCoercible$4(argument)); -}; -var uncurryThis$f = functionUncurryThis; -var toObject$4 = toObject$5; -var hasOwnProperty = uncurryThis$f({}.hasOwnProperty); -var hasOwnProperty_1 = Object.hasOwn || function hasOwn(it, key) { - return hasOwnProperty(toObject$4(it), key); -}; -var uncurryThis$e = functionUncurryThis; -var id$1 = 0; -var postfix = Math.random(); -var toString$6 = uncurryThis$e(1 .toString); -var uid$2 = function(key) { - return "Symbol(" + (key === void 0 ? "" : key) + ")_" + toString$6(++id$1 + postfix, 36); -}; -var globalThis$9 = globalThis_1; -var shared$3 = shared$4; -var hasOwn$7 = hasOwnProperty_1; -var uid$1 = uid$2; -var NATIVE_SYMBOL = symbolConstructorDetection; -var USE_SYMBOL_AS_UID = useSymbolAsUid; -var Symbol$1 = globalThis$9.Symbol; -var WellKnownSymbolsStore = shared$3("wks"); -var createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol$1["for"] || Symbol$1 : Symbol$1 && Symbol$1.withoutSetter || uid$1; -var wellKnownSymbol$9 = function(name) { - if (!hasOwn$7(WellKnownSymbolsStore, name)) { - WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn$7(Symbol$1, name) ? Symbol$1[name] : createWellKnownSymbol("Symbol." + name); + // eslint-disable-next-line no-restricted-syntax + get point() { + return new Vec(this.x, this.y); } - return WellKnownSymbolsStore[name]; -}; -var call$9 = functionCall; -var isObject$5 = isObject$7; -var isSymbol$1 = isSymbol$2; -var getMethod$3 = getMethod$4; -var ordinaryToPrimitive = ordinaryToPrimitive$1; -var wellKnownSymbol$8 = wellKnownSymbol$9; -var $TypeError$5 = TypeError; -var TO_PRIMITIVE = wellKnownSymbol$8("toPrimitive"); -var toPrimitive$1 = function(input, pref) { - if (!isObject$5(input) || isSymbol$1(input)) return input; - var exoticToPrim = getMethod$3(input, TO_PRIMITIVE); - var result; - if (exoticToPrim) { - if (pref === void 0) pref = "default"; - result = call$9(exoticToPrim, input, pref); - if (!isObject$5(result) || isSymbol$1(result)) return result; - throw new $TypeError$5("Can't convert object to primitive value"); + // eslint-disable-next-line no-restricted-syntax + set point(val) { + this.x = val.x; + this.y = val.y; } - if (pref === void 0) pref = "number"; - return ordinaryToPrimitive(input, pref); -}; -var toPrimitive = toPrimitive$1; -var isSymbol = isSymbol$2; -var toPropertyKey$2 = function(argument) { - var key = toPrimitive(argument, "string"); - return isSymbol(key) ? key : key + ""; -}; -var globalThis$8 = globalThis_1; -var isObject$4 = isObject$7; -var document$1 = globalThis$8.document; -var EXISTS$1 = isObject$4(document$1) && isObject$4(document$1.createElement); -var documentCreateElement$1 = function(it) { - return EXISTS$1 ? document$1.createElement(it) : {}; -}; -var DESCRIPTORS$7 = descriptors; -var fails$a = fails$f; -var createElement = documentCreateElement$1; -var ie8DomDefine = !DESCRIPTORS$7 && !fails$a(function() { - return Object.defineProperty(createElement("div"), "a", { - get: function() { - return 7; - } - }).a !== 7; -}); -var DESCRIPTORS$6 = descriptors; -var call$8 = functionCall; -var propertyIsEnumerableModule = objectPropertyIsEnumerable; -var createPropertyDescriptor$1 = createPropertyDescriptor$2; -var toIndexedObject$3 = toIndexedObject$4; -var toPropertyKey$1 = toPropertyKey$2; -var hasOwn$6 = hasOwnProperty_1; -var IE8_DOM_DEFINE$1 = ie8DomDefine; -var $getOwnPropertyDescriptor$1 = Object.getOwnPropertyDescriptor; -objectGetOwnPropertyDescriptor.f = DESCRIPTORS$6 ? $getOwnPropertyDescriptor$1 : function getOwnPropertyDescriptor(O2, P2) { - O2 = toIndexedObject$3(O2); - P2 = toPropertyKey$1(P2); - if (IE8_DOM_DEFINE$1) try { - return $getOwnPropertyDescriptor$1(O2, P2); - } catch (error) { + // eslint-disable-next-line no-restricted-syntax + get minX() { + return this.x; } - if (hasOwn$6(O2, P2)) return createPropertyDescriptor$1(!call$8(propertyIsEnumerableModule.f, O2, P2), O2[P2]); -}; -var objectDefineProperty = {}; -var DESCRIPTORS$5 = descriptors; -var fails$9 = fails$f; -var v8PrototypeDefineBug = DESCRIPTORS$5 && fails$9(function() { - return Object.defineProperty(function() { - }, "prototype", { - value: 42, - writable: false - }).prototype !== 42; -}); -var isObject$3 = isObject$7; -var $String$2 = String; -var $TypeError$4 = TypeError; -var anObject$7 = function(argument) { - if (isObject$3(argument)) return argument; - throw new $TypeError$4($String$2(argument) + " is not an object"); -}; -var DESCRIPTORS$4 = descriptors; -var IE8_DOM_DEFINE = ie8DomDefine; -var V8_PROTOTYPE_DEFINE_BUG$1 = v8PrototypeDefineBug; -var anObject$6 = anObject$7; -var toPropertyKey = toPropertyKey$2; -var $TypeError$3 = TypeError; -var $defineProperty = Object.defineProperty; -var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; -var ENUMERABLE = "enumerable"; -var CONFIGURABLE$1 = "configurable"; -var WRITABLE = "writable"; -objectDefineProperty.f = DESCRIPTORS$4 ? V8_PROTOTYPE_DEFINE_BUG$1 ? function defineProperty(O2, P2, Attributes) { - anObject$6(O2); - P2 = toPropertyKey(P2); - anObject$6(Attributes); - if (typeof O2 === "function" && P2 === "prototype" && "value" in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) { - var current = $getOwnPropertyDescriptor(O2, P2); - if (current && current[WRITABLE]) { - O2[P2] = Attributes.value; - Attributes = { - configurable: CONFIGURABLE$1 in Attributes ? Attributes[CONFIGURABLE$1] : current[CONFIGURABLE$1], - enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE], - writable: false - }; - } + // eslint-disable-next-line no-restricted-syntax + set minX(n) { + this.x = n; } - return $defineProperty(O2, P2, Attributes); -} : $defineProperty : function defineProperty2(O2, P2, Attributes) { - anObject$6(O2); - P2 = toPropertyKey(P2); - anObject$6(Attributes); - if (IE8_DOM_DEFINE) try { - return $defineProperty(O2, P2, Attributes); - } catch (error) { + // eslint-disable-next-line no-restricted-syntax + get midX() { + return this.x + this.w / 2; } - if ("get" in Attributes || "set" in Attributes) throw new $TypeError$3("Accessors not supported"); - if ("value" in Attributes) O2[P2] = Attributes.value; - return O2; -}; -var DESCRIPTORS$3 = descriptors; -var definePropertyModule$3 = objectDefineProperty; -var createPropertyDescriptor = createPropertyDescriptor$2; -var createNonEnumerableProperty$3 = DESCRIPTORS$3 ? function(object2, key, value) { - return definePropertyModule$3.f(object2, key, createPropertyDescriptor(1, value)); -} : function(object2, key, value) { - object2[key] = value; - return object2; -}; -var makeBuiltIn$2 = { exports: {} }; -var DESCRIPTORS$2 = descriptors; -var hasOwn$5 = hasOwnProperty_1; -var FunctionPrototype$1 = Function.prototype; -var getDescriptor = DESCRIPTORS$2 && Object.getOwnPropertyDescriptor; -var EXISTS = hasOwn$5(FunctionPrototype$1, "name"); -var PROPER = EXISTS && (function something() { -}).name === "something"; -var CONFIGURABLE = EXISTS && (!DESCRIPTORS$2 || DESCRIPTORS$2 && getDescriptor(FunctionPrototype$1, "name").configurable); -var functionName = { - EXISTS, - PROPER, - CONFIGURABLE -}; -var uncurryThis$d = functionUncurryThis; -var isCallable$9 = isCallable$f; -var store$1 = sharedStoreExports; -var functionToString = uncurryThis$d(Function.toString); -if (!isCallable$9(store$1.inspectSource)) { - store$1.inspectSource = function(it) { - return functionToString(it); - }; -} -var inspectSource$2 = store$1.inspectSource; -var globalThis$7 = globalThis_1; -var isCallable$8 = isCallable$f; -var WeakMap$2 = globalThis$7.WeakMap; -var weakMapBasicDetection = isCallable$8(WeakMap$2) && /native code/.test(String(WeakMap$2)); -var shared$2 = shared$4; -var uid = uid$2; -var keys = shared$2("keys"); -var sharedKey$2 = function(key) { - return keys[key] || (keys[key] = uid(key)); -}; -var hiddenKeys$4 = {}; -var NATIVE_WEAK_MAP = weakMapBasicDetection; -var globalThis$6 = globalThis_1; -var isObject$2 = isObject$7; -var createNonEnumerableProperty$2 = createNonEnumerableProperty$3; -var hasOwn$4 = hasOwnProperty_1; -var shared$1 = sharedStoreExports; -var sharedKey$1 = sharedKey$2; -var hiddenKeys$3 = hiddenKeys$4; -var OBJECT_ALREADY_INITIALIZED = "Object already initialized"; -var TypeError$1 = globalThis$6.TypeError; -var WeakMap$1 = globalThis$6.WeakMap; -var set, get, has; -var enforce = function(it) { - return has(it) ? get(it) : set(it, {}); -}; -var getterFor = function(TYPE) { - return function(it) { - var state; - if (!isObject$2(it) || (state = get(it)).type !== TYPE) { - throw new TypeError$1("Incompatible receiver, " + TYPE + " required"); - } - return state; - }; -}; -if (NATIVE_WEAK_MAP || shared$1.state) { - var store = shared$1.state || (shared$1.state = new WeakMap$1()); - store.get = store.get; - store.has = store.has; - store.set = store.set; - set = function(it, metadata) { - if (store.has(it)) throw new TypeError$1(OBJECT_ALREADY_INITIALIZED); - metadata.facade = it; - store.set(it, metadata); - return metadata; - }; - get = function(it) { - return store.get(it) || {}; - }; - has = function(it) { - return store.has(it); - }; -} else { - var STATE = sharedKey$1("state"); - hiddenKeys$3[STATE] = true; - set = function(it, metadata) { - if (hasOwn$4(it, STATE)) throw new TypeError$1(OBJECT_ALREADY_INITIALIZED); - metadata.facade = it; - createNonEnumerableProperty$2(it, STATE, metadata); - return metadata; - }; - get = function(it) { - return hasOwn$4(it, STATE) ? it[STATE] : {}; - }; - has = function(it) { - return hasOwn$4(it, STATE); - }; -} -var internalState = { - set, - get, - has, - enforce, - getterFor -}; -var uncurryThis$c = functionUncurryThis; -var fails$8 = fails$f; -var isCallable$7 = isCallable$f; -var hasOwn$3 = hasOwnProperty_1; -var DESCRIPTORS$1 = descriptors; -var CONFIGURABLE_FUNCTION_NAME = functionName.CONFIGURABLE; -var inspectSource$1 = inspectSource$2; -var InternalStateModule = internalState; -var enforceInternalState = InternalStateModule.enforce; -var getInternalState$1 = InternalStateModule.get; -var $String$1 = String; -var defineProperty$1 = Object.defineProperty; -var stringSlice$5 = uncurryThis$c("".slice); -var replace$3 = uncurryThis$c("".replace); -var join = uncurryThis$c([].join); -var CONFIGURABLE_LENGTH = DESCRIPTORS$1 && !fails$8(function() { - return defineProperty$1(function() { - }, "length", { value: 8 }).length !== 8; -}); -var TEMPLATE = String(String).split("String"); -var makeBuiltIn$1 = makeBuiltIn$2.exports = function(value, name, options) { - if (stringSlice$5($String$1(name), 0, 7) === "Symbol(") { - name = "[" + replace$3($String$1(name), /^Symbol\(([^)]*)\).*$/, "$1") + "]"; + // eslint-disable-next-line no-restricted-syntax + get maxX() { + return this.x + this.w; } - if (options && options.getter) name = "get " + name; - if (options && options.setter) name = "set " + name; - if (!hasOwn$3(value, "name") || CONFIGURABLE_FUNCTION_NAME && value.name !== name) { - if (DESCRIPTORS$1) defineProperty$1(value, "name", { value: name, configurable: true }); - else value.name = name; + // eslint-disable-next-line no-restricted-syntax + get minY() { + return this.y; + } + // eslint-disable-next-line no-restricted-syntax + set minY(n) { + this.y = n; + } + // eslint-disable-next-line no-restricted-syntax + get midY() { + return this.y + this.h / 2; + } + // eslint-disable-next-line no-restricted-syntax + get maxY() { + return this.y + this.h; + } + // eslint-disable-next-line no-restricted-syntax + get width() { + return this.w; } - if (CONFIGURABLE_LENGTH && options && hasOwn$3(options, "arity") && value.length !== options.arity) { - defineProperty$1(value, "length", { value: options.arity }); + // eslint-disable-next-line no-restricted-syntax + set width(n) { + this.w = n; } - try { - if (options && hasOwn$3(options, "constructor") && options.constructor) { - if (DESCRIPTORS$1) defineProperty$1(value, "prototype", { writable: false }); - } else if (value.prototype) value.prototype = void 0; - } catch (error) { + // eslint-disable-next-line no-restricted-syntax + get height() { + return this.h; } - var state = enforceInternalState(value); - if (!hasOwn$3(state, "source")) { - state.source = join(TEMPLATE, typeof name == "string" ? name : ""); + // eslint-disable-next-line no-restricted-syntax + set height(n) { + this.h = n; } - return value; -}; -Function.prototype.toString = makeBuiltIn$1(function toString() { - return isCallable$7(this) && getInternalState$1(this).source || inspectSource$1(this); -}, "toString"); -var makeBuiltInExports = makeBuiltIn$2.exports; -var isCallable$6 = isCallable$f; -var definePropertyModule$2 = objectDefineProperty; -var makeBuiltIn = makeBuiltInExports; -var defineGlobalProperty$1 = defineGlobalProperty$3; -var defineBuiltIn$2 = function(O2, key, value, options) { - if (!options) options = {}; - var simple = options.enumerable; - var name = options.name !== void 0 ? options.name : key; - if (isCallable$6(value)) makeBuiltIn(value, name, options); - if (options.global) { - if (simple) O2[key] = value; - else defineGlobalProperty$1(key, value); - } else { - try { - if (!options.unsafe) delete O2[key]; - else if (O2[key]) simple = true; - } catch (error) { - } - if (simple) O2[key] = value; - else definePropertyModule$2.f(O2, key, { - value, - enumerable: false, - configurable: !options.nonConfigurable, - writable: !options.nonWritable - }); + // eslint-disable-next-line no-restricted-syntax + get aspectRatio() { + return this.width / this.height; } - return O2; -}; -var objectGetOwnPropertyNames = {}; -var ceil = Math.ceil; -var floor$2 = Math.floor; -var mathTrunc = Math.trunc || function trunc(x2) { - var n2 = +x2; - return (n2 > 0 ? floor$2 : ceil)(n2); -}; -var trunc2 = mathTrunc; -var toIntegerOrInfinity$7 = function(argument) { - var number2 = +argument; - return number2 !== number2 || number2 === 0 ? 0 : trunc2(number2); -}; -var toIntegerOrInfinity$6 = toIntegerOrInfinity$7; -var max$3 = Math.max; -var min$4 = Math.min; -var toAbsoluteIndex$1 = function(index2, length) { - var integer2 = toIntegerOrInfinity$6(index2); - return integer2 < 0 ? max$3(integer2 + length, 0) : min$4(integer2, length); -}; -var toIntegerOrInfinity$5 = toIntegerOrInfinity$7; -var min$3 = Math.min; -var toLength$2 = function(argument) { - var len = toIntegerOrInfinity$5(argument); - return len > 0 ? min$3(len, 9007199254740991) : 0; -}; -var toLength$1 = toLength$2; -var lengthOfArrayLike$5 = function(obj) { - return toLength$1(obj.length); -}; -var toIndexedObject$2 = toIndexedObject$4; -var toAbsoluteIndex = toAbsoluteIndex$1; -var lengthOfArrayLike$4 = lengthOfArrayLike$5; -var createMethod$1 = function(IS_INCLUDES) { - return function($this, el2, fromIndex) { - var O2 = toIndexedObject$2($this); - var length = lengthOfArrayLike$4(O2); - if (length === 0) return !IS_INCLUDES && -1; - var index2 = toAbsoluteIndex(fromIndex, length); - var value; - if (IS_INCLUDES && el2 !== el2) while (length > index2) { - value = O2[index2++]; - if (value !== value) return true; - } - else for (; length > index2; index2++) { - if ((IS_INCLUDES || index2 in O2) && O2[index2] === el2) return IS_INCLUDES || index2 || 0; - } - return !IS_INCLUDES && -1; - }; -}; -var arrayIncludes = { - // `Array.prototype.includes` method - // https://tc39.es/ecma262/#sec-array.prototype.includes - includes: createMethod$1(true), - // `Array.prototype.indexOf` method - // https://tc39.es/ecma262/#sec-array.prototype.indexof - indexOf: createMethod$1(false) -}; -var uncurryThis$b = functionUncurryThis; -var hasOwn$2 = hasOwnProperty_1; -var toIndexedObject$1 = toIndexedObject$4; -var indexOf$2 = arrayIncludes.indexOf; -var hiddenKeys$2 = hiddenKeys$4; -var push$1 = uncurryThis$b([].push); -var objectKeysInternal = function(object2, names) { - var O2 = toIndexedObject$1(object2); - var i2 = 0; - var result = []; - var key; - for (key in O2) !hasOwn$2(hiddenKeys$2, key) && hasOwn$2(O2, key) && push$1(result, key); - while (names.length > i2) if (hasOwn$2(O2, key = names[i2++])) { - ~indexOf$2(result, key) || push$1(result, key); + // eslint-disable-next-line no-restricted-syntax + get center() { + return new Vec(this.midX, this.midY); } - return result; -}; -var enumBugKeys$3 = [ - "constructor", - "hasOwnProperty", - "isPrototypeOf", - "propertyIsEnumerable", - "toLocaleString", - "toString", - "valueOf" -]; -var internalObjectKeys$1 = objectKeysInternal; -var enumBugKeys$2 = enumBugKeys$3; -var hiddenKeys$1 = enumBugKeys$2.concat("length", "prototype"); -objectGetOwnPropertyNames.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O2) { - return internalObjectKeys$1(O2, hiddenKeys$1); -}; -var objectGetOwnPropertySymbols = {}; -objectGetOwnPropertySymbols.f = Object.getOwnPropertySymbols; -var getBuiltIn$2 = getBuiltIn$4; -var uncurryThis$a = functionUncurryThis; -var getOwnPropertyNamesModule = objectGetOwnPropertyNames; -var getOwnPropertySymbolsModule = objectGetOwnPropertySymbols; -var anObject$5 = anObject$7; -var concat$1 = uncurryThis$a([].concat); -var ownKeys$3 = getBuiltIn$2("Reflect", "ownKeys") || function ownKeys(it) { - var keys3 = getOwnPropertyNamesModule.f(anObject$5(it)); - var getOwnPropertySymbols = getOwnPropertySymbolsModule.f; - return getOwnPropertySymbols ? concat$1(keys3, getOwnPropertySymbols(it)) : keys3; -}; -var hasOwn$1 = hasOwnProperty_1; -var ownKeys$2 = ownKeys$3; -var getOwnPropertyDescriptorModule = objectGetOwnPropertyDescriptor; -var definePropertyModule$1 = objectDefineProperty; -var copyConstructorProperties$1 = function(target, source, exceptions) { - var keys3 = ownKeys$2(source); - var defineProperty4 = definePropertyModule$1.f; - var getOwnPropertyDescriptor3 = getOwnPropertyDescriptorModule.f; - for (var i2 = 0; i2 < keys3.length; i2++) { - var key = keys3[i2]; - if (!hasOwn$1(target, key) && !(exceptions && hasOwn$1(exceptions, key))) { - defineProperty4(target, key, getOwnPropertyDescriptor3(source, key)); - } + // eslint-disable-next-line no-restricted-syntax + set center(v2) { + this.minX = v2.x - this.width / 2; + this.minY = v2.y - this.height / 2; } -}; -var fails$7 = fails$f; -var isCallable$5 = isCallable$f; -var replacement = /#|\.prototype\./; -var isForced$1 = function(feature, detection) { - var value = data[normalize(feature)]; - return value === POLYFILL ? true : value === NATIVE ? false : isCallable$5(detection) ? fails$7(detection) : !!detection; -}; -var normalize = isForced$1.normalize = function(string2) { - return String(string2).replace(replacement, ".").toLowerCase(); -}; -var data = isForced$1.data = {}; -var NATIVE = isForced$1.NATIVE = "N"; -var POLYFILL = isForced$1.POLYFILL = "P"; -var isForced_1 = isForced$1; -var globalThis$5 = globalThis_1; -var getOwnPropertyDescriptor2 = objectGetOwnPropertyDescriptor.f; -var createNonEnumerableProperty$1 = createNonEnumerableProperty$3; -var defineBuiltIn$1 = defineBuiltIn$2; -var defineGlobalProperty = defineGlobalProperty$3; -var copyConstructorProperties = copyConstructorProperties$1; -var isForced = isForced_1; -var _export = function(options, source) { - var TARGET = options.target; - var GLOBAL = options.global; - var STATIC = options.stat; - var FORCED2, target, key, targetProperty, sourceProperty, descriptor; - if (GLOBAL) { - target = globalThis$5; - } else if (STATIC) { - target = globalThis$5[TARGET] || defineGlobalProperty(TARGET, {}); - } else { - target = globalThis$5[TARGET] && globalThis$5[TARGET].prototype; + // eslint-disable-next-line no-restricted-syntax + get corners() { + return [ + new Vec(this.minX, this.minY), + new Vec(this.maxX, this.minY), + new Vec(this.maxX, this.maxY), + new Vec(this.minX, this.maxY) + ]; } - if (target) for (key in source) { - sourceProperty = source[key]; - if (options.dontCallGetSet) { - descriptor = getOwnPropertyDescriptor2(target, key); - targetProperty = descriptor && descriptor.value; - } else targetProperty = target[key]; - FORCED2 = isForced(GLOBAL ? key : TARGET + (STATIC ? "." : "#") + key, options.forced); - if (!FORCED2 && targetProperty !== void 0) { - if (typeof sourceProperty == typeof targetProperty) continue; - copyConstructorProperties(sourceProperty, targetProperty); - } - if (options.sham || targetProperty && targetProperty.sham) { - createNonEnumerableProperty$1(sourceProperty, "sham", true); - } - defineBuiltIn$1(target, key, sourceProperty, options); + // eslint-disable-next-line no-restricted-syntax + get cornersAndCenter() { + return [ + new Vec(this.minX, this.minY), + new Vec(this.maxX, this.minY), + new Vec(this.maxX, this.maxY), + new Vec(this.minX, this.maxY), + this.center + ]; } -}; -var objectDefineProperties = {}; -var internalObjectKeys = objectKeysInternal; -var enumBugKeys$1 = enumBugKeys$3; -var objectKeys$1 = Object.keys || function keys2(O2) { - return internalObjectKeys(O2, enumBugKeys$1); -}; -var DESCRIPTORS = descriptors; -var V8_PROTOTYPE_DEFINE_BUG = v8PrototypeDefineBug; -var definePropertyModule = objectDefineProperty; -var anObject$4 = anObject$7; -var toIndexedObject = toIndexedObject$4; -var objectKeys = objectKeys$1; -objectDefineProperties.f = DESCRIPTORS && !V8_PROTOTYPE_DEFINE_BUG ? Object.defineProperties : function defineProperties(O2, Properties) { - anObject$4(O2); - var props = toIndexedObject(Properties); - var keys3 = objectKeys(Properties); - var length = keys3.length; - var index2 = 0; - var key; - while (length > index2) definePropertyModule.f(O2, key = keys3[index2++], props[key]); - return O2; -}; -var getBuiltIn$1 = getBuiltIn$4; -var html$1 = getBuiltIn$1("document", "documentElement"); -var anObject$3 = anObject$7; -var definePropertiesModule = objectDefineProperties; -var enumBugKeys = enumBugKeys$3; -var hiddenKeys = hiddenKeys$4; -var html = html$1; -var documentCreateElement = documentCreateElement$1; -var sharedKey = sharedKey$2; -var GT = ">"; -var LT = "<"; -var PROTOTYPE = "prototype"; -var SCRIPT = "script"; -var IE_PROTO = sharedKey("IE_PROTO"); -var EmptyConstructor = function() { -}; -var scriptTag = function(content) { - return LT + SCRIPT + GT + content + LT + "/" + SCRIPT + GT; -}; -var NullProtoObjectViaActiveX = function(activeXDocument2) { - activeXDocument2.write(scriptTag("")); - activeXDocument2.close(); - var temp = activeXDocument2.parentWindow.Object; - activeXDocument2 = null; - return temp; -}; -var NullProtoObjectViaIFrame = function() { - var iframe = documentCreateElement("iframe"); - var JS = "java" + SCRIPT + ":"; - var iframeDocument; - iframe.style.display = "none"; - html.appendChild(iframe); - iframe.src = String(JS); - iframeDocument = iframe.contentWindow.document; - iframeDocument.open(); - iframeDocument.write(scriptTag("document.F=Object")); - iframeDocument.close(); - return iframeDocument.F; -}; -var activeXDocument; -var NullProtoObject = function() { - try { - activeXDocument = new ActiveXObject("htmlfile"); - } catch (error) { + // eslint-disable-next-line no-restricted-syntax + get sides() { + const { corners } = this; + return [ + [corners[0], corners[1]], + [corners[1], corners[2]], + [corners[2], corners[3]], + [corners[3], corners[0]] + ]; } - NullProtoObject = typeof document != "undefined" ? document.domain && activeXDocument ? NullProtoObjectViaActiveX(activeXDocument) : NullProtoObjectViaIFrame() : NullProtoObjectViaActiveX(activeXDocument); - var length = enumBugKeys.length; - while (length--) delete NullProtoObject[PROTOTYPE][enumBugKeys[length]]; - return NullProtoObject(); -}; -hiddenKeys[IE_PROTO] = true; -var objectCreate = Object.create || function create(O2, Properties) { - var result; - if (O2 !== null) { - EmptyConstructor[PROTOTYPE] = anObject$3(O2); - result = new EmptyConstructor(); - EmptyConstructor[PROTOTYPE] = null; - result[IE_PROTO] = O2; - } else result = NullProtoObject(); - return Properties === void 0 ? result : definePropertiesModule.f(result, Properties); -}; -var wellKnownSymbol$7 = wellKnownSymbol$9; -var create$1 = objectCreate; -var defineProperty3 = objectDefineProperty.f; -var UNSCOPABLES = wellKnownSymbol$7("unscopables"); -var ArrayPrototype = Array.prototype; -if (ArrayPrototype[UNSCOPABLES] === void 0) { - defineProperty3(ArrayPrototype, UNSCOPABLES, { - configurable: true, - value: create$1(null) - }); -} -var addToUnscopables$3 = function(key) { - ArrayPrototype[UNSCOPABLES][key] = true; -}; -var $$6 = _export; -var toObject$3 = toObject$5; -var lengthOfArrayLike$3 = lengthOfArrayLike$5; -var toIntegerOrInfinity$4 = toIntegerOrInfinity$7; -var addToUnscopables$2 = addToUnscopables$3; -$$6({ target: "Array", proto: true }, { - at: function at(index2) { - var O2 = toObject$3(this); - var len = lengthOfArrayLike$3(O2); - var relativeIndex = toIntegerOrInfinity$4(index2); - var k2 = relativeIndex >= 0 ? relativeIndex : len + relativeIndex; - return k2 < 0 || k2 >= len ? void 0 : O2[k2]; + // eslint-disable-next-line no-restricted-syntax + get size() { + return new Vec(this.w, this.h); } -}); -addToUnscopables$2("at"); -var globalThis$4 = globalThis_1; -var uncurryThis$9 = functionUncurryThis; -var entryUnbind$5 = function(CONSTRUCTOR, METHOD) { - return uncurryThis$9(globalThis$4[CONSTRUCTOR].prototype[METHOD]); -}; -var entryUnbind$4 = entryUnbind$5; -entryUnbind$4("Array", "at"); -var classof$5 = classofRaw$2; -var isArray$2 = Array.isArray || function isArray(argument) { - return classof$5(argument) === "Array"; -}; -var $TypeError$2 = TypeError; -var MAX_SAFE_INTEGER = 9007199254740991; -var doesNotExceedSafeInteger$1 = function(it) { - if (it > MAX_SAFE_INTEGER) throw $TypeError$2("Maximum allowed index exceeded"); - return it; -}; -var classofRaw$1 = classofRaw$2; -var uncurryThis$8 = functionUncurryThis; -var functionUncurryThisClause = function(fn) { - if (classofRaw$1(fn) === "Function") return uncurryThis$8(fn); -}; -var uncurryThis$7 = functionUncurryThisClause; -var aCallable$1 = aCallable$3; -var NATIVE_BIND$1 = functionBindNative; -var bind$1 = uncurryThis$7(uncurryThis$7.bind); -var functionBindContext = function(fn, that) { - aCallable$1(fn); - return that === void 0 ? fn : NATIVE_BIND$1 ? bind$1(fn, that) : function() { - return fn.apply(that, arguments); - }; -}; -var isArray$1 = isArray$2; -var lengthOfArrayLike$2 = lengthOfArrayLike$5; -var doesNotExceedSafeInteger = doesNotExceedSafeInteger$1; -var bind = functionBindContext; -var flattenIntoArray$2 = function(target, original, source, sourceLen, start, depth, mapper, thisArg) { - var targetIndex = start; - var sourceIndex = 0; - var mapFn = mapper ? bind(mapper, thisArg) : false; - var element, elementLen; - while (sourceIndex < sourceLen) { - if (sourceIndex in source) { - element = mapFn ? mapFn(source[sourceIndex], sourceIndex, original) : source[sourceIndex]; - if (depth > 0 && isArray$1(element)) { - elementLen = lengthOfArrayLike$2(element); - targetIndex = flattenIntoArray$2(target, original, element, elementLen, targetIndex, depth - 1) - 1; - } else { - doesNotExceedSafeInteger(targetIndex + 1); - target[targetIndex] = element; - } - targetIndex++; - } - sourceIndex++; + toFixed() { + this.x = toPrecision(this.x); + this.y = toPrecision(this.y); + this.w = toPrecision(this.w); + this.h = toPrecision(this.h); + return this; } - return targetIndex; -}; -var flattenIntoArray_1 = flattenIntoArray$2; -var wellKnownSymbol$6 = wellKnownSymbol$9; -var TO_STRING_TAG$1 = wellKnownSymbol$6("toStringTag"); -var test = {}; -test[TO_STRING_TAG$1] = "z"; -var toStringTagSupport = String(test) === "[object z]"; -var TO_STRING_TAG_SUPPORT = toStringTagSupport; -var isCallable$4 = isCallable$f; -var classofRaw = classofRaw$2; -var wellKnownSymbol$5 = wellKnownSymbol$9; -var TO_STRING_TAG = wellKnownSymbol$5("toStringTag"); -var $Object = Object; -var CORRECT_ARGUMENTS = classofRaw(/* @__PURE__ */ function() { - return arguments; -}()) === "Arguments"; -var tryGet = function(it, key) { - try { - return it[key]; - } catch (error) { + setTo(B2) { + this.x = B2.x; + this.y = B2.y; + this.w = B2.w; + this.h = B2.h; + return this; } -}; -var classof$4 = TO_STRING_TAG_SUPPORT ? classofRaw : function(it) { - var O2, tag, result; - return it === void 0 ? "Undefined" : it === null ? "Null" : typeof (tag = tryGet(O2 = $Object(it), TO_STRING_TAG)) == "string" ? tag : CORRECT_ARGUMENTS ? classofRaw(O2) : (result = classofRaw(O2)) === "Object" && isCallable$4(O2.callee) ? "Arguments" : result; -}; -var uncurryThis$6 = functionUncurryThis; -var fails$6 = fails$f; -var isCallable$3 = isCallable$f; -var classof$3 = classof$4; -var getBuiltIn = getBuiltIn$4; -var inspectSource = inspectSource$2; -var noop$1 = function() { -}; -var construct = getBuiltIn("Reflect", "construct"); -var constructorRegExp = /^\s*(?:class|function)\b/; -var exec$1 = uncurryThis$6(constructorRegExp.exec); -var INCORRECT_TO_STRING = !constructorRegExp.test(noop$1); -var isConstructorModern = function isConstructor(argument) { - if (!isCallable$3(argument)) return false; - try { - construct(noop$1, [], argument); - return true; - } catch (error) { - return false; + set(x2 = 0, y2 = 0, w2 = 0, h2 = 0) { + this.x = x2; + this.y = y2; + this.w = w2; + this.h = h2; + return this; } -}; -var isConstructorLegacy = function isConstructor2(argument) { - if (!isCallable$3(argument)) return false; - switch (classof$3(argument)) { - case "AsyncFunction": - case "GeneratorFunction": - case "AsyncGeneratorFunction": - return false; + expand(A) { + const minX = Math.min(this.minX, A.minX); + const minY = Math.min(this.minY, A.minY); + const maxX = Math.max(this.maxX, A.maxX); + const maxY = Math.max(this.maxY, A.maxY); + this.x = minX; + this.y = minY; + this.w = maxX - minX; + this.h = maxY - minY; + return this; } - try { - return INCORRECT_TO_STRING || !!exec$1(constructorRegExp, inspectSource(argument)); - } catch (error) { - return true; + expandBy(n) { + this.x -= n; + this.y -= n; + this.w += n * 2; + this.h += n * 2; + return this; } -}; -isConstructorLegacy.sham = true; -var isConstructor$1 = !construct || fails$6(function() { - var called; - return isConstructorModern(isConstructorModern.call) || !isConstructorModern(Object) || !isConstructorModern(function() { - called = true; - }) || called; -}) ? isConstructorLegacy : isConstructorModern; -var isArray2 = isArray$2; -var isConstructor3 = isConstructor$1; -var isObject$1 = isObject$7; -var wellKnownSymbol$4 = wellKnownSymbol$9; -var SPECIES$1 = wellKnownSymbol$4("species"); -var $Array = Array; -var arraySpeciesConstructor$1 = function(originalArray) { - var C2; - if (isArray2(originalArray)) { - C2 = originalArray.constructor; - if (isConstructor3(C2) && (C2 === $Array || isArray2(C2.prototype))) C2 = void 0; - else if (isObject$1(C2)) { - C2 = C2[SPECIES$1]; - if (C2 === null) C2 = void 0; - } + scale(n) { + this.x /= n; + this.y /= n; + this.w /= n; + this.h /= n; + return this; } - return C2 === void 0 ? $Array : C2; -}; -var arraySpeciesConstructor = arraySpeciesConstructor$1; -var arraySpeciesCreate$2 = function(originalArray, length) { - return new (arraySpeciesConstructor(originalArray))(length === 0 ? 0 : length); -}; -var $$5 = _export; -var flattenIntoArray$1 = flattenIntoArray_1; -var aCallable = aCallable$3; -var toObject$2 = toObject$5; -var lengthOfArrayLike$1 = lengthOfArrayLike$5; -var arraySpeciesCreate$1 = arraySpeciesCreate$2; -$$5({ target: "Array", proto: true }, { - flatMap: function flatMap(callbackfn) { - var O2 = toObject$2(this); - var sourceLen = lengthOfArrayLike$1(O2); - var A2; - aCallable(callbackfn); - A2 = arraySpeciesCreate$1(O2, 0); - A2.length = flattenIntoArray$1(A2, O2, O2, sourceLen, 0, 1, callbackfn, arguments.length > 1 ? arguments[1] : void 0); - return A2; + clone() { + const { x: x2, y: y2, w: w2, h: h2 } = this; + return new Box(x2, y2, w2, h2); } -}); -var addToUnscopables$1 = addToUnscopables$3; -addToUnscopables$1("flatMap"); -var entryUnbind$3 = entryUnbind$5; -entryUnbind$3("Array", "flatMap"); -var $$4 = _export; -var flattenIntoArray = flattenIntoArray_1; -var toObject$1 = toObject$5; -var lengthOfArrayLike = lengthOfArrayLike$5; -var toIntegerOrInfinity$3 = toIntegerOrInfinity$7; -var arraySpeciesCreate = arraySpeciesCreate$2; -$$4({ target: "Array", proto: true }, { - flat: function flat() { - var depthArg = arguments.length ? arguments[0] : void 0; - var O2 = toObject$1(this); - var sourceLen = lengthOfArrayLike(O2); - var A2 = arraySpeciesCreate(O2, 0); - A2.length = flattenIntoArray(A2, O2, O2, sourceLen, 0, depthArg === void 0 ? 1 : toIntegerOrInfinity$3(depthArg)); - return A2; + translate(delta) { + this.x += delta.x; + this.y += delta.y; + return this; } -}); -var addToUnscopables = addToUnscopables$3; -addToUnscopables("flat"); -var entryUnbind$2 = entryUnbind$5; -entryUnbind$2("Array", "flat"); -var classof$2 = classof$4; -var $String = String; -var toString$5 = function(argument) { - if (classof$2(argument) === "Symbol") throw new TypeError("Cannot convert a Symbol value to a string"); - return $String(argument); -}; -var $$3 = _export; -var uncurryThis$5 = functionUncurryThis; -var requireObjectCoercible$3 = requireObjectCoercible$6; -var toIntegerOrInfinity$2 = toIntegerOrInfinity$7; -var toString$4 = toString$5; -var fails$5 = fails$f; -var charAt$4 = uncurryThis$5("".charAt); -var FORCED = fails$5(function() { - return "𠮷".at(-2) !== "\uD842"; -}); -$$3({ target: "String", proto: true, forced: FORCED }, { - at: function at2(index2) { - var S2 = toString$4(requireObjectCoercible$3(this)); - var len = S2.length; - var relativeIndex = toIntegerOrInfinity$2(index2); - var k2 = relativeIndex >= 0 ? relativeIndex : len + relativeIndex; - return k2 < 0 || k2 >= len ? void 0 : charAt$4(S2, k2); + snapToGrid(size2) { + const minX = Math.round(this.minX / size2) * size2; + const minY = Math.round(this.minY / size2) * size2; + const maxX = Math.round(this.maxX / size2) * size2; + const maxY = Math.round(this.maxY / size2) * size2; + this.minX = minX; + this.minY = minY; + this.width = Math.max(1, maxX - minX); + this.height = Math.max(1, maxY - minY); } -}); -var entryUnbind$1 = entryUnbind$5; -entryUnbind$1("String", "at"); -var anObject$2 = anObject$7; -var regexpFlags$1 = function() { - var that = anObject$2(this); - var result = ""; - if (that.hasIndices) result += "d"; - if (that.global) result += "g"; - if (that.ignoreCase) result += "i"; - if (that.multiline) result += "m"; - if (that.dotAll) result += "s"; - if (that.unicode) result += "u"; - if (that.unicodeSets) result += "v"; - if (that.sticky) result += "y"; - return result; -}; -var fails$4 = fails$f; -var globalThis$3 = globalThis_1; -var $RegExp$2 = globalThis$3.RegExp; -var UNSUPPORTED_Y$1 = fails$4(function() { - var re2 = $RegExp$2("a", "y"); - re2.lastIndex = 2; - return re2.exec("abcd") !== null; -}); -var MISSED_STICKY = UNSUPPORTED_Y$1 || fails$4(function() { - return !$RegExp$2("a", "y").sticky; -}); -var BROKEN_CARET = UNSUPPORTED_Y$1 || fails$4(function() { - var re2 = $RegExp$2("^r", "gy"); - re2.lastIndex = 2; - return re2.exec("str") !== null; -}); -var regexpStickyHelpers = { - BROKEN_CARET, - MISSED_STICKY, - UNSUPPORTED_Y: UNSUPPORTED_Y$1 -}; -var fails$3 = fails$f; -var globalThis$2 = globalThis_1; -var $RegExp$1 = globalThis$2.RegExp; -var regexpUnsupportedDotAll = fails$3(function() { - var re2 = $RegExp$1(".", "s"); - return !(re2.dotAll && re2.test("\n") && re2.flags === "s"); -}); -var fails$2 = fails$f; -var globalThis$1 = globalThis_1; -var $RegExp = globalThis$1.RegExp; -var regexpUnsupportedNcg = fails$2(function() { - var re2 = $RegExp("(?b)", "g"); - return re2.exec("b").groups.a !== "b" || "b".replace(re2, "$c") !== "bc"; -}); -var call$7 = functionCall; -var uncurryThis$4 = functionUncurryThis; -var toString$3 = toString$5; -var regexpFlags = regexpFlags$1; -var stickyHelpers = regexpStickyHelpers; -var shared = shared$4; -var create2 = objectCreate; -var getInternalState = internalState.get; -var UNSUPPORTED_DOT_ALL = regexpUnsupportedDotAll; -var UNSUPPORTED_NCG = regexpUnsupportedNcg; -var nativeReplace = shared("native-string-replace", String.prototype.replace); -var nativeExec = RegExp.prototype.exec; -var patchedExec = nativeExec; -var charAt$3 = uncurryThis$4("".charAt); -var indexOf$1 = uncurryThis$4("".indexOf); -var replace$2 = uncurryThis$4("".replace); -var stringSlice$4 = uncurryThis$4("".slice); -var UPDATES_LAST_INDEX_WRONG = function() { - var re1 = /a/; - var re2 = /b*/g; - call$7(nativeExec, re1, "a"); - call$7(nativeExec, re2, "a"); - return re1.lastIndex !== 0 || re2.lastIndex !== 0; -}(); -var UNSUPPORTED_Y = stickyHelpers.BROKEN_CARET; -var NPCG_INCLUDED = /()??/.exec("")[1] !== void 0; -var PATCH = UPDATES_LAST_INDEX_WRONG || NPCG_INCLUDED || UNSUPPORTED_Y || UNSUPPORTED_DOT_ALL || UNSUPPORTED_NCG; -if (PATCH) { - patchedExec = function exec2(string2) { - var re2 = this; - var state = getInternalState(re2); - var str = toString$3(string2); - var raw = state.raw; - var result, reCopy, lastIndex, match2, i2, object2, group; - if (raw) { - raw.lastIndex = re2.lastIndex; - result = call$7(patchedExec, raw, str); - re2.lastIndex = raw.lastIndex; - return result; + collides(B2) { + return Box.Collides(this, B2); + } + contains(B2) { + return Box.Contains(this, B2); + } + includes(B2) { + return Box.Includes(this, B2); + } + containsPoint(V2, margin = 0) { + return Box.ContainsPoint(this, V2, margin); + } + getHandlePoint(handle) { + switch (handle) { + case "top_left": + return new Vec(this.minX, this.minY); + case "top_right": + return new Vec(this.maxX, this.minY); + case "bottom_left": + return new Vec(this.minX, this.maxY); + case "bottom_right": + return new Vec(this.maxX, this.maxY); + case "top": + return new Vec(this.midX, this.minY); + case "right": + return new Vec(this.maxX, this.midY); + case "bottom": + return new Vec(this.midX, this.maxY); + case "left": + return new Vec(this.minX, this.midY); } - var groups = state.groups; - var sticky = UNSUPPORTED_Y && re2.sticky; - var flags = call$7(regexpFlags, re2); - var source = re2.source; - var charsAdded = 0; - var strCopy = str; - if (sticky) { - flags = replace$2(flags, "y", ""); - if (indexOf$1(flags, "g") === -1) { - flags += "g"; + } + toJson() { + return { x: this.minX, y: this.minY, w: this.w, h: this.h }; + } + resize(handle, dx, dy) { + const { minX: a0x, minY: a0y, maxX: a1x, maxY: a1y } = this; + let { minX: b0x, minY: b0y, maxX: b1x, maxY: b1y } = this; + switch (handle) { + case "left": + case "top_left": + case "bottom_left": { + b0x += dx; + break; } - strCopy = stringSlice$4(str, re2.lastIndex); - if (re2.lastIndex > 0 && (!re2.multiline || re2.multiline && charAt$3(str, re2.lastIndex - 1) !== "\n")) { - source = "(?: " + source + ")"; - strCopy = " " + strCopy; - charsAdded++; + case "right": + case "top_right": + case "bottom_right": { + b1x += dx; + break; } - reCopy = new RegExp("^(?:" + source + ")", flags); - } - if (NPCG_INCLUDED) { - reCopy = new RegExp("^" + source + "$(?!\\s)", flags); - } - if (UPDATES_LAST_INDEX_WRONG) lastIndex = re2.lastIndex; - match2 = call$7(nativeExec, sticky ? reCopy : re2, strCopy); - if (sticky) { - if (match2) { - match2.input = stringSlice$4(match2.input, charsAdded); - match2[0] = stringSlice$4(match2[0], charsAdded); - match2.index = re2.lastIndex; - re2.lastIndex += match2[0].length; - } else re2.lastIndex = 0; - } else if (UPDATES_LAST_INDEX_WRONG && match2) { - re2.lastIndex = re2.global ? match2.index + match2[0].length : lastIndex; - } - if (NPCG_INCLUDED && match2 && match2.length > 1) { - call$7(nativeReplace, match2[0], reCopy, function() { - for (i2 = 1; i2 < arguments.length - 2; i2++) { - if (arguments[i2] === void 0) match2[i2] = void 0; - } - }); } - if (match2 && groups) { - match2.groups = object2 = create2(null); - for (i2 = 0; i2 < groups.length; i2++) { - group = groups[i2]; - object2[group[0]] = match2[group[1]]; + switch (handle) { + case "top": + case "top_left": + case "top_right": { + b0y += dy; + break; + } + case "bottom": + case "bottom_left": + case "bottom_right": { + b1y += dy; + break; } } - return match2; - }; -} -var regexpExec$2 = patchedExec; -var $$2 = _export; -var exec = regexpExec$2; -$$2({ target: "RegExp", proto: true, forced: /./.exec !== exec }, { - exec -}); -var NATIVE_BIND = functionBindNative; -var FunctionPrototype = Function.prototype; -var apply$1 = FunctionPrototype.apply; -var call$6 = FunctionPrototype.call; -var functionApply = typeof Reflect == "object" && Reflect.apply || (NATIVE_BIND ? call$6.bind(apply$1) : function() { - return call$6.apply(apply$1, arguments); -}); -var call$5 = functionCall; -var defineBuiltIn = defineBuiltIn$2; -var regexpExec$1 = regexpExec$2; -var fails$1 = fails$f; -var wellKnownSymbol$3 = wellKnownSymbol$9; -var createNonEnumerableProperty = createNonEnumerableProperty$3; -var SPECIES = wellKnownSymbol$3("species"); -var RegExpPrototype$1 = RegExp.prototype; -var fixRegexpWellKnownSymbolLogic = function(KEY, exec2, FORCED2, SHAM) { - var SYMBOL = wellKnownSymbol$3(KEY); - var DELEGATES_TO_SYMBOL = !fails$1(function() { - var O2 = {}; - O2[SYMBOL] = function() { - return 7; - }; - return ""[KEY](O2) !== 7; - }); - var DELEGATES_TO_EXEC = DELEGATES_TO_SYMBOL && !fails$1(function() { - var execCalled = false; - var re2 = /a/; - if (KEY === "split") { - re2 = {}; - re2.constructor = {}; - re2.constructor[SPECIES] = function() { - return re2; - }; - re2.flags = ""; - re2[SYMBOL] = /./[SYMBOL]; + const scaleX = (b1x - b0x) / (a1x - a0x); + const scaleY = (b1y - b0y) / (a1y - a0y); + const flipX = scaleX < 0; + const flipY = scaleY < 0; + if (flipX) { + const t2 = b1x; + b1x = b0x; + b0x = t2; } - re2.exec = function() { - execCalled = true; - return null; - }; - re2[SYMBOL](""); - return !execCalled; - }); - if (!DELEGATES_TO_SYMBOL || !DELEGATES_TO_EXEC || FORCED2) { - var nativeRegExpMethod = /./[SYMBOL]; - var methods = exec2(SYMBOL, ""[KEY], function(nativeMethod, regexp, str, arg2, forceStringMethod) { - var $exec = regexp.exec; - if ($exec === regexpExec$1 || $exec === RegExpPrototype$1.exec) { - if (DELEGATES_TO_SYMBOL && !forceStringMethod) { - return { done: true, value: call$5(nativeRegExpMethod, regexp, str, arg2) }; - } - return { done: true, value: call$5(nativeMethod, str, regexp, arg2) }; - } - return { done: false }; - }); - defineBuiltIn(String.prototype, KEY, methods[0]); - defineBuiltIn(RegExpPrototype$1, SYMBOL, methods[1]); + if (flipY) { + const t2 = b1y; + b1y = b0y; + b0y = t2; + } + this.minX = b0x; + this.minY = b0y; + this.width = Math.abs(b1x - b0x); + this.height = Math.abs(b1y - b0y); } - if (SHAM) createNonEnumerableProperty(RegExpPrototype$1[SYMBOL], "sham", true); -}; -var uncurryThis$3 = functionUncurryThis; -var toIntegerOrInfinity$1 = toIntegerOrInfinity$7; -var toString$2 = toString$5; -var requireObjectCoercible$2 = requireObjectCoercible$6; -var charAt$2 = uncurryThis$3("".charAt); -var charCodeAt = uncurryThis$3("".charCodeAt); -var stringSlice$3 = uncurryThis$3("".slice); -var createMethod = function(CONVERT_TO_STRING) { - return function($this, pos) { - var S2 = toString$2(requireObjectCoercible$2($this)); - var position = toIntegerOrInfinity$1(pos); - var size2 = S2.length; - var first, second; - if (position < 0 || position >= size2) return CONVERT_TO_STRING ? "" : void 0; - first = charCodeAt(S2, position); - return first < 55296 || first > 56319 || position + 1 === size2 || (second = charCodeAt(S2, position + 1)) < 56320 || second > 57343 ? CONVERT_TO_STRING ? charAt$2(S2, position) : first : CONVERT_TO_STRING ? stringSlice$3(S2, position, position + 2) : (first - 55296 << 10) + (second - 56320) + 65536; - }; -}; -var stringMultibyte = { - // `String.prototype.codePointAt` method - // https://tc39.es/ecma262/#sec-string.prototype.codepointat - codeAt: createMethod(false), - // `String.prototype.at` method - // https://github.com/mathiasbynens/String.prototype.at - charAt: createMethod(true) -}; -var charAt$1 = stringMultibyte.charAt; -var advanceStringIndex$1 = function(S2, index2, unicode) { - return index2 + (unicode ? charAt$1(S2, index2).length : 1); -}; -var uncurryThis$2 = functionUncurryThis; -var toObject = toObject$5; -var floor$1 = Math.floor; -var charAt = uncurryThis$2("".charAt); -var replace$1 = uncurryThis$2("".replace); -var stringSlice$2 = uncurryThis$2("".slice); -var SUBSTITUTION_SYMBOLS = /\$([$&'`]|\d{1,2}|<[^>]*>)/g; -var SUBSTITUTION_SYMBOLS_NO_NAMED = /\$([$&'`]|\d{1,2})/g; -var getSubstitution$2 = function(matched, str, position, captures, namedCaptures, replacement2) { - var tailPos = position + matched.length; - var m2 = captures.length; - var symbols = SUBSTITUTION_SYMBOLS_NO_NAMED; - if (namedCaptures !== void 0) { - namedCaptures = toObject(namedCaptures); - symbols = SUBSTITUTION_SYMBOLS; + union(box) { + const minX = Math.min(this.minX, box.x); + const minY = Math.min(this.minY, box.y); + const maxX = Math.max(this.maxX, box.w + box.x); + const maxY = Math.max(this.maxY, box.h + box.y); + this.x = minX; + this.y = minY; + this.width = maxX - minX; + this.height = maxY - minY; + return this; } - return replace$1(replacement2, symbols, function(match2, ch2) { - var capture; - switch (charAt(ch2, 0)) { - case "$": - return "$"; - case "&": - return matched; - case "`": - return stringSlice$2(str, 0, position); - case "'": - return stringSlice$2(str, tailPos); - case "<": - capture = namedCaptures[stringSlice$2(ch2, 1, -1)]; - break; - default: - var n2 = +ch2; - if (n2 === 0) return match2; - if (n2 > m2) { - var f2 = floor$1(n2 / 10); - if (f2 === 0) return match2; - if (f2 <= m2) return captures[f2 - 1] === void 0 ? charAt(ch2, 1) : captures[f2 - 1] + charAt(ch2, 1); - return match2; - } - capture = captures[n2 - 1]; + static From(box) { + return new Box(box.x, box.y, box.w, box.h); + } + static FromCenter(center, size2) { + return new Box(center.x - size2.x / 2, center.y - size2.y / 2, size2.x, size2.y); + } + static FromPoints(points) { + if (points.length === 0) return new Box(); + let minX = Infinity; + let minY = Infinity; + let maxX = -Infinity; + let maxY = -Infinity; + let point; + for (let i2 = 0, n = points.length; i2 < n; i2++) { + point = points[i2]; + minX = Math.min(point.x, minX); + minY = Math.min(point.y, minY); + maxX = Math.max(point.x, maxX); + maxY = Math.max(point.y, maxY); } - return capture === void 0 ? "" : capture; - }); -}; -var call$4 = functionCall; -var anObject$1 = anObject$7; -var isCallable$2 = isCallable$f; -var classof$1 = classofRaw$2; -var regexpExec = regexpExec$2; -var $TypeError$1 = TypeError; -var regexpExecAbstract = function(R2, S2) { - var exec2 = R2.exec; - if (isCallable$2(exec2)) { - var result = call$4(exec2, R2, S2); - if (result !== null) anObject$1(result); - return result; + return new Box(minX, minY, maxX - minX, maxY - minY); } - if (classof$1(R2) === "RegExp") return call$4(regexpExec, R2, S2); - throw new $TypeError$1("RegExp#exec called on incompatible receiver"); -}; -var apply = functionApply; -var call$3 = functionCall; -var uncurryThis$1 = functionUncurryThis; -var fixRegExpWellKnownSymbolLogic = fixRegexpWellKnownSymbolLogic; -var fails = fails$f; -var anObject = anObject$7; -var isCallable$1 = isCallable$f; -var isNullOrUndefined$1 = isNullOrUndefined$4; -var toIntegerOrInfinity = toIntegerOrInfinity$7; -var toLength = toLength$2; -var toString$1 = toString$5; -var requireObjectCoercible$1 = requireObjectCoercible$6; -var advanceStringIndex = advanceStringIndex$1; -var getMethod$2 = getMethod$4; -var getSubstitution$1 = getSubstitution$2; -var regExpExec = regexpExecAbstract; -var wellKnownSymbol$2 = wellKnownSymbol$9; -var REPLACE$1 = wellKnownSymbol$2("replace"); -var max$2 = Math.max; -var min$2 = Math.min; -var concat = uncurryThis$1([].concat); -var push = uncurryThis$1([].push); -var stringIndexOf = uncurryThis$1("".indexOf); -var stringSlice$1 = uncurryThis$1("".slice); -var maybeToString = function(it) { - return it === void 0 ? it : String(it); -}; -var REPLACE_KEEPS_$0 = function() { - return "a".replace(/./, "$0") === "$0"; -}(); -var REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE = function() { - if (/./[REPLACE$1]) { - return /./[REPLACE$1]("a", "$0") === ""; + static Expand(A, B2) { + const minX = Math.min(B2.minX, A.minX); + const minY = Math.min(B2.minY, A.minY); + const maxX = Math.max(B2.maxX, A.maxX); + const maxY = Math.max(B2.maxY, A.maxY); + return new Box(minX, minY, maxX - minX, maxY - minY); } - return false; -}(); -var REPLACE_SUPPORTS_NAMED_GROUPS = !fails(function() { - var re2 = /./; - re2.exec = function() { - var result = []; - result.groups = { a: "7" }; - return result; - }; - return "".replace(re2, "$") !== "7"; -}); -fixRegExpWellKnownSymbolLogic("replace", function(_2, nativeReplace2, maybeCallNative) { - var UNSAFE_SUBSTITUTE = REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE ? "$" : "$0"; - return [ - // `String.prototype.replace` method - // https://tc39.es/ecma262/#sec-string.prototype.replace - function replace2(searchValue, replaceValue) { - var O2 = requireObjectCoercible$1(this); - var replacer = isNullOrUndefined$1(searchValue) ? void 0 : getMethod$2(searchValue, REPLACE$1); - return replacer ? call$3(replacer, searchValue, O2, replaceValue) : call$3(nativeReplace2, toString$1(O2), searchValue, replaceValue); - }, - // `RegExp.prototype[@@replace]` method - // https://tc39.es/ecma262/#sec-regexp.prototype-@@replace - function(string2, replaceValue) { - var rx = anObject(this); - var S2 = toString$1(string2); - if (typeof replaceValue == "string" && stringIndexOf(replaceValue, UNSAFE_SUBSTITUTE) === -1 && stringIndexOf(replaceValue, "$<") === -1) { - var res = maybeCallNative(nativeReplace2, rx, S2, replaceValue); - if (res.done) return res.value; + static ExpandBy(A, n) { + return new Box(A.minX - n, A.minY - n, A.width + n * 2, A.height + n * 2); + } + static Collides(A, B2) { + return !(A.maxX < B2.minX || A.minX > B2.maxX || A.maxY < B2.minY || A.minY > B2.maxY); + } + static Contains(A, B2) { + return A.minX < B2.minX && A.minY < B2.minY && A.maxY > B2.maxY && A.maxX > B2.maxX; + } + static Includes(A, B2) { + return Box.Collides(A, B2) || Box.Contains(A, B2); + } + static ContainsPoint(A, B2, margin = 0) { + return !(B2.x < A.minX - margin || B2.y < A.minY - margin || B2.x > A.maxX + margin || B2.y > A.maxY + margin); + } + static Common(boxes) { + let minX = Infinity; + let minY = Infinity; + let maxX = -Infinity; + let maxY = -Infinity; + for (let i2 = 0; i2 < boxes.length; i2++) { + const B2 = boxes[i2]; + minX = Math.min(minX, B2.minX); + minY = Math.min(minY, B2.minY); + maxX = Math.max(maxX, B2.maxX); + maxY = Math.max(maxY, B2.maxY); + } + return new Box(minX, minY, maxX - minX, maxY - minY); + } + static Sides(A, inset = 0) { + const { corners } = A; + return [ + [corners[0], corners[1]], + [corners[1], corners[2]], + [corners[2], corners[3]], + [corners[3], corners[0]] + ]; + } + static Resize(box, handle, dx, dy, isAspectRatioLocked = false) { + const { minX: a0x, minY: a0y, maxX: a1x, maxY: a1y } = box; + let { minX: b0x, minY: b0y, maxX: b1x, maxY: b1y } = box; + switch (handle) { + case "left": + case "top_left": + case "bottom_left": { + b0x += dx; + break; } - var functionalReplace = isCallable$1(replaceValue); - if (!functionalReplace) replaceValue = toString$1(replaceValue); - var global2 = rx.global; - var fullUnicode; - if (global2) { - fullUnicode = rx.unicode; - rx.lastIndex = 0; + case "right": + case "top_right": + case "bottom_right": { + b1x += dx; + break; } - var results = []; - var result; - while (true) { - result = regExpExec(rx, S2); - if (result === null) break; - push(results, result); - if (!global2) break; - var matchStr = toString$1(result[0]); - if (matchStr === "") rx.lastIndex = advanceStringIndex(S2, toLength(rx.lastIndex), fullUnicode); + } + switch (handle) { + case "top": + case "top_left": + case "top_right": { + b0y += dy; + break; } - var accumulatedResult = ""; - var nextSourcePosition = 0; - for (var i2 = 0; i2 < results.length; i2++) { - result = results[i2]; - var matched = toString$1(result[0]); - var position = max$2(min$2(toIntegerOrInfinity(result.index), S2.length), 0); - var captures = []; - var replacement2; - for (var j2 = 1; j2 < result.length; j2++) push(captures, maybeToString(result[j2])); - var namedCaptures = result.groups; - if (functionalReplace) { - var replacerArgs = concat([matched], captures, position, S2); - if (namedCaptures !== void 0) push(replacerArgs, namedCaptures); - replacement2 = toString$1(apply(replaceValue, void 0, replacerArgs)); - } else { - replacement2 = getSubstitution$1(matched, S2, position, captures, namedCaptures, replaceValue); - } - if (position >= nextSourcePosition) { - accumulatedResult += stringSlice$1(S2, nextSourcePosition, position) + replacement2; - nextSourcePosition = position + matched.length; - } + case "bottom": + case "bottom_left": + case "bottom_right": { + b1y += dy; + break; } - return accumulatedResult + stringSlice$1(S2, nextSourcePosition); } - ]; -}, !REPLACE_SUPPORTS_NAMED_GROUPS || !REPLACE_KEEPS_$0 || REGEXP_REPLACE_SUBSTITUTES_UNDEFINED_CAPTURE); -var isObject = isObject$7; -var classof = classofRaw$2; -var wellKnownSymbol$1 = wellKnownSymbol$9; -var MATCH = wellKnownSymbol$1("match"); -var isRegexp = function(it) { - var isRegExp2; - return isObject(it) && ((isRegExp2 = it[MATCH]) !== void 0 ? !!isRegExp2 : classof(it) === "RegExp"); -}; -var call$2 = functionCall; -var hasOwn2 = hasOwnProperty_1; -var isPrototypeOf = objectIsPrototypeOf; -var regExpFlags = regexpFlags$1; -var RegExpPrototype = RegExp.prototype; -var regexpGetFlags = function(R2) { - var flags = R2.flags; - return flags === void 0 && !("flags" in RegExpPrototype) && !hasOwn2(R2, "flags") && isPrototypeOf(RegExpPrototype, R2) ? call$2(regExpFlags, R2) : flags; -}; -var $$1 = _export; -var call$1 = functionCall; -var uncurryThis = functionUncurryThis; -var requireObjectCoercible = requireObjectCoercible$6; -var isCallable = isCallable$f; -var isNullOrUndefined = isNullOrUndefined$4; -var isRegExp = isRegexp; -var toString2 = toString$5; -var getMethod$1 = getMethod$4; -var getRegExpFlags = regexpGetFlags; -var getSubstitution = getSubstitution$2; -var wellKnownSymbol = wellKnownSymbol$9; -var REPLACE = wellKnownSymbol("replace"); -var $TypeError = TypeError; -var indexOf = uncurryThis("".indexOf); -uncurryThis("".replace); -var stringSlice = uncurryThis("".slice); -var max$1 = Math.max; -$$1({ target: "String", proto: true }, { - replaceAll: function replaceAll(searchValue, replaceValue) { - var O2 = requireObjectCoercible(this); - var IS_REG_EXP, flags, replacer, string2, searchString, functionalReplace, searchLength, advanceBy, position, replacement2; - var endOfLastMatch = 0; - var result = ""; - if (!isNullOrUndefined(searchValue)) { - IS_REG_EXP = isRegExp(searchValue); - if (IS_REG_EXP) { - flags = toString2(requireObjectCoercible(getRegExpFlags(searchValue))); - if (!~indexOf(flags, "g")) throw new $TypeError("`.replaceAll` does not allow non-global regexes"); + const scaleX = (b1x - b0x) / (a1x - a0x); + const scaleY = (b1y - b0y) / (a1y - a0y); + const flipX = scaleX < 0; + const flipY = scaleY < 0; + if (isAspectRatioLocked) { + const aspectRatio = (a1x - a0x) / (a1y - a0y); + const bw = Math.abs(b1x - b0x); + const bh = Math.abs(b1y - b0y); + const tw = bw * (scaleY < 0 ? 1 : -1) * (1 / aspectRatio); + const th = bh * (scaleX < 0 ? 1 : -1) * aspectRatio; + const isTall = aspectRatio < bw / bh; + switch (handle) { + case "top_left": { + if (isTall) b0y = b1y + tw; + else b0x = b1x + th; + break; + } + case "top_right": { + if (isTall) b0y = b1y + tw; + else b1x = b0x - th; + break; + } + case "bottom_right": { + if (isTall) b1y = b0y - tw; + else b1x = b0x - th; + break; + } + case "bottom_left": { + if (isTall) b1y = b0y - tw; + else b0x = b1x + th; + break; + } + case "bottom": + case "top": { + const m2 = (b0x + b1x) / 2; + const w2 = bh * aspectRatio; + b0x = m2 - w2 / 2; + b1x = m2 + w2 / 2; + break; + } + case "left": + case "right": { + const m2 = (b0y + b1y) / 2; + const h2 = bw / aspectRatio; + b0y = m2 - h2 / 2; + b1y = m2 + h2 / 2; + break; + } } - replacer = getMethod$1(searchValue, REPLACE); - if (replacer) return call$1(replacer, searchValue, O2, replaceValue); } - string2 = toString2(O2); - searchString = toString2(searchValue); - functionalReplace = isCallable(replaceValue); - if (!functionalReplace) replaceValue = toString2(replaceValue); - searchLength = searchString.length; - advanceBy = max$1(1, searchLength); - position = indexOf(string2, searchString); - while (position !== -1) { - replacement2 = functionalReplace ? toString2(replaceValue(searchString, position, string2)) : getSubstitution(searchString, string2, position, [], void 0, replaceValue); - result += stringSlice(string2, endOfLastMatch, position) + replacement2; - endOfLastMatch = position + searchLength; - position = position + advanceBy > string2.length ? -1 : indexOf(string2, searchString, position + advanceBy); + if (flipX) { + const t2 = b1x; + b1x = b0x; + b0x = t2; } - if (endOfLastMatch < string2.length) { - result += stringSlice(string2, endOfLastMatch); + if (flipY) { + const t2 = b1y; + b1y = b0y; + b0y = t2; } - return result; + const final = new Box(b0x, b0y, Math.abs(b1x - b0x), Math.abs(b1y - b0y)); + return { + box: final, + scaleX: +(final.width / box.width * (scaleX > 0 ? 1 : -1)).toFixed(5), + scaleY: +(final.height / box.height * (scaleY > 0 ? 1 : -1)).toFixed(5) + }; } -}); -var entryUnbind = entryUnbind$5; -entryUnbind("String", "replaceAll"); -function isChild(x2) { - return x2 && typeof x2 === "object" && "parents" in x2; -} -function haveParentsChanged(child) { - for (let i2 = 0, n2 = child.parents.length; i2 < n2; i2++) { - child.parents[i2].__unsafe__getWithoutCapture(true); - if (child.parents[i2].lastChangedEpoch !== child.parentEpochs[i2]) { - return true; - } + equals(other) { + return Box.Equals(this, other); } - return false; -} -function detach(parent, child) { - if (!parent.children.remove(child)) { - return; + static Equals(a2, b2) { + return b2.x === a2.x && b2.y === a2.y && b2.w === a2.w && b2.h === a2.h; } - if (parent.children.isEmpty && isChild(parent)) { - for (let i2 = 0, n2 = parent.parents.length; i2 < n2; i2++) { - detach(parent.parents[i2], parent); - } + zeroFix() { + this.w = Math.max(1, this.w); + this.h = Math.max(1, this.h); + return this; } -} -function attach(parent, child) { - if (!parent.children.add(child)) { - return; + static ZeroFix(other) { + return new Box(other.x, other.y, Math.max(1, other.w), Math.max(1, other.h)); } - if (isChild(parent)) { - for (let i2 = 0, n2 = parent.parents.length; i2 < n2; i2++) { - attach(parent.parents[i2], parent); - } +} +function flipSelectionHandleY(handle) { + switch (handle) { + case "top": + return "bottom"; + case "bottom": + return "top"; + case "top_left": + return "bottom_left"; + case "top_right": + return "bottom_right"; + case "bottom_left": + return "top_left"; + case "bottom_right": + return "top_right"; + default: + return handle; } } -function equals(a2, b2) { - const shallowEquals = a2 === b2 || Object.is(a2, b2) || Boolean(a2 && b2 && typeof a2.equals === "function" && a2.equals(b2)); - return shallowEquals; +function flipSelectionHandleX(handle) { + switch (handle) { + case "left": + return "right"; + case "right": + return "left"; + case "top_left": + return "top_right"; + case "top_right": + return "top_left"; + case "bottom_left": + return "bottom_right"; + case "bottom_right": + return "bottom_left"; + default: + return handle; + } } -function singleton(key, init) { - const symbol = Symbol.for(`com.tldraw.state/${key}`); - const global2 = globalThis; - global2[symbol] ?? (global2[symbol] = init()); - return global2[symbol]; +function isSelectionCorner(selection) { + return selection === "top_left" || selection === "top_right" || selection === "bottom_right" || selection === "bottom_left"; } -const EMPTY_ARRAY = singleton("empty_array", () => Object.freeze([])); -const ARRAY_SIZE_THRESHOLD = 8; -class ArraySet { - constructor() { - __publicField(this, "arraySize", 0); - __publicField(this, "array", Array(ARRAY_SIZE_THRESHOLD)); - __publicField(this, "set", null); +class Mat { + constructor(a2, b2, c2, d2, e2, f2) { + __publicField(this, "a", 1); + __publicField(this, "b", 0); + __publicField(this, "c", 0); + __publicField(this, "d", 1); + __publicField(this, "e", 0); + __publicField(this, "f", 0); + this.a = a2; + this.b = b2; + this.c = c2; + this.d = d2; + this.e = e2; + this.f = f2; } - /** - * Get whether this ArraySet has any elements. - * - * @returns True if this ArraySet has any elements, false otherwise. - */ - // eslint-disable-next-line no-restricted-syntax - get isEmpty() { - if (this.array) { - return this.arraySize === 0; + equals(m2) { + return this === m2 || this.a === m2.a && this.b === m2.b && this.c === m2.c && this.d === m2.d && this.e === m2.e && this.f === m2.f; + } + identity() { + this.a = 1; + this.b = 0; + this.c = 0; + this.d = 1; + this.e = 0; + this.f = 0; + return this; + } + multiply(m2) { + const m22 = m2; + const { a: a2, b: b2, c: c2, d: d2, e: e2, f: f2 } = this; + this.a = a2 * m22.a + c2 * m22.b; + this.c = a2 * m22.c + c2 * m22.d; + this.e = a2 * m22.e + c2 * m22.f + e2; + this.b = b2 * m22.a + d2 * m22.b; + this.d = b2 * m22.c + d2 * m22.d; + this.f = b2 * m22.e + d2 * m22.f + f2; + return this; + } + rotate(r, cx, cy) { + if (r === 0) return this; + if (cx === void 0) return this.multiply(Mat.Rotate(r)); + return this.translate(cx, cy).multiply(Mat.Rotate(r)).translate(-cx, -cy); + } + translate(x2, y2) { + return this.multiply(Mat.Translate(x2, y2)); + } + scale(x2, y2) { + return this.multiply(Mat.Scale(x2, y2)); + } + invert() { + const { a: a2, b: b2, c: c2, d: d2, e: e2, f: f2 } = this; + const denom = a2 * d2 - b2 * c2; + this.a = d2 / denom; + this.b = b2 / -denom; + this.c = c2 / -denom; + this.d = a2 / denom; + this.e = (d2 * e2 - c2 * f2) / -denom; + this.f = (b2 * e2 - a2 * f2) / denom; + return this; + } + applyToPoint(point) { + return Mat.applyToPoint(this, point); + } + applyToPoints(points) { + return Mat.applyToPoints(this, points); + } + rotation() { + return Mat.Rotation(this); + } + point() { + return Mat.Point(this); + } + decomposed() { + return Mat.Decompose(this); + } + toCssString() { + return Mat.toCssString(this); + } + setTo(model2) { + Object.assign(this, model2); + return this; + } + decompose() { + return Mat.Decompose(this); + } + clone() { + return new Mat(this.a, this.b, this.c, this.d, this.e, this.f); + } + /* --------------------- Static --------------------- */ + static Identity() { + return new Mat(1, 0, 0, 1, 0, 0); + } + static Translate(x2, y2) { + return new Mat(1, 0, 0, 1, x2, y2); + } + static Rotate(r, cx, cy) { + if (r === 0) return Mat.Identity(); + const cosAngle = Math.cos(r); + const sinAngle = Math.sin(r); + const rotationMatrix = new Mat(cosAngle, sinAngle, -sinAngle, cosAngle, 0, 0); + if (cx === void 0) return rotationMatrix; + return Mat.Compose(Mat.Translate(cx, cy), rotationMatrix, Mat.Translate(-cx, -cy)); + } + static Scale(x2, y2, cx, cy) { + const scaleMatrix = new Mat(x2, 0, 0, y2, 0, 0); + if (cx === void 0) return scaleMatrix; + return Mat.Compose(Mat.Translate(cx, cy), scaleMatrix, Mat.Translate(-cx, -cy)); + } + static Multiply(m1, m2) { + return { + a: m1.a * m2.a + m1.c * m2.b, + c: m1.a * m2.c + m1.c * m2.d, + e: m1.a * m2.e + m1.c * m2.f + m1.e, + b: m1.b * m2.a + m1.d * m2.b, + d: m1.b * m2.c + m1.d * m2.d, + f: m1.b * m2.e + m1.d * m2.f + m1.f + }; + } + static Inverse(m2) { + const denom = m2.a * m2.d - m2.b * m2.c; + return { + a: m2.d / denom, + b: m2.b / -denom, + c: m2.c / -denom, + d: m2.a / denom, + e: (m2.d * m2.e - m2.c * m2.f) / -denom, + f: (m2.b * m2.e - m2.a * m2.f) / denom + }; + } + static Absolute(m2) { + const denom = m2.a * m2.d - m2.b * m2.c; + return { + a: m2.d / denom, + b: m2.b / -denom, + c: m2.c / -denom, + d: m2.a / denom, + e: (m2.d * m2.e - m2.c * m2.f) / denom, + f: (m2.b * m2.e - m2.a * m2.f) / -denom + }; + } + static Compose(...matrices) { + const matrix = Mat.Identity(); + for (let i2 = 0, n = matrices.length; i2 < n; i2++) { + matrix.multiply(matrices[i2]); } - if (this.set) { - return this.set.size === 0; + return matrix; + } + static Point(m2) { + return new Vec(m2.e, m2.f); + } + static Rotation(m2) { + let rotation; + if (m2.a !== 0 || m2.c !== 0) { + const hypotAc = (m2.a * m2.a + m2.c * m2.c) ** 0.5; + rotation = Math.acos(m2.a / hypotAc) * (m2.c > 0 ? -1 : 1); + } else if (m2.b !== 0 || m2.d !== 0) { + const hypotBd = (m2.b * m2.b + m2.d * m2.d) ** 0.5; + rotation = HALF_PI + Math.acos(m2.b / hypotBd) * (m2.d > 0 ? -1 : 1); + } else { + rotation = 0; } - throw new Error("no set or array"); + return clampRadians(rotation); + } + static Decompose(m2) { + let scaleX, scaleY, rotation; + if (m2.a !== 0 || m2.c !== 0) { + const hypotAc = (m2.a * m2.a + m2.c * m2.c) ** 0.5; + scaleX = hypotAc; + scaleY = (m2.a * m2.d - m2.b * m2.c) / hypotAc; + rotation = Math.acos(m2.a / hypotAc) * (m2.c > 0 ? -1 : 1); + } else if (m2.b !== 0 || m2.d !== 0) { + const hypotBd = (m2.b * m2.b + m2.d * m2.d) ** 0.5; + scaleX = (m2.a * m2.d - m2.b * m2.c) / hypotBd; + scaleY = hypotBd; + rotation = HALF_PI + Math.acos(m2.b / hypotBd) * (m2.d > 0 ? -1 : 1); + } else { + scaleX = 0; + scaleY = 0; + rotation = 0; + } + return { + x: m2.e, + y: m2.f, + scaleX, + scaleY, + rotation: clampRadians(rotation) + }; + } + static Smooth(m2, precision = 1e10) { + m2.a = Math.round(m2.a * precision) / precision; + m2.b = Math.round(m2.b * precision) / precision; + m2.c = Math.round(m2.c * precision) / precision; + m2.d = Math.round(m2.d * precision) / precision; + m2.e = Math.round(m2.e * precision) / precision; + m2.f = Math.round(m2.f * precision) / precision; + return m2; + } + static toCssString(m2) { + return `matrix(${toDomPrecision(m2.a)}, ${toDomPrecision(m2.b)}, ${toDomPrecision( + m2.c + )}, ${toDomPrecision(m2.d)}, ${toDomPrecision(m2.e)}, ${toDomPrecision(m2.f)})`; + } + static applyToPoint(m2, point) { + return new Vec( + m2.a * point.x + m2.c * point.y + m2.e, + m2.b * point.x + m2.d * point.y + m2.f, + point.z + ); + } + static applyToXY(m2, x2, y2) { + return [m2.a * x2 + m2.c * y2 + m2.e, m2.b * x2 + m2.d * y2 + m2.f]; + } + static applyToPoints(m2, points) { + return points.map( + (point) => new Vec(m2.a * point.x + m2.c * point.y + m2.e, m2.b * point.x + m2.d * point.y + m2.f, point.z) + ); + } + static applyToBounds(m2, box) { + return new Box(m2.e + box.minX, m2.f + box.minY, box.width, box.height); + } + static From(m2) { + return new Mat(m2.a, m2.b, m2.c, m2.d, m2.e, m2.f); + } + static Cast(m2) { + return m2 instanceof Mat ? m2 : Mat.From(m2); + } +} +class Geometry2d { + constructor(opts) { + __publicField(this, "isFilled", false); + __publicField(this, "isClosed", true); + __publicField(this, "isLabel", false); + __publicField(this, "debugColor"); + __publicField(this, "ignore"); + __publicField(this, "_vertices"); + __publicField(this, "_bounds"); + __publicField(this, "_area"); + __publicField(this, "_length"); + this.isFilled = opts.isFilled; + this.isClosed = opts.isClosed; + this.isLabel = opts.isLabel ?? false; + this.debugColor = opts.debugColor; + this.ignore = opts.ignore; } - /** - * Add an item to the ArraySet if it is not already present. - * - * @param elem - The element to add. - */ - add(elem) { - if (this.array) { - const idx = this.array.indexOf(elem); - if (idx !== -1) { - return false; - } - if (this.arraySize < ARRAY_SIZE_THRESHOLD) { - this.array[this.arraySize] = elem; - this.arraySize++; - return true; - } else { - this.set = new Set(this.array); - this.array = null; - this.set.add(elem); - return true; - } - } - if (this.set) { - if (this.set.has(elem)) { - return false; - } - this.set.add(elem); + // hitTestPoint(point: Vec, margin = 0, hitInside = false) { + // // We've removed the broad phase here; that should be done outside of the call + // return this.distanceToPoint(point, hitInside) <= margin + // } + hitTestPoint(point, margin = 0, hitInside = false) { + if (this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices)) { return true; } - throw new Error("no set or array"); + return Vec.Dist2(point, this.nearestPoint(point)) <= margin * margin; } - /** - * Remove an item from the ArraySet if it is present. - * - * @param elem - The element to remove - */ - remove(elem) { - if (this.array) { - const idx = this.array.indexOf(elem); - if (idx === -1) { - return false; - } - this.array[idx] = void 0; - this.arraySize--; - if (idx !== this.arraySize) { - this.array[idx] = this.array[this.arraySize]; - this.array[this.arraySize] = void 0; - } - return true; - } - if (this.set) { - if (!this.set.has(elem)) { - return false; + distanceToPoint(point, hitInside = false) { + return point.dist(this.nearestPoint(point)) * (this.isClosed && (this.isFilled || hitInside) && pointInPolygon(point, this.vertices) ? -1 : 1); + } + distanceToLineSegment(A, B2) { + if (A.equals(B2)) return this.distanceToPoint(A); + const { vertices } = this; + let nearest; + let dist = Infinity; + let d2, p2, q; + for (let i2 = 0; i2 < vertices.length; i2++) { + p2 = vertices[i2]; + q = Vec.NearestPointOnLineSegment(A, B2, p2, true); + d2 = Vec.Dist2(p2, q); + if (d2 < dist) { + dist = d2; + nearest = q; } - this.set.delete(elem); - return true; } - throw new Error("no set or array"); + if (!nearest) throw Error("nearest point not found"); + return this.isClosed && this.isFilled && pointInPolygon(nearest, this.vertices) ? -dist : dist; } - /** - * Run a callback for each element in the ArraySet. - * - * @param visitor - The callback to run for each element. - */ - visit(visitor) { - if (this.array) { - for (let i2 = 0; i2 < this.arraySize; i2++) { - const elem = this.array[i2]; - if (typeof elem !== "undefined") { - visitor(elem); - } + hitTestLineSegment(A, B2, distance = 0) { + return this.distanceToLineSegment(A, B2) <= distance; + } + nearestPointOnLineSegment(A, B2) { + const { vertices } = this; + let nearest; + let dist = Infinity; + let d2, p2, q; + for (let i2 = 0; i2 < vertices.length; i2++) { + p2 = vertices[i2]; + q = Vec.NearestPointOnLineSegment(A, B2, p2, true); + d2 = Vec.Dist2(p2, q); + if (d2 < dist) { + dist = d2; + nearest = q; } - return; - } - if (this.set) { - this.set.forEach(visitor); - return; } - throw new Error("no set or array"); + if (!nearest) throw Error("nearest point not found"); + return nearest; } - has(elem) { - if (this.array) { - return this.array.indexOf(elem) !== -1; - } else { - return this.set.has(elem); - } + isPointInBounds(point, margin = 0) { + const { bounds } = this; + return !(point.x < bounds.minX - margin || point.y < bounds.minY - margin || point.x > bounds.maxX + margin || point.y > bounds.maxY + margin); } - clear() { - if (this.set) { - this.set.clear(); - } else { - this.arraySize = 0; - this.array = []; + // eslint-disable-next-line no-restricted-syntax + get vertices() { + if (!this._vertices) { + this._vertices = this.getVertices(); } + return this._vertices; } - size() { - if (this.set) { - return this.set.size; - } else { - return this.arraySize; + getBounds() { + return Box.FromPoints(this.vertices); + } + // eslint-disable-next-line no-restricted-syntax + get bounds() { + if (!this._bounds) { + this._bounds = this.getBounds(); } + return this._bounds; } -} -const RESET_VALUE = Symbol.for("com.tldraw.state/RESET_VALUE"); -class HistoryBuffer { - constructor(capacity) { - __publicField(this, "index", 0); - // use a wrap around buffer to store the last N values - __publicField(this, "buffer"); - this.capacity = capacity; - this.buffer = new Array(capacity); + // eslint-disable-next-line no-restricted-syntax + get center() { + return this.bounds.center; } - /** - * Add a diff to the history buffer. - * - * @param lastComputedEpoch - The epoch when the diff was computed. - * @param currentEpoch - The current epoch. - * @param diff - The diff to add, or else a reset value. - */ - pushEntry(lastComputedEpoch, currentEpoch, diff) { - if (diff === void 0) { - return; - } - if (diff === RESET_VALUE) { - this.clear(); - return; + // eslint-disable-next-line no-restricted-syntax + get area() { + if (!this._area) { + this._area = this.getArea(); } - this.buffer[this.index] = [lastComputedEpoch, currentEpoch, diff]; - this.index = (this.index + 1) % this.capacity; + return this._area; } - /** - * Clear the history buffer. - */ - clear() { - this.index = 0; - this.buffer.fill(void 0); + getArea() { + if (!this.isClosed) { + return 0; + } + const { vertices } = this; + let area = 0; + for (let i2 = 0, n = vertices.length; i2 < n; i2++) { + const curr = vertices[i2]; + const next = vertices[(i2 + 1) % n]; + area += curr.x * next.y - next.x * curr.y; + } + return area / 2; } - /** - * Get the diffs since the given epoch. - * - * @param sinceEpoch - The epoch to get diffs since. - * @returns An array of diffs or a flag to reset the history buffer. - */ - getChangesSince(sinceEpoch) { - const { index: index2, capacity, buffer } = this; - for (let i2 = 0; i2 < capacity; i2++) { - const offset2 = (index2 - 1 + capacity - i2) % capacity; - const elem = buffer[offset2]; - if (!elem) { - return RESET_VALUE; - } - const [fromEpoch, toEpoch] = elem; - if (i2 === 0 && sinceEpoch >= toEpoch) { - return []; - } - if (fromEpoch <= sinceEpoch && sinceEpoch < toEpoch) { - const len = i2 + 1; - const result = new Array(len); - for (let j2 = 0; j2 < len; j2++) { - result[j2] = buffer[(offset2 + j2) % capacity][2]; - } - return result; - } + toSimpleSvgPath() { + let path = ""; + const { vertices } = this; + const n = vertices.length; + if (n === 0) return path; + path += `M${vertices[0].x},${vertices[0].y}`; + for (let i2 = 1; i2 < n; i2++) { + path += `L${vertices[i2].x},${vertices[i2].y}`; } - return RESET_VALUE; + if (this.isClosed) { + path += "Z"; + } + return path; } -} -class CaptureStackFrame { - constructor(below, child) { - __publicField(this, "offset", 0); - __publicField(this, "maybeRemoved"); - this.below = below; - this.child = child; + // eslint-disable-next-line no-restricted-syntax + get length() { + if (this._length) return this._length; + this._length = this.getLength(); + return this._length; } -} -const inst$1 = singleton("capture", () => ({ stack: null })); -function unsafe__withoutCapture(fn) { - const oldStack = inst$1.stack; - inst$1.stack = null; - try { - return fn(); - } finally { - inst$1.stack = oldStack; + getLength() { + const { vertices } = this; + let n1, p1 = vertices[0], length = 0; + for (let i2 = 1; i2 < vertices.length; i2++) { + n1 = vertices[i2]; + length += Vec.Dist2(p1, n1); + p1 = n1; + } + return Math.sqrt(length); } } -function startCapturingParents(child) { - inst$1.stack = new CaptureStackFrame(inst$1.stack, child); - child.parentSet.clear(); -} -function stopCapturingParents() { - const frame2 = inst$1.stack; - inst$1.stack = frame2.below; - if (frame2.offset < frame2.child.parents.length) { - for (let i2 = frame2.offset; i2 < frame2.child.parents.length; i2++) { - const maybeRemovedParent = frame2.child.parents[i2]; - if (!frame2.child.parentSet.has(maybeRemovedParent)) { - detach(maybeRemovedParent, frame2.child); +class Group2d extends Geometry2d { + constructor(config) { + super({ ...config, isClosed: true, isFilled: false }); + __publicField(this, "children", []); + __publicField(this, "ignoredChildren", []); + for (const child of config.children) { + if (child.ignore) { + this.ignoredChildren.push(child); + } else { + this.children.push(child); } } - frame2.child.parents.length = frame2.offset; - frame2.child.parentEpochs.length = frame2.offset; + if (this.children.length === 0) throw Error("Group2d must have at least one child"); } - if (frame2.maybeRemoved) { - for (let i2 = 0; i2 < frame2.maybeRemoved.length; i2++) { - const maybeRemovedParent = frame2.maybeRemoved[i2]; - if (!frame2.child.parentSet.has(maybeRemovedParent)) { - detach(maybeRemovedParent, frame2.child); - } - } + getVertices() { + return this.children.filter((c2) => !c2.isLabel).flatMap((c2) => c2.vertices); } -} -function maybeCaptureParent(p2) { - if (inst$1.stack) { - const wasCapturedAlready = inst$1.stack.child.parentSet.has(p2); - if (wasCapturedAlready) { - return; - } - inst$1.stack.child.parentSet.add(p2); - if (inst$1.stack.child.isActivelyListening) { - attach(p2, inst$1.stack.child); + nearestPoint(point) { + let dist = Infinity; + let nearest; + const { children } = this; + if (children.length === 0) { + throw Error("no children"); } - if (inst$1.stack.offset < inst$1.stack.child.parents.length) { - const maybeRemovedParent = inst$1.stack.child.parents[inst$1.stack.offset]; - if (maybeRemovedParent !== p2) { - if (!inst$1.stack.maybeRemoved) { - inst$1.stack.maybeRemoved = [maybeRemovedParent]; - } else { - inst$1.stack.maybeRemoved.push(maybeRemovedParent); - } + let p2; + let d2; + for (const child of children) { + p2 = child.nearestPoint(point); + d2 = Vec.Dist2(p2, point); + if (d2 < dist) { + dist = d2; + nearest = p2; } } - inst$1.stack.child.parents[inst$1.stack.offset] = p2; - inst$1.stack.child.parentEpochs[inst$1.stack.offset] = p2.lastChangedEpoch; - inst$1.stack.offset++; + if (!nearest) throw Error("nearest point not found"); + return nearest; } -} -const GLOBAL_START_EPOCH = -1; -class __EffectScheduler__ { - constructor(name, runEffect, options) { - __publicField(this, "_isActivelyListening", false); - /** @internal */ - __publicField(this, "lastTraversedEpoch", GLOBAL_START_EPOCH); - __publicField(this, "lastReactedEpoch", GLOBAL_START_EPOCH); - __publicField(this, "_scheduleCount", 0); - /** @internal */ - __publicField(this, "parentSet", new ArraySet()); - /** @internal */ - __publicField(this, "parentEpochs", []); - /** @internal */ - __publicField(this, "parents", []); - __publicField(this, "_scheduleEffect"); - /** @internal */ - // eslint-disable-next-line local/prefer-class-methods - __publicField(this, "maybeExecute", () => { - if (!this._isActivelyListening) return; - this.execute(); - }); - this.name = name; - this.runEffect = runEffect; - this._scheduleEffect = options == null ? void 0 : options.scheduleEffect; + distanceToPoint(point, hitInside = false) { + return Math.min(...this.children.map((c2, i2) => c2.distanceToPoint(point, hitInside || i2 > 0))); } - /** - * Whether this scheduler is attached and actively listening to its parents. - * @public - */ - // eslint-disable-next-line no-restricted-syntax - get isActivelyListening() { - return this._isActivelyListening; + hitTestPoint(point, margin, hitInside) { + return !!this.children.filter((c2) => !c2.isLabel).find((c2) => c2.hitTestPoint(point, margin, hitInside)); } - /** - * The number of times this effect has been scheduled. - * @public - */ - // eslint-disable-next-line no-restricted-syntax - get scheduleCount() { - return this._scheduleCount; + hitTestLineSegment(A, B2, zoom) { + return !!this.children.filter((c2) => !c2.isLabel).find((c2) => c2.hitTestLineSegment(A, B2, zoom)); } - /** @internal */ - maybeScheduleEffect() { - if (!this._isActivelyListening) return; - if (this.lastReactedEpoch === getGlobalEpoch()) return; - if (this.parents.length && !haveParentsChanged(this)) { - this.lastReactedEpoch = getGlobalEpoch(); - return; - } - this.scheduleEffect(); + getArea() { + return this.children[0].area; } - /** @internal */ - scheduleEffect() { - this._scheduleCount++; - if (this._scheduleEffect) { - this._scheduleEffect(this.maybeExecute); - } else { - this.execute(); + toSimpleSvgPath() { + let path = ""; + for (const child of this.children) { + path += child.toSimpleSvgPath(); } - } - /** - * Makes this scheduler become 'actively listening' to its parents. - * If it has been executed before it will immediately become eligible to receive 'maybeScheduleEffect' calls. - * If it has not executed before it will need to be manually executed once to become eligible for scheduling, i.e. by calling [[EffectScheduler.execute]]. - * @public - */ - attach() { - this._isActivelyListening = true; - for (let i2 = 0, n2 = this.parents.length; i2 < n2; i2++) { - attach(this.parents[i2], this); + const corners = Box.FromPoints(this.vertices).corners; + for (let i2 = 0, n = corners.length; i2 < n; i2++) { + const corner = corners[i2]; + const prevCorner = corners[(i2 - 1 + n) % n]; + const prevDist = corner.dist(prevCorner); + const nextCorner = corners[(i2 + 1) % n]; + const nextDist = corner.dist(nextCorner); + const A = corner.clone().lrp(prevCorner, 4 / prevDist); + const B2 = corner; + const C2 = corner.clone().lrp(nextCorner, 4 / nextDist); + path += `M${A.x},${A.y} L${B2.x},${B2.y} L${C2.x},${C2.y} `; } + return path; } - /** - * Makes this scheduler stop 'actively listening' to its parents. - * It will no longer be eligible to receive 'maybeScheduleEffect' calls until [[EffectScheduler.attach]] is called again. - */ - detach() { - this._isActivelyListening = false; - for (let i2 = 0, n2 = this.parents.length; i2 < n2; i2++) { - detach(this.parents[i2], this); - } + getLength() { + return this.children.reduce((a2, c2) => c2.isLabel ? a2 : a2 + c2.length, 0); } - /** - * Executes the effect immediately and returns the result. - * @returns The result of the effect. - */ - execute() { - try { - startCapturingParents(this); - const currentEpoch = getGlobalEpoch(); - const result = this.runEffect(this.lastReactedEpoch); - this.lastReactedEpoch = currentEpoch; - return result; - } finally { - stopCapturingParents(); + getSvgPathData() { + return this.children.map((c2, i2) => c2.isLabel ? "" : c2.getSvgPathData(i2 === 0)).join(" "); + } +} +function useTick$1(isEnabled = true) { + const [_2, setTick] = reactExports.useState(0); + const editor = useEditor(); + reactExports.useEffect(() => { + if (!isEnabled) return; + const update = () => setTick((tick2) => tick2 + 1); + editor.on("tick", update); + return () => { + editor.off("tick", update); + }; + }, [editor, isEnabled]); +} +const GeometryDebuggingView = track(function GeometryDebuggingView2({ + showStroke = true, + showVertices = true, + showClosestPointOnOutline = true +}) { + const editor = useEditor(); + useTick$1(showClosestPointOnOutline); + const zoomLevel = editor.getZoomLevel(); + const renderingShapes = editor.getRenderingShapes(); + const { + inputs: { currentPagePoint } + } = editor; + return /* @__PURE__ */ jsxRuntimeExports.jsx( + "svg", + { + style: { + position: "absolute", + pointerEvents: "none", + zIndex: 999999999, + top: 0, + left: 0, + overflow: "visible" + }, + children: renderingShapes.map((result) => { + const shape = editor.getShape(result.id); + if (shape.type === "group") return null; + const geometry = editor.getShapeGeometry(shape); + const pageTransform = editor.getShapePageTransform(shape); + const pointInShapeSpace = editor.getPointInShapeSpace(shape, currentPagePoint); + const nearestPointOnShape = geometry.nearestPoint(pointInShapeSpace); + const distanceToPoint = geometry.distanceToPoint(pointInShapeSpace, true); + const dist = Math.abs(distanceToPoint) * zoomLevel; + const hitInside = distanceToPoint < 0; + const { vertices } = geometry; + return /* @__PURE__ */ jsxRuntimeExports.jsxs( + "g", + { + transform: pageTransform.toCssString(), + strokeLinecap: "round", + strokeLinejoin: "round", + children: [ + showStroke && /* @__PURE__ */ jsxRuntimeExports.jsx( + "g", + { + stroke: geometry.debugColor ?? "red", + opacity: "1", + strokeWidth: 2 / zoomLevel, + fill: "none", + children: /* @__PURE__ */ jsxRuntimeExports.jsx(GeometryStroke, { geometry }) + } + ), + showVertices && vertices.map((v2, i2) => /* @__PURE__ */ jsxRuntimeExports.jsx( + "circle", + { + cx: v2.x, + cy: v2.y, + r: 2 / zoomLevel, + fill: `hsl(${modulate(i2, [0, vertices.length - 1], [120, 200])}, 100%, 50%)`, + stroke: "black", + strokeWidth: 1 / zoomLevel + }, + `v${i2}` + )), + showClosestPointOnOutline && dist < 150 && /* @__PURE__ */ jsxRuntimeExports.jsx( + "line", + { + x1: nearestPointOnShape.x, + y1: nearestPointOnShape.y, + x2: pointInShapeSpace.x, + y2: pointInShapeSpace.y, + opacity: 1 - dist / 150, + stroke: hitInside ? "goldenrod" : "dodgerblue", + strokeWidth: 2 / zoomLevel + } + ) + ] + }, + result.id + "_outline" + ); + }) } + ); +}); +function GeometryStroke({ geometry }) { + if (geometry instanceof Group2d) { + return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: [...geometry.children, ...geometry.ignoredChildren].map((child, i2) => /* @__PURE__ */ jsxRuntimeExports.jsx(GeometryStroke, { geometry: child }, i2)) }); } + return /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: geometry.toSimpleSvgPath() }); } -const EffectScheduler = singleton( - "EffectScheduler", - () => __EffectScheduler__ -); -function react(name, fn, options) { - const scheduler2 = new EffectScheduler(name, fn, options); - scheduler2.attach(); - scheduler2.scheduleEffect(); - return () => { - scheduler2.detach(); - }; +function uniq(array2) { + return _uniq(array2); } -function reactor(name, fn, options) { - const scheduler2 = new EffectScheduler(name, fn, options); - return { - scheduler: scheduler2, - start: (options2) => { - const force = (options2 == null ? void 0 : options2.force) ?? false; - scheduler2.attach(); - if (force) { - scheduler2.scheduleEffect(); - } else { - scheduler2.maybeScheduleEffect(); - } +function usePeerIds() { + const editor = useEditor(); + const $userIds = useComputed( + "userIds", + () => uniq(editor.getCollaborators().map((p2) => p2.userId)).sort(), + { isEqual: (a2, b2) => { + var _a3; + return a2.join(",") === ((_a3 = b2.join) == null ? void 0 : _a3.call(b2, ",")); + } }, + [editor] + ); + return useValue($userIds); +} +function usePresence$1(userId) { + const editor = useEditor(); + const latestPresence = useValue( + `latestPresence:${userId}`, + () => { + return editor.getCollaborators().find((c2) => c2.userId === userId); }, - stop: () => { - scheduler2.detach(); - } - }; + [editor, userId] + ); + return latestPresence ?? null; } -class Transaction { - constructor(parent) { - __publicField(this, "initialAtomValues", /* @__PURE__ */ new Map()); - this.parent = parent; - } - /** - * Get whether this transaction is a root (no parents). - * - * @public - */ - // eslint-disable-next-line no-restricted-syntax - get isRoot() { - return this.parent === null; +const LiveCollaborators = track(function Collaborators() { + const peerIds = usePeerIds(); + return peerIds.map((id2) => /* @__PURE__ */ jsxRuntimeExports.jsx(CollaboratorGuard, { collaboratorId: id2 }, id2)); +}); +const CollaboratorGuard = track(function CollaboratorGuard2({ + collaboratorId +}) { + const editor = useEditor(); + const presence = usePresence$1(collaboratorId); + const collaboratorState = useCollaboratorState(editor, presence); + if (!(presence && presence.currentPageId === editor.getCurrentPageId())) { + return null; } - /** - * Commit the transaction's changes. - * - * @public - */ - commit() { - if (inst.globalIsReacting) { - for (const atom2 of this.initialAtomValues.keys()) { - traverseAtomForCleanup(atom2); + switch (collaboratorState) { + case "inactive": { + const { followingUserId, highlightedUserIds } = editor.getInstanceState(); + if (!(followingUserId === presence.userId || highlightedUserIds.includes(presence.userId))) { + return null; } - } else if (this.isRoot) { - flushChanges(this.initialAtomValues.keys()); - } else { - this.initialAtomValues.forEach((value, atom2) => { - if (!this.parent.initialAtomValues.has(atom2)) { - this.parent.initialAtomValues.set(atom2, value); - } - }); + break; + } + case "idle": { + const { highlightedUserIds } = editor.getInstanceState(); + if (presence.followingUserId === editor.user.getId() && !(presence.chatMessage || highlightedUserIds.includes(presence.userId))) { + return null; + } + break; } } - /** - * Abort the transaction. - * - * @public - */ - abort() { - inst.globalEpoch++; - this.initialAtomValues.forEach((value, atom2) => { - var _a3; - atom2.set(value); - (_a3 = atom2.historyBuffer) == null ? void 0 : _a3.clear(); - }); - this.commit(); - } -} -const inst = singleton("transactions", () => ({ - // The current epoch (global to all atoms). - globalEpoch: GLOBAL_START_EPOCH + 1, - // Whether any transaction is reacting. - globalIsReacting: false, - currentTransaction: null, - cleanupReactors: null, - reactionEpoch: GLOBAL_START_EPOCH + 1 -})); -function getReactionEpoch() { - return inst.reactionEpoch; -} -function getGlobalEpoch() { - return inst.globalEpoch; -} -function getIsReacting() { - return inst.globalIsReacting; + return /* @__PURE__ */ jsxRuntimeExports.jsx(Collaborator, { latestPresence: presence }); +}); +const Collaborator = track(function Collaborator2({ + latestPresence +}) { + const editor = useEditor(); + const { + CollaboratorBrush, + CollaboratorScribble, + CollaboratorCursor, + CollaboratorHint, + CollaboratorShapeIndicator + } = useEditorComponents(); + const zoomLevel = editor.getZoomLevel(); + const viewportPageBounds = editor.getViewportPageBounds(); + const { userId, chatMessage, brush, scribbles, selectedShapeIds, userName, cursor, color } = latestPresence; + const isCursorInViewport = !(cursor.x < viewportPageBounds.minX - 12 / zoomLevel || cursor.y < viewportPageBounds.minY - 16 / zoomLevel || cursor.x > viewportPageBounds.maxX - 12 / zoomLevel || cursor.y > viewportPageBounds.maxY - 16 / zoomLevel); + return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ + brush && CollaboratorBrush ? /* @__PURE__ */ jsxRuntimeExports.jsx( + CollaboratorBrush, + { + className: "tl-collaborator__brush", + brush, + color, + opacity: 0.1 + }, + userId + "_brush" + ) : null, + isCursorInViewport && CollaboratorCursor ? /* @__PURE__ */ jsxRuntimeExports.jsx( + CollaboratorCursor, + { + className: "tl-collaborator__cursor", + point: cursor, + color, + zoom: zoomLevel, + name: userName !== "New User" ? userName : null, + chatMessage + }, + userId + "_cursor" + ) : CollaboratorHint ? /* @__PURE__ */ jsxRuntimeExports.jsx( + CollaboratorHint, + { + className: "tl-collaborator__cursor-hint", + point: cursor, + color, + zoom: zoomLevel, + viewport: viewportPageBounds + }, + userId + "_cursor_hint" + ) : null, + CollaboratorScribble && scribbles.length ? /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: scribbles.map((scribble) => /* @__PURE__ */ jsxRuntimeExports.jsx( + CollaboratorScribble, + { + className: "tl-collaborator__scribble", + scribble, + color, + zoom: zoomLevel, + opacity: scribble.color === "laser" ? 0.5 : 0.1 + }, + userId + "_scribble_" + scribble.id + )) }) : null, + CollaboratorShapeIndicator && selectedShapeIds.filter((id2) => !editor.isShapeHidden(id2)).map((shapeId) => /* @__PURE__ */ jsxRuntimeExports.jsx( + CollaboratorShapeIndicator, + { + className: "tl-collaborator__shape-indicator", + shapeId, + color, + opacity: 0.5 + }, + userId + "_" + shapeId + )) + ] }); +}); +function getStateFromElapsedTime(editor, elapsed) { + return elapsed > editor.options.collaboratorInactiveTimeoutMs ? "inactive" : elapsed > editor.options.collaboratorIdleTimeoutMs ? "idle" : "active"; } -function traverse(reactors, child) { - if (child.lastTraversedEpoch === inst.globalEpoch) { - return; - } - child.lastTraversedEpoch = inst.globalEpoch; - if (child instanceof EffectScheduler) { - reactors.add(child); - } else { - child.children.visit((c2) => traverse(reactors, c2)); +function useCollaboratorState(editor, latestPresence) { + const rLastActivityTimestamp = reactExports.useRef((latestPresence == null ? void 0 : latestPresence.lastActivityTimestamp) ?? -1); + const [state, setState] = reactExports.useState( + () => getStateFromElapsedTime(editor, Date.now() - rLastActivityTimestamp.current) + ); + reactExports.useEffect(() => { + const interval = editor.timers.setInterval(() => { + setState(getStateFromElapsedTime(editor, Date.now() - rLastActivityTimestamp.current)); + }, editor.options.collaboratorCheckIntervalMs); + return () => clearInterval(interval); + }, [editor]); + if (latestPresence) { + rLastActivityTimestamp.current = latestPresence.lastActivityTimestamp; } + return state; } -function flushChanges(atoms) { - var _a3; - if (inst.globalIsReacting) { - throw new Error("flushChanges cannot be called during a reaction"); - } - const outerTxn = inst.currentTransaction; - try { - inst.currentTransaction = null; - inst.globalIsReacting = true; - inst.reactionEpoch = inst.globalEpoch; - const reactors = /* @__PURE__ */ new Set(); - for (const atom2 of atoms) { - atom2.children.visit((child) => traverse(reactors, child)); - } - for (const r2 of reactors) { - r2.maybeScheduleEffect(); +function MenuClickCapture() { + const editor = useEditor(); + const isMenuOpen = useValue("is menu open", () => editor.menus.hasAnyOpenMenus(), [editor]); + const [isPointing, setIsPointing] = reactExports.useState(false); + const showElement = isMenuOpen || isPointing; + const canvasEvents = useCanvasEvents(); + const rPointerState = reactExports.useRef({ + isDown: false, + isDragging: false, + start: new Vec() + }); + const handlePointerDown = reactExports.useCallback( + (e2) => { + if (e2.button === 0) { + setIsPointing(true); + rPointerState.current = { + isDown: true, + isDragging: false, + start: new Vec(e2.clientX, e2.clientY) + }; + } + editor.menus.clearOpenMenus(); + }, + [editor] + ); + const handlePointerMove = reactExports.useCallback( + (e2) => { + var _a3, _b2, _c2; + if (!rPointerState.current.isDown) return; + if (rPointerState.current.isDragging) { + (_a3 = canvasEvents.onPointerMove) == null ? void 0 : _a3.call(canvasEvents, e2); + return; + } + if ( + // We're pointing, but are we dragging? + Vec.Dist2(rPointerState.current.start, new Vec(e2.clientX, e2.clientY)) > editor.options.dragDistanceSquared + ) { + rPointerState.current = { + ...rPointerState.current, + isDown: true, + isDragging: true + }; + const { x: x2, y: y2 } = rPointerState.current.start; + (_b2 = canvasEvents.onPointerDown) == null ? void 0 : _b2.call(canvasEvents, { + ...e2, + clientX: x2, + clientY: y2, + button: 0 + }); + (_c2 = canvasEvents.onPointerMove) == null ? void 0 : _c2.call(canvasEvents, e2); + } + }, + [canvasEvents, editor] + ); + const handlePointerUp = reactExports.useCallback( + (e2) => { + var _a3; + (_a3 = canvasEvents.onPointerUp) == null ? void 0 : _a3.call(canvasEvents, e2); + setIsPointing(false); + rPointerState.current = { + isDown: false, + isDragging: false, + start: new Vec(e2.clientX, e2.clientY) + }; + }, + [canvasEvents] + ); + return showElement && /* @__PURE__ */ jsxRuntimeExports.jsx( + "div", + { + className: "tlui-menu-click-capture", + "data-testid": "menu-click-capture.content", + ...canvasEvents, + onPointerDown: handlePointerDown, + onPointerMove: handlePointerMove, + onPointerUp: handlePointerUp } - let updateDepth = 0; - while ((_a3 = inst.cleanupReactors) == null ? void 0 : _a3.size) { - if (updateDepth++ > 1e3) { - throw new Error("Reaction update depth limit exceeded"); + ); +} +const Shape = reactExports.memo(function Shape2({ + id: id2, + shape, + util, + index: index2, + backgroundIndex, + opacity +}) { + const editor = useEditor(); + const { ShapeErrorFallback } = useEditorComponents(); + const containerRef = reactExports.useRef(null); + const bgContainerRef = reactExports.useRef(null); + const memoizedStuffRef = reactExports.useRef({ + transform: "", + clipPath: "none", + width: 0, + height: 0, + x: 0, + y: 0, + isCulled: false + }); + useQuickReactor( + "set shape stuff", + () => { + const shape2 = editor.getShape(id2); + if (!shape2) return; + const prev = memoizedStuffRef.current; + const clipPath = editor.getShapeClipPath(id2) ?? "none"; + if (clipPath !== prev.clipPath) { + setStyleProperty(containerRef.current, "clip-path", clipPath); + setStyleProperty(bgContainerRef.current, "clip-path", clipPath); + prev.clipPath = clipPath; + } + const pageTransform = editor.getShapePageTransform(id2); + const transform = Mat.toCssString(pageTransform); + const bounds = editor.getShapeGeometry(shape2).bounds; + if (transform !== prev.transform) { + setStyleProperty(containerRef.current, "transform", transform); + setStyleProperty(bgContainerRef.current, "transform", transform); + prev.transform = transform; + } + const width = Math.max(bounds.width, 1); + const height = Math.max(bounds.height, 1); + if (width !== prev.width || height !== prev.height) { + setStyleProperty(containerRef.current, "width", width + "px"); + setStyleProperty(containerRef.current, "height", height + "px"); + setStyleProperty(bgContainerRef.current, "width", width + "px"); + setStyleProperty(bgContainerRef.current, "height", height + "px"); + prev.width = width; + prev.height = height; + } + }, + [editor] + ); + useQuickReactor( + "set opacity and z-index", + () => { + const container = containerRef.current; + const bgContainer = bgContainerRef.current; + setStyleProperty(container, "opacity", opacity); + setStyleProperty(bgContainer, "opacity", opacity); + setStyleProperty(container, "z-index", index2); + setStyleProperty(bgContainer, "z-index", backgroundIndex); + }, + [opacity, index2, backgroundIndex] + ); + useQuickReactor( + "set display", + () => { + const shape2 = editor.getShape(id2); + if (!shape2) return; + const culledShapes = editor.getCulledShapes(); + const isCulled = culledShapes.has(id2); + if (isCulled !== memoizedStuffRef.current.isCulled) { + setStyleProperty(containerRef.current, "display", isCulled ? "none" : "block"); + setStyleProperty(bgContainerRef.current, "display", isCulled ? "none" : "block"); + memoizedStuffRef.current.isCulled = isCulled; + } + }, + [editor] + ); + const annotateError2 = reactExports.useCallback( + (error) => editor.annotateError(error, { origin: "shape", willCrashApp: false }), + [editor] + ); + if (!shape) return null; + const isFilledShape = "fill" in shape.props && shape.props.fill !== "none"; + return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ + util.backgroundComponent && /* @__PURE__ */ jsxRuntimeExports.jsx( + "div", + { + ref: bgContainerRef, + className: "tl-shape tl-shape-background", + "data-shape-type": shape.type, + "data-shape-id": shape.id, + draggable: false, + children: /* @__PURE__ */ jsxRuntimeExports.jsx(OptionalErrorBoundary, { fallback: ShapeErrorFallback, onError: annotateError2, children: /* @__PURE__ */ jsxRuntimeExports.jsx(InnerShapeBackground, { shape, util }) }) + } + ), + /* @__PURE__ */ jsxRuntimeExports.jsx( + "div", + { + ref: containerRef, + className: "tl-shape", + "data-shape-type": shape.type, + "data-shape-is-filled": isFilledShape, + "data-shape-id": shape.id, + draggable: false, + children: /* @__PURE__ */ jsxRuntimeExports.jsx(OptionalErrorBoundary, { fallback: ShapeErrorFallback, onError: annotateError2, children: /* @__PURE__ */ jsxRuntimeExports.jsx(InnerShape, { shape, util }) }) + } + ) + ] }); +}); +const InnerShape = reactExports.memo( + function InnerShape2({ shape, util }) { + return useStateTracking( + "InnerShape:" + shape.type, + () => ( + // always fetch the latest shape from the store even if the props/meta have not changed, to avoid + // calling the render method with stale data. + util.component(util.editor.store.unsafeGetWithoutCapture(shape.id)) + ) + ); + }, + (prev, next) => prev.shape.props === next.shape.props && prev.shape.meta === next.shape.meta +); +const InnerShapeBackground = reactExports.memo( + function InnerShapeBackground2({ + shape, + util + }) { + return useStateTracking( + "InnerShape:" + shape.type, + () => { + var _a3; + return ( + // always fetch the latest shape from the store even if the props/meta have not changed, to avoid + // calling the render method with stale data. + (_a3 = util.backgroundComponent) == null ? void 0 : _a3.call(util, util.editor.store.unsafeGetWithoutCapture(shape.id)) + ); + } + ); + }, + (prev, next) => prev.shape.props === next.shape.props && prev.shape.meta === next.shape.meta +); +function DefaultCanvas({ className }) { + const editor = useEditor(); + const { Background, SvgDefs, ShapeIndicators } = useEditorComponents(); + const rCanvas = reactExports.useRef(null); + const rHtmlLayer = reactExports.useRef(null); + const rHtmlLayer2 = reactExports.useRef(null); + const container = useContainer(); + useScreenBounds(rCanvas); + useDocumentEvents(); + useCoarsePointer(); + useGestureEvents(rCanvas); + useFixSafariDoubleTapZoomPencilEvents(rCanvas); + const rMemoizedStuff = reactExports.useRef({ lodDisableTextOutline: false, allowTextOutline: true }); + useQuickReactor( + "position layers", + function positionLayersWhenCameraMoves() { + const { x: x2, y: y2, z } = editor.getCamera(); + if (rMemoizedStuff.current.allowTextOutline && tlenv.isSafari) { + container.style.setProperty("--tl-text-outline", "none"); + rMemoizedStuff.current.allowTextOutline = false; + } + if (rMemoizedStuff.current.allowTextOutline && z < editor.options.textShadowLod !== rMemoizedStuff.current.lodDisableTextOutline) { + const lodDisableTextOutline = z < editor.options.textShadowLod; + container.style.setProperty( + "--tl-text-outline", + lodDisableTextOutline ? "none" : `var(--tl-text-outline-reference)` + ); + rMemoizedStuff.current.lodDisableTextOutline = lodDisableTextOutline; } - const reactors2 = inst.cleanupReactors; - inst.cleanupReactors = null; - for (const r2 of reactors2) { - r2.maybeScheduleEffect(); + const offset2 = z >= 1 ? modulate(z, [1, 8], [0.125, 0.5], true) : modulate(z, [0.1, 1], [-2, 0.125], true); + const transform = `scale(${toDomPrecision(z)}) translate(${toDomPrecision( + x2 + offset2 + )}px,${toDomPrecision(y2 + offset2)}px)`; + setStyleProperty(rHtmlLayer.current, "transform", transform); + setStyleProperty(rHtmlLayer2.current, "transform", transform); + }, + [editor, container] + ); + const events = useCanvasEvents(); + const shapeSvgDefs = useValue( + "shapeSvgDefs", + () => { + const shapeSvgDefsByKey = /* @__PURE__ */ new Map(); + for (const util of objectMapValues(editor.shapeUtils)) { + if (!util) return; + const defs = util.getCanvasSvgDefs(); + for (const { key, component: Component } of defs) { + if (shapeSvgDefsByKey.has(key)) continue; + shapeSvgDefsByKey.set(key, /* @__PURE__ */ jsxRuntimeExports.jsx(Component, {}, key)); + } } - } - } finally { - inst.cleanupReactors = null; - inst.globalIsReacting = false; - inst.currentTransaction = outerTxn; - } -} -function atomDidChange(atom2, previousValue) { - if (inst.currentTransaction) { - if (!inst.currentTransaction.initialAtomValues.has(atom2)) { - inst.currentTransaction.initialAtomValues.set(atom2, previousValue); - } - } else if (inst.globalIsReacting) { - traverseAtomForCleanup(atom2); - } else { - flushChanges([atom2]); - } -} -function traverseAtomForCleanup(atom2) { - const rs = inst.cleanupReactors ?? (inst.cleanupReactors = /* @__PURE__ */ new Set()); - atom2.children.visit((child) => traverse(rs, child)); -} -function advanceGlobalEpoch() { - inst.globalEpoch++; + return [...shapeSvgDefsByKey.values()]; + }, + [editor] + ); + const hideShapes = useValue("debug_shapes", () => debugFlags.hideShapes.get(), [debugFlags]); + const debugSvg = useValue("debug_svg", () => debugFlags.debugSvg.get(), [debugFlags]); + const debugGeometry = useValue("debug_geometry", () => debugFlags.debugGeometry.get(), [ + debugFlags + ]); + const isEditingAnything = useValue( + "isEditingAnything", + () => editor.getEditingShapeId() !== null, + [editor] + ); + const isSelectingAnything = useValue( + "isSelectingAnything", + () => !!editor.getSelectedShapeIds().length, + [editor] + ); + return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ + /* @__PURE__ */ jsxRuntimeExports.jsxs( + "div", + { + ref: rCanvas, + draggable: false, + "data-iseditinganything": isEditingAnything, + "data-isselectinganything": isSelectingAnything, + className: classNames("tl-canvas", className), + "data-testid": "canvas", + ...events, + children: [ + /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { className: "tl-svg-context", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("defs", { children: [ + shapeSvgDefs, + /* @__PURE__ */ jsxRuntimeExports.jsx(CursorDef, {}), + /* @__PURE__ */ jsxRuntimeExports.jsx(CollaboratorHintDef, {}), + SvgDefs && /* @__PURE__ */ jsxRuntimeExports.jsx(SvgDefs, {}) + ] }) }), + Background && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "tl-background__wrapper", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Background, {}) }), + /* @__PURE__ */ jsxRuntimeExports.jsx(GridWrapper, {}), + /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { ref: rHtmlLayer, className: "tl-html-layer tl-shapes", draggable: false, children: [ + /* @__PURE__ */ jsxRuntimeExports.jsx(OnTheCanvasWrapper, {}), + /* @__PURE__ */ jsxRuntimeExports.jsx(SelectionBackgroundWrapper, {}), + hideShapes ? null : debugSvg ? /* @__PURE__ */ jsxRuntimeExports.jsx(ShapesWithSVGs, {}) : /* @__PURE__ */ jsxRuntimeExports.jsx(ShapesToDisplay, {}) + ] }), + /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "tl-overlays", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { ref: rHtmlLayer2, className: "tl-html-layer", children: [ + debugGeometry ? /* @__PURE__ */ jsxRuntimeExports.jsx(GeometryDebuggingView, {}) : null, + /* @__PURE__ */ jsxRuntimeExports.jsx(HandlesWrapper, {}), + /* @__PURE__ */ jsxRuntimeExports.jsx(BrushWrapper, {}), + /* @__PURE__ */ jsxRuntimeExports.jsx(ScribbleWrapper, {}), + /* @__PURE__ */ jsxRuntimeExports.jsx(ZoomBrushWrapper, {}), + ShapeIndicators && /* @__PURE__ */ jsxRuntimeExports.jsx(ShapeIndicators, {}), + /* @__PURE__ */ jsxRuntimeExports.jsx(HintedShapeIndicator, {}), + /* @__PURE__ */ jsxRuntimeExports.jsx(SnapIndicatorWrapper, {}), + /* @__PURE__ */ jsxRuntimeExports.jsx(SelectionForegroundWrapper, {}), + /* @__PURE__ */ jsxRuntimeExports.jsx(LiveCollaborators, {}) + ] }) }), + /* @__PURE__ */ jsxRuntimeExports.jsx(MovingCameraHitTestBlocker, {}) + ] + } + ), + /* @__PURE__ */ jsxRuntimeExports.jsx(MenuClickCapture, {}), + /* @__PURE__ */ jsxRuntimeExports.jsx(InFrontOfTheCanvasWrapper, {}) + ] }); } -function transaction(fn) { - const txn = new Transaction(inst.currentTransaction); - inst.currentTransaction = txn; - try { - let result = void 0; - let rollback = false; - try { - result = fn(() => rollback = true); - } catch (e2) { - txn.abort(); - throw e2; - } - if (rollback) { - txn.abort(); - } else { - txn.commit(); - } - return result; - } finally { - inst.currentTransaction = inst.currentTransaction.parent; - } +function InFrontOfTheCanvasWrapper() { + const { InFrontOfTheCanvas } = useEditorComponents(); + if (!InFrontOfTheCanvas) return null; + return /* @__PURE__ */ jsxRuntimeExports.jsx(InFrontOfTheCanvas, {}); } -function transact(fn) { - if (inst.currentTransaction) { - return fn(); - } - return transaction(fn); +function GridWrapper() { + const editor = useEditor(); + const gridSize = useValue("gridSize", () => editor.getDocumentSettings().gridSize, [editor]); + const { x: x2, y: y2, z } = useValue("camera", () => editor.getCamera(), [editor]); + const isGridMode = useValue("isGridMode", () => editor.getInstanceState().isGridMode, [editor]); + const { Grid } = useEditorComponents(); + if (!(Grid && isGridMode)) return null; + return /* @__PURE__ */ jsxRuntimeExports.jsx(Grid, { x: x2, y: y2, z, size: gridSize }); } -class __Atom__ { - constructor(name, current, options) { - __publicField(this, "isEqual"); - __publicField(this, "computeDiff"); - __publicField(this, "lastChangedEpoch", getGlobalEpoch()); - __publicField(this, "children", new ArraySet()); - __publicField(this, "historyBuffer"); - this.name = name; - this.current = current; - this.isEqual = (options == null ? void 0 : options.isEqual) ?? null; - if (!options) return; - if (options.historyLength) { - this.historyBuffer = new HistoryBuffer(options.historyLength); - } - this.computeDiff = options.computeDiff; - } - __unsafe__getWithoutCapture(_ignoreErrors) { - return this.current; - } - get() { - maybeCaptureParent(this); - return this.current; - } - set(value, diff) { - var _a3, _b2; - if (((_a3 = this.isEqual) == null ? void 0 : _a3.call(this, this.current, value)) ?? equals(this.current, value)) { - return this.current; - } - advanceGlobalEpoch(); - if (this.historyBuffer) { - this.historyBuffer.pushEntry( - this.lastChangedEpoch, - getGlobalEpoch(), - diff ?? ((_b2 = this.computeDiff) == null ? void 0 : _b2.call(this, this.current, value, this.lastChangedEpoch, getGlobalEpoch())) ?? RESET_VALUE - ); - } - this.lastChangedEpoch = getGlobalEpoch(); - const oldValue = this.current; - this.current = value; - atomDidChange(this, oldValue); - return value; - } - update(updater) { - return this.set(updater(this.current)); - } - getDiffSince(epoch) { - var _a3; - maybeCaptureParent(this); - if (epoch >= this.lastChangedEpoch) { - return EMPTY_ARRAY; - } - return ((_a3 = this.historyBuffer) == null ? void 0 : _a3.getChangesSince(epoch)) ?? RESET_VALUE; - } +function ScribbleWrapper() { + const editor = useEditor(); + const scribbles = useValue("scribbles", () => editor.getInstanceState().scribbles, [editor]); + const zoomLevel = useValue("zoomLevel", () => editor.getZoomLevel(), [editor]); + const { Scribble } = useEditorComponents(); + if (!(Scribble && scribbles.length)) return null; + return scribbles.map((scribble) => /* @__PURE__ */ jsxRuntimeExports.jsx(Scribble, { className: "tl-user-scribble", scribble, zoom: zoomLevel }, scribble.id)); } -const _Atom = singleton("Atom", () => __Atom__); -function atom(name, initialValue, options) { - return new _Atom(name, initialValue, options); +function BrushWrapper() { + const editor = useEditor(); + const brush = useValue("brush", () => editor.getInstanceState().brush, [editor]); + const { Brush } = useEditorComponents(); + if (!(Brush && brush)) return null; + return /* @__PURE__ */ jsxRuntimeExports.jsx(Brush, { className: "tl-user-brush", brush }); } -let didWarnComputedGetter = false; -function logComputedGetterWarning() { - if (didWarnComputedGetter) return; - didWarnComputedGetter = true; - console.warn( - `Using \`@computed\` as a decorator for getters is deprecated and will be removed in the near future. Please refactor to use \`@computed\` as a decorator for methods. - -// Before -@computed -get foo() { - return 'foo' +function ZoomBrushWrapper() { + const editor = useEditor(); + const zoomBrush = useValue("zoomBrush", () => editor.getInstanceState().zoomBrush, [editor]); + const { ZoomBrush } = useEditorComponents(); + if (!(ZoomBrush && zoomBrush)) return null; + return /* @__PURE__ */ jsxRuntimeExports.jsx(ZoomBrush, { className: "tl-user-brush tl-zoom-brush", brush: zoomBrush }); } - -// After -@computed -getFoo() { - return 'foo' +function SnapIndicatorWrapper() { + const editor = useEditor(); + const lines = useValue("snapLines", () => editor.snaps.getIndicators(), [editor]); + const zoomLevel = useValue("zoomLevel", () => editor.getZoomLevel(), [editor]); + const { SnapIndicator } = useEditorComponents(); + if (!(SnapIndicator && lines.length > 0)) return null; + return lines.map((line) => /* @__PURE__ */ jsxRuntimeExports.jsx(SnapIndicator, { className: "tl-user-snapline", line, zoom: zoomLevel }, line.id)); } -` +function HandlesWrapper() { + const editor = useEditor(); + const shapeIdWithHandles = useValue( + "handles shapeIdWithHandles", + () => { + const { isReadonly, isChangingStyle } = editor.getInstanceState(); + if (isReadonly || isChangingStyle) return false; + const onlySelectedShape = editor.getOnlySelectedShape(); + if (!onlySelectedShape) return false; + const handles = editor.getShapeHandles(onlySelectedShape); + if (!handles) return false; + return onlySelectedShape.id; + }, + [editor] ); + if (!shapeIdWithHandles) return null; + return /* @__PURE__ */ jsxRuntimeExports.jsx(HandlesWrapperInner, { shapeId: shapeIdWithHandles }); } -const UNINITIALIZED = Symbol.for("com.tldraw.state/UNINITIALIZED"); -function isUninitialized(value) { - return value === UNINITIALIZED; -} -const WithDiff = singleton( - "WithDiff", - () => class WithDiff { - constructor(value, diff) { - this.value = value; - this.diff = diff; - } - } -); -function withDiff(value, diff) { - return new WithDiff(value, diff); -} -class __UNSAFE__Computed { - constructor(name, derive, options) { - __publicField(this, "lastChangedEpoch", GLOBAL_START_EPOCH); - __publicField(this, "lastTraversedEpoch", GLOBAL_START_EPOCH); - /** - * The epoch when the reactor was last checked. - */ - __publicField(this, "lastCheckedEpoch", GLOBAL_START_EPOCH); - __publicField(this, "parentSet", new ArraySet()); - __publicField(this, "parents", []); - __publicField(this, "parentEpochs", []); - __publicField(this, "children", new ArraySet()); - __publicField(this, "historyBuffer"); - // The last-computed value of this signal. - __publicField(this, "state", UNINITIALIZED); - // If the signal throws an error we stash it so we can rethrow it on the next get() - __publicField(this, "error", null); - __publicField(this, "computeDiff"); - __publicField(this, "isEqual"); - this.name = name; - this.derive = derive; - if (options == null ? void 0 : options.historyLength) { - this.historyBuffer = new HistoryBuffer(options.historyLength); - } - this.computeDiff = options == null ? void 0 : options.computeDiff; - this.isEqual = (options == null ? void 0 : options.isEqual) ?? equals; - } - // eslint-disable-next-line no-restricted-syntax - get isActivelyListening() { - return !this.children.isEmpty; - } - __unsafe__getWithoutCapture(ignoreErrors) { - var _a3; - const isNew = this.lastChangedEpoch === GLOBAL_START_EPOCH; - const globalEpoch = getGlobalEpoch(); - if (!isNew && (this.lastCheckedEpoch === globalEpoch || this.isActivelyListening && getIsReacting() && this.lastTraversedEpoch < getReactionEpoch() || !haveParentsChanged(this))) { - this.lastCheckedEpoch = globalEpoch; - if (this.error) { - if (!ignoreErrors) { - throw this.error.thrownValue; - } else { - return this.state; - } - } else { - return this.state; - } - } - try { - startCapturingParents(this); - const result = this.derive(this.state, this.lastCheckedEpoch); - const newState = result instanceof WithDiff ? result.value : result; - const isUninitialized2 = this.state === UNINITIALIZED; - if (isUninitialized2 || !this.isEqual(newState, this.state)) { - if (this.historyBuffer && !isUninitialized2) { - const diff = result instanceof WithDiff ? result.diff : void 0; - this.historyBuffer.pushEntry( - this.lastChangedEpoch, - getGlobalEpoch(), - diff ?? ((_a3 = this.computeDiff) == null ? void 0 : _a3.call(this, this.state, newState, this.lastCheckedEpoch, getGlobalEpoch())) ?? RESET_VALUE - ); - } - this.lastChangedEpoch = getGlobalEpoch(); - this.state = newState; - } - this.error = null; - this.lastCheckedEpoch = getGlobalEpoch(); - return this.state; - } catch (e2) { - if (this.state !== UNINITIALIZED) { - this.state = UNINITIALIZED; - this.lastChangedEpoch = getGlobalEpoch(); - } - this.lastCheckedEpoch = getGlobalEpoch(); - if (this.historyBuffer) { - this.historyBuffer.clear(); - } - this.error = { thrownValue: e2 }; - if (!ignoreErrors) throw e2; - return this.state; - } finally { - stopCapturingParents(); - } - } - get() { - try { - return this.__unsafe__getWithoutCapture(); - } finally { - maybeCaptureParent(this); - } - } - getDiffSince(epoch) { - var _a3; - this.__unsafe__getWithoutCapture(true); - maybeCaptureParent(this); - if (epoch >= this.lastChangedEpoch) { - return EMPTY_ARRAY; - } - return ((_a3 = this.historyBuffer) == null ? void 0 : _a3.getChangesSince(epoch)) ?? RESET_VALUE; - } -} -const _Computed = singleton("Computed", () => __UNSAFE__Computed); -function computedMethodLegacyDecorator(options = {}, _target, key, descriptor) { - const originalMethod = descriptor.value; - const derivationKey = Symbol.for("__@tldraw/state__computed__" + key); - descriptor.value = function() { - let d2 = this[derivationKey]; - if (!d2) { - d2 = new _Computed(key, originalMethod.bind(this), options); - Object.defineProperty(this, derivationKey, { - enumerable: false, - configurable: false, - writable: false, - value: d2 - }); - } - return d2.get(); - }; - descriptor.value[isComputedMethodKey] = true; - return descriptor; -} -function computedGetterLegacyDecorator(options = {}, _target, key, descriptor) { - const originalMethod = descriptor.get; - const derivationKey = Symbol.for("__@tldraw/state__computed__" + key); - descriptor.get = function() { - let d2 = this[derivationKey]; - if (!d2) { - d2 = new _Computed(key, originalMethod.bind(this), options); - Object.defineProperty(this, derivationKey, { - enumerable: false, - configurable: false, - writable: false, - value: d2 - }); - } - return d2.get(); - }; - return descriptor; -} -function computedMethodTc39Decorator(options, compute, context) { - assert(context.kind === "method", "@computed can only be used on methods"); - const derivationKey = Symbol.for("__@tldraw/state__computed__" + String(context.name)); - const fn = function() { - let d2 = this[derivationKey]; - if (!d2) { - d2 = new _Computed(String(context.name), compute.bind(this), options); - Object.defineProperty(this, derivationKey, { - enumerable: false, - configurable: false, - writable: false, - value: d2 - }); - } - return d2.get(); - }; - fn[isComputedMethodKey] = true; - return fn; -} -function computedDecorator(options = {}, args) { - if (args.length === 2) { - const [originalMethod, context] = args; - return computedMethodTc39Decorator(options, originalMethod, context); - } else { - const [_target, key, descriptor] = args; - if (descriptor.get) { - logComputedGetterWarning(); - return computedGetterLegacyDecorator(options, _target, key, descriptor); - } else { - return computedMethodLegacyDecorator(options, _target, key, descriptor); - } +function HandlesWrapperInner({ shapeId }) { + const editor = useEditor(); + const { Handles } = useEditorComponents(); + const zoomLevel = useValue("zoomLevel", () => editor.getZoomLevel(), [editor]); + const isCoarse = useValue("coarse pointer", () => editor.getInstanceState().isCoarsePointer, [ + editor + ]); + const transform = useValue("handles transform", () => editor.getShapePageTransform(shapeId), [ + editor, + shapeId + ]); + const handles = useValue( + "handles", + () => { + const handles2 = editor.getShapeHandles(shapeId); + if (!handles2) return null; + const minDistBetweenVirtualHandlesAndRegularHandles = (isCoarse ? editor.options.coarseHandleRadius : editor.options.handleRadius) / zoomLevel * 2; + return handles2.filter( + (handle) => ( + // if the handle isn't a virtual handle, we'll display it + // but for virtual handles, we'll only display them if they're far enough away from vertex handles + handle.type !== "virtual" || !handles2.some( + (h2) => ( + // skip the handle we're checking against + // and check that their distance isn't below the minimum distance + h2 !== handle && // only check against vertex handles + h2.type === "vertex" && Vec.Dist(handle, h2) < minDistBetweenVirtualHandlesAndRegularHandles + ) + ) + ) + ).sort((a2) => a2.type === "vertex" ? 1 : -1); + }, + [editor, zoomLevel, isCoarse, shapeId] + ); + const isHidden2 = useValue("isHidden", () => editor.isShapeHidden(shapeId), [editor, shapeId]); + if (!Handles || !handles || !transform || isHidden2) { + return null; } + return /* @__PURE__ */ jsxRuntimeExports.jsx(Handles, { children: /* @__PURE__ */ jsxRuntimeExports.jsx("g", { transform: Mat.toCssString(transform), children: handles.map((handle) => { + return /* @__PURE__ */ jsxRuntimeExports.jsx( + HandleWrapper, + { + shapeId, + handle, + zoom: zoomLevel, + isCoarse + }, + handle.id + ); + }) }) }); } -const isComputedMethodKey = "@@__isComputedMethod__@@"; -function computed() { - if (arguments.length === 1) { - const options = arguments[0]; - return (...args) => computedDecorator(options, args); - } else if (typeof arguments[0] === "string") { - return new _Computed(arguments[0], arguments[1], arguments[2]); - } else { - return computedDecorator(void 0, arguments); - } +function HandleWrapper({ + shapeId, + handle, + zoom, + isCoarse +}) { + const events = useHandleEvents(shapeId, handle.id); + const { Handle } = useEditorComponents(); + if (!Handle) return null; + return /* @__PURE__ */ jsxRuntimeExports.jsx("g", { "aria-label": "handle", transform: `translate(${handle.x}, ${handle.y})`, ...events, children: /* @__PURE__ */ jsxRuntimeExports.jsx(Handle, { shapeId, handle, zoom, isCoarse }) }); } -const currentApiVersion = 1; -const actualApiVersion = singleton("apiVersion", () => currentApiVersion); -if (actualApiVersion !== currentApiVersion) { - throw new Error( - `You have multiple incompatible versions of @tldraw/state in your app. Please deduplicate the package.` +function ShapesWithSVGs() { + const editor = useEditor(); + const renderingShapes = useValue("rendering shapes", () => editor.getRenderingShapes(), [editor]); + return renderingShapes.map((result) => /* @__PURE__ */ jsxRuntimeExports.jsxs(reactExports.Fragment, { children: [ + /* @__PURE__ */ jsxRuntimeExports.jsx(Shape, { ...result }), + /* @__PURE__ */ jsxRuntimeExports.jsx(DebugSvgCopy, { id: result.id, mode: "iframe" }) + ] }, result.id + "_fragment")); +} +function ReflowIfNeeded() { + const editor = useEditor(); + const culledShapesRef = reactExports.useRef(/* @__PURE__ */ new Set()); + useQuickReactor( + "reflow for culled shapes", + () => { + const culledShapes = editor.getCulledShapes(); + if (culledShapesRef.current.size === culledShapes.size && [...culledShapes].every((id2) => culledShapesRef.current.has(id2))) + return; + culledShapesRef.current = culledShapes; + const canvas = document.getElementsByClassName("tl-canvas"); + if (canvas.length === 0) return; + canvas[0].offsetHeight; + }, + [editor] ); + return null; } -registerTldrawLibraryVersion( - "@tldraw/state", - "3.4.1", - "esm" -); -function useStateTracking(name, render) { - const renderRef = React.useRef(render); - renderRef.current = render; - const [scheduler2, subscribe, getSnapshot2] = React.useMemo(() => { - let scheduleUpdate = null; - const subscribe2 = (cb2) => { - scheduleUpdate = cb2; - return () => { - scheduleUpdate = null; - }; - }; - const scheduler22 = new EffectScheduler( - `useStateTracking(${name})`, - // this is what `scheduler.execute()` will call - () => { - var _a3; - return (_a3 = renderRef.current) == null ? void 0 : _a3.call(renderRef); - }, - // this is what will be invoked when @tldraw/state detects a change in an upstream reactive value - { - scheduleEffect() { - scheduleUpdate == null ? void 0 : scheduleUpdate(); - } - } - ); - const getSnapshot22 = () => scheduler22.scheduleCount; - return [scheduler22, subscribe2, getSnapshot22]; - }, [name]); - React.useSyncExternalStore(subscribe, getSnapshot2, getSnapshot2); - React.useEffect(() => { - scheduler2.attach(); - scheduler2.maybeScheduleEffect(); - return () => { - scheduler2.detach(); - }; - }, [scheduler2]); - return scheduler2.execute(); +function ShapesToDisplay() { + const editor = useEditor(); + const renderingShapes = useValue("rendering shapes", () => editor.getRenderingShapes(), [editor]); + return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ + renderingShapes.map((result) => /* @__PURE__ */ jsxRuntimeExports.jsx(Shape, { ...result }, result.id + "_shape")), + tlenv.isSafari && /* @__PURE__ */ jsxRuntimeExports.jsx(ReflowIfNeeded, {}) + ] }); } -const ProxyHandlers = { - /** - * This is a function call trap for functional components. When this is called, we know it means - * React did run 'Component()', that means we can use any hooks here to setup our effect and - * store. - * - * With the native Proxy, all other calls such as access/setting to/of properties will be - * forwarded to the target Component, so we don't need to copy the Component's own or inherited - * properties. - * - * @see https://github.com/facebook/react/blob/2d80a0cd690bb5650b6c8a6c079a87b5dc42bd15/packages/react-reconciler/src/ReactFiberHooks.old.js#L460 - */ - apply(Component, thisArg, argumentsList) { - return useStateTracking( - Component.displayName ?? Component.name ?? "tracked(???)", - () => Component.apply(thisArg, argumentsList) - ); - } -}; -const ReactMemoSymbol = Symbol.for("react.memo"); -const ReactForwardRefSymbol = Symbol.for("react.forward_ref"); -function track(baseComponent) { - let compare = null; - const $$typeof = baseComponent["$$typeof"]; - if ($$typeof === ReactMemoSymbol) { - baseComponent = baseComponent.type; - compare = baseComponent.compare; - } - if ($$typeof === ReactForwardRefSymbol) { - return reactExports.memo(reactExports.forwardRef(new Proxy(baseComponent.render, ProxyHandlers))); - } - return reactExports.memo(new Proxy(baseComponent, ProxyHandlers), compare); +function HintedShapeIndicator() { + const editor = useEditor(); + const { ShapeIndicator } = useEditorComponents(); + const ids = useValue("hinting shape ids", () => dedupe(editor.getHintingShapeIds()), [editor]); + if (!ids.length) return null; + if (!ShapeIndicator) return null; + return ids.map((id2) => /* @__PURE__ */ jsxRuntimeExports.jsx(ShapeIndicator, { className: "tl-user-indicator__hint", shapeId: id2 }, id2 + "_hinting")); } -function useAtom(name, valueOrInitialiser, options) { - return reactExports.useState(() => { - const initialValue = typeof valueOrInitialiser === "function" ? valueOrInitialiser() : valueOrInitialiser; - return atom(`useAtom(${name})`, initialValue, options); - })[0]; +function CursorDef() { + return /* @__PURE__ */ jsxRuntimeExports.jsxs("g", { id: useSharedSafeId("cursor"), children: [ + /* @__PURE__ */ jsxRuntimeExports.jsxs("g", { fill: "rgba(0,0,0,.2)", transform: "translate(-11,-11)", children: [ + /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "m12 24.4219v-16.015l11.591 11.619h-6.781l-.411.124z" }), + /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "m21.0845 25.0962-3.605 1.535-4.682-11.089 3.686-1.553z" }) + ] }), + /* @__PURE__ */ jsxRuntimeExports.jsxs("g", { fill: "white", transform: "translate(-12,-12)", children: [ + /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "m12 24.4219v-16.015l11.591 11.619h-6.781l-.411.124z" }), + /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "m21.0845 25.0962-3.605 1.535-4.682-11.089 3.686-1.553z" }) + ] }), + /* @__PURE__ */ jsxRuntimeExports.jsxs("g", { fill: "currentColor", transform: "translate(-12,-12)", children: [ + /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "m19.751 24.4155-1.844.774-3.1-7.374 1.841-.775z" }), + /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "m13 10.814v11.188l2.969-2.866.428-.139h4.768z" }) + ] }) + ] }); } -function useComputed$1() { - const name = arguments[0]; - const compute = arguments[1]; - const opts = arguments.length === 3 ? void 0 : arguments[2]; - const deps = arguments.length === 3 ? arguments[2] : arguments[3]; - return reactExports.useMemo(() => computed(`useComputed(${name})`, compute, opts), deps); +function CollaboratorHintDef() { + const cursorHintId = useSharedSafeId("cursor_hint"); + return /* @__PURE__ */ jsxRuntimeExports.jsx("path", { id: cursorHintId, fill: "currentColor", d: "M -2,-5 2,0 -2,5 Z" }); } -function useQuickReactor(name, reactFn, deps = EMPTY_ARRAY) { +function DebugSvgCopy({ id: id2, mode }) { + const editor = useEditor(); + const [image, setImage] = reactExports.useState(null); + const isInRoot = useValue( + "is in root", + () => { + const shape = editor.getShape(id2); + return (shape == null ? void 0 : shape.parentId) === editor.getCurrentPageId(); + }, + [editor, id2] + ); reactExports.useEffect(() => { - const scheduler2 = new EffectScheduler(name, reactFn); - scheduler2.attach(); - scheduler2.execute(); + if (!isInRoot) return; + let latest = null; + const unsubscribe = react("shape to svg", async () => { + const renderId = Math.random(); + latest = renderId; + const isSingleFrame = editor.isShapeOfType(id2, "frame"); + const padding = isSingleFrame ? 0 : 10; + let bounds = editor.getShapePageBounds(id2); + if (!bounds) return; + bounds = bounds.clone().expandBy(padding); + const result = await editor.getSvgString([id2], { + padding, + background: editor.getInstanceState().exportBackground + }); + if (latest !== renderId || !result) return; + const svgDataUrl = `data:image/svg+xml;utf8,${encodeURIComponent(result.svg)}`; + setImage({ src: svgDataUrl, bounds }); + }); return () => { - scheduler2.detach(); + latest = null; + unsubscribe(); }; - }, deps); -} -function useValue() { - const args = arguments; - const deps = args.length === 3 ? args[2] : [args[0]]; - const name = args.length === 3 ? args[0] : `useValue(${args[0].name})`; - const isInRender = reactExports.useRef(true); - isInRender.current = true; - const $val = reactExports.useMemo(() => { - if (args.length === 1) { - return args[0]; - } - return computed(name, () => { - if (isInRender.current) { - return args[1](); - } else { - try { - return args[1](); - } catch { - return {}; + }, [editor, id2, isInRoot]); + if (!isInRoot || !image) return null; + if (mode === "iframe") { + return /* @__PURE__ */ jsxRuntimeExports.jsx( + "iframe", + { + src: image.src, + width: image.bounds.width, + height: image.bounds.height, + referrerPolicy: "no-referrer", + style: { + position: "absolute", + top: 0, + left: 0, + border: "none", + transform: `translate(${image.bounds.x}px, ${image.bounds.maxY + 12}px)`, + outline: "1px solid black", + maxWidth: "none" } } - }); - }, deps); - try { - const { subscribe, getSnapshot: getSnapshot2 } = reactExports.useMemo(() => { - return { - subscribe: (listen) => { - return react(`useValue(${name})`, () => { - $val.get(); - listen(); - }); - }, - getSnapshot: () => $val.get() - }; - }, [$val]); - return reactExports.useSyncExternalStore(subscribe, getSnapshot2, getSnapshot2); - } finally { - isInRender.current = false; - } -} -registerTldrawLibraryVersion( - "@tldraw/state-react", - "3.4.1", - "esm" -); -class IncrementalSetConstructor { - constructor(previousValue) { - /** - * The next value of the set. - * - * @internal - */ - __publicField(this, "nextValue"); - /** - * The diff of the set. - * - * @internal - */ - __publicField(this, "diff"); - this.previousValue = previousValue; - } - /** - * Get the next value of the set. - * - * @public - */ - get() { - var _a3, _b2, _c2, _d2; - const numRemoved = ((_b2 = (_a3 = this.diff) == null ? void 0 : _a3.removed) == null ? void 0 : _b2.size) ?? 0; - const numAdded = ((_d2 = (_c2 = this.diff) == null ? void 0 : _c2.added) == null ? void 0 : _d2.size) ?? 0; - if (numRemoved === 0 && numAdded === 0) { - return void 0; - } - return { value: this.nextValue, diff: this.diff }; - } - /** - * Add an item to the set. - * - * @param item - The item to add. - * @param wasAlreadyPresent - Whether the item was already present in the set. - * @internal - */ - _add(item, wasAlreadyPresent) { - var _a3, _b2; - this.nextValue ?? (this.nextValue = new Set(this.previousValue)); - this.nextValue.add(item); - this.diff ?? (this.diff = {}); - if (wasAlreadyPresent) { - (_a3 = this.diff.removed) == null ? void 0 : _a3.delete(item); - } else { - (_b2 = this.diff).added ?? (_b2.added = /* @__PURE__ */ new Set()); - this.diff.added.add(item); - } - } - /** - * Add an item to the set. - * - * @param item - The item to add. - * @public - */ - add(item) { - var _a3, _b2, _c2; - const wasAlreadyPresent = this.previousValue.has(item); - if (wasAlreadyPresent) { - const wasRemoved = (_b2 = (_a3 = this.diff) == null ? void 0 : _a3.removed) == null ? void 0 : _b2.has(item); - if (!wasRemoved) return; - return this._add(item, wasAlreadyPresent); - } - const isCurrentlyPresent = (_c2 = this.nextValue) == null ? void 0 : _c2.has(item); - if (isCurrentlyPresent) return; - this._add(item, wasAlreadyPresent); - } - /** - * Remove an item from the set. - * - * @param item - The item to remove. - * @param wasAlreadyPresent - Whether the item was already present in the set. - * @internal - */ - _remove(item, wasAlreadyPresent) { - var _a3, _b2; - this.nextValue ?? (this.nextValue = new Set(this.previousValue)); - this.nextValue.delete(item); - this.diff ?? (this.diff = {}); - if (wasAlreadyPresent) { - (_a3 = this.diff).removed ?? (_a3.removed = /* @__PURE__ */ new Set()); - this.diff.removed.add(item); - } else { - (_b2 = this.diff.added) == null ? void 0 : _b2.delete(item); - } - } - /** - * Remove an item from the set. - * - * @param item - The item to remove. - * @public - */ - remove(item) { - var _a3, _b2, _c2, _d2; - const wasAlreadyPresent = this.previousValue.has(item); - if (!wasAlreadyPresent) { - const wasAdded = (_b2 = (_a3 = this.diff) == null ? void 0 : _a3.added) == null ? void 0 : _b2.has(item); - if (!wasAdded) return; - return this._remove(item, wasAlreadyPresent); - } - const hasAlreadyBeenRemoved = (_d2 = (_c2 = this.diff) == null ? void 0 : _c2.removed) == null ? void 0 : _d2.has(item); - if (hasAlreadyBeenRemoved) return; - this._remove(item, wasAlreadyPresent); - } -} -class RecordType { - constructor(typeName, config) { - __publicField(this, "createDefaultProperties"); - __publicField(this, "validator"); - __publicField(this, "ephemeralKeys"); - __publicField(this, "ephemeralKeySet"); - __publicField(this, "scope"); - this.typeName = typeName; - this.createDefaultProperties = config.createDefaultProperties; - this.validator = config.validator ?? { validate: (r2) => r2 }; - this.scope = config.scope ?? "document"; - this.ephemeralKeys = config.ephemeralKeys; - const ephemeralKeySet = /* @__PURE__ */ new Set(); - if (config.ephemeralKeys) { - for (const [key, isEphemeral] of objectMapEntries(config.ephemeralKeys)) { - if (isEphemeral) ephemeralKeySet.add(key); - } - } - this.ephemeralKeySet = ephemeralKeySet; - } - /** - * Create a new record of this type. - * - * @param properties - The properties of the record. - * @returns The new record. - */ - create(properties) { - const result = { ...this.createDefaultProperties(), id: this.createId() }; - for (const [k2, v2] of Object.entries(properties)) { - if (v2 !== void 0) { - result[k2] = v2; - } - } - result.typeName = this.typeName; - return result; - } - /** - * Clone a record of this type. - * - * @param record - The record to clone. - * @returns The cloned record. - * @public - */ - clone(record) { - return { ...structuredClone(record), id: this.createId() }; - } - /** - * Create a new ID for this record type. - * - * @example - * - * ```ts - * const id = recordType.createId() - * ``` - * - * @returns The new ID. - * @public - */ - createId(customUniquePart) { - return this.typeName + ":" + (customUniquePart ?? uniqueId()); - } - /** - * Create a new ID for this record type based on the given ID. - * - * @example - * - * ```ts - * const id = recordType.createCustomId('myId') - * ``` - * - * @deprecated - Use `createId` instead. - * @param id - The ID to base the new ID on. - * @returns The new ID. - */ - createCustomId(id2) { - return this.typeName + ":" + id2; - } - /** - * Takes an id like `user:123` and returns the part after the colon `123` - * - * @param id - The id - * @returns - */ - parseId(id2) { - if (!this.isId(id2)) { - throw new Error(`ID "${id2}" is not a valid ID for type "${this.typeName}"`); - } - return id2.slice(this.typeName.length + 1); - } - /** - * Check whether a record is an instance of this record type. - * - * @example - * - * ```ts - * const result = recordType.isInstance(someRecord) - * ``` - * - * @param record - The record to check. - * @returns Whether the record is an instance of this record type. - */ - isInstance(record) { - return (record == null ? void 0 : record.typeName) === this.typeName; - } - /** - * Check whether an id is an id of this type. - * - * @example - * - * ```ts - * const result = recordType.isIn('someId') - * ``` - * - * @param id - The id to check. - * @returns Whether the id is an id of this type. - */ - isId(id2) { - if (!id2) return false; - for (let i2 = 0; i2 < this.typeName.length; i2++) { - if (id2[i2] !== this.typeName[i2]) return false; - } - return id2[this.typeName.length] === ":"; - } - /** - * Create a new RecordType that has the same type name as this RecordType and includes the given - * default properties. - * - * @example - * - * ```ts - * const authorType = createRecordType('author', () => ({ living: true })) - * const deadAuthorType = authorType.withDefaultProperties({ living: false }) - * ``` - * - * @param createDefaultProperties - A function that returns the default properties of the new RecordType. - * @returns The new RecordType. - */ - withDefaultProperties(createDefaultProperties) { - return new RecordType(this.typeName, { - createDefaultProperties, - validator: this.validator, - scope: this.scope, - ephemeralKeys: this.ephemeralKeys - }); + ); } - /** - * Check that the passed in record passes the validations for this type. Returns its input - * correctly typed if it does, but throws an error otherwise. - */ - validate(record, recordBefore) { - if (recordBefore && this.validator.validateUsingKnownGoodVersion) { - return this.validator.validateUsingKnownGoodVersion(recordBefore, record); + return /* @__PURE__ */ jsxRuntimeExports.jsx( + "img", + { + src: image.src, + width: image.bounds.width, + height: image.bounds.height, + referrerPolicy: "no-referrer", + style: { + position: "absolute", + top: 0, + left: 0, + transform: `translate(${image.bounds.x}px, ${image.bounds.maxY + 12}px)`, + outline: "1px solid black", + maxWidth: "none" + } } - return this.validator.validate(record); - } -} -function createRecordType(typeName, config) { - return new RecordType(typeName, { - createDefaultProperties: () => ({}), - validator: config.validator, - scope: config.scope, - ephemeralKeys: config.ephemeralKeys - }); -} -function createEmptyRecordsDiff() { - return { added: {}, updated: {}, removed: {} }; + ); } -function reverseRecordsDiff(diff) { - const result = { added: diff.removed, removed: diff.added, updated: {} }; - for (const [from, to] of Object.values(diff.updated)) { - result.updated[from.id] = [to, from]; - } - return result; +function SelectionForegroundWrapper() { + const editor = useEditor(); + const selectionRotation = useValue("selection rotation", () => editor.getSelectionRotation(), [ + editor + ]); + const selectionBounds = useValue( + "selection bounds", + () => editor.getSelectionRotatedPageBounds(), + [editor] + ); + const { SelectionForeground } = useEditorComponents(); + if (!selectionBounds || !SelectionForeground) return null; + return /* @__PURE__ */ jsxRuntimeExports.jsx(SelectionForeground, { bounds: selectionBounds, rotation: selectionRotation }); } -function isRecordsDiffEmpty(diff) { - return Object.keys(diff.added).length === 0 && Object.keys(diff.updated).length === 0 && Object.keys(diff.removed).length === 0; +function SelectionBackgroundWrapper() { + const editor = useEditor(); + const selectionRotation = useValue("selection rotation", () => editor.getSelectionRotation(), [ + editor + ]); + const selectionBounds = useValue( + "selection bounds", + () => editor.getSelectionRotatedPageBounds(), + [editor] + ); + const { SelectionBackground } = useEditorComponents(); + if (!selectionBounds || !SelectionBackground) return null; + return /* @__PURE__ */ jsxRuntimeExports.jsx(SelectionBackground, { bounds: selectionBounds, rotation: selectionRotation }); } -function squashRecordDiffs(diffs) { - const result = { added: {}, removed: {}, updated: {} }; - squashRecordDiffsMutable(result, diffs); - return result; +function OnTheCanvasWrapper() { + const { OnTheCanvas } = useEditorComponents(); + if (!OnTheCanvas) return null; + return /* @__PURE__ */ jsxRuntimeExports.jsx(OnTheCanvas, {}); } -function squashRecordDiffsMutable(target, diffs) { - for (const diff of diffs) { - for (const [id2, value] of objectMapEntries(diff.added)) { - if (target.removed[id2]) { - const original = target.removed[id2]; - delete target.removed[id2]; - if (original !== value) { - target.updated[id2] = [original, value]; - } - } else { - target.added[id2] = value; - } - } - for (const [id2, [_from, to]] of objectMapEntries(diff.updated)) { - if (target.added[id2]) { - target.added[id2] = to; - delete target.updated[id2]; - delete target.removed[id2]; - continue; - } - if (target.updated[id2]) { - target.updated[id2] = [target.updated[id2][0], to]; - delete target.removed[id2]; - continue; - } - target.updated[id2] = diff.updated[id2]; - delete target.removed[id2]; - } - for (const [id2, value] of objectMapEntries(diff.removed)) { - if (target.added[id2]) { - delete target.added[id2]; - } else if (target.updated[id2]) { - target.removed[id2] = target.updated[id2][0]; - delete target.updated[id2]; - } else { - target.removed[id2] = value; - } +function MovingCameraHitTestBlocker() { + const editor = useEditor(); + const cameraState = useValue("camera state", () => editor.getCameraState(), [editor]); + return /* @__PURE__ */ jsxRuntimeExports.jsx( + "div", + { + className: classNames("tl-hit-test-blocker", { + "tl-hit-test-blocker__hidden": cameraState === "idle" + }) } - } + ); } -var lodash_isequal = { exports: {} }; -lodash_isequal.exports; -(function(module, exports) { - var LARGE_ARRAY_SIZE2 = 200; - var HASH_UNDEFINED2 = "__lodash_hash_undefined__"; - var COMPARE_PARTIAL_FLAG = 1, COMPARE_UNORDERED_FLAG = 2; - var MAX_SAFE_INTEGER2 = 9007199254740991; - var argsTag = "[object Arguments]", arrayTag = "[object Array]", asyncTag = "[object AsyncFunction]", boolTag = "[object Boolean]", dateTag = "[object Date]", errorTag = "[object Error]", funcTag2 = "[object Function]", genTag2 = "[object GeneratorFunction]", mapTag = "[object Map]", numberTag = "[object Number]", nullTag = "[object Null]", objectTag = "[object Object]", promiseTag = "[object Promise]", proxyTag = "[object Proxy]", regexpTag = "[object RegExp]", setTag = "[object Set]", stringTag = "[object String]", symbolTag2 = "[object Symbol]", undefinedTag = "[object Undefined]", weakMapTag = "[object WeakMap]"; - var arrayBufferTag = "[object ArrayBuffer]", dataViewTag = "[object DataView]", float32Tag = "[object Float32Array]", float64Tag = "[object Float64Array]", int8Tag = "[object Int8Array]", int16Tag = "[object Int16Array]", int32Tag = "[object Int32Array]", uint8Tag = "[object Uint8Array]", uint8ClampedTag = "[object Uint8ClampedArray]", uint16Tag = "[object Uint16Array]", uint32Tag = "[object Uint32Array]"; - var reRegExpChar2 = /[\\^$.*+?()[\]{}|]/g; - var reIsHostCtor2 = /^\[object .+?Constructor\]$/; - var reIsUint = /^(?:0|[1-9]\d*)$/; - var typedArrayTags = {}; - typedArrayTags[float32Tag] = typedArrayTags[float64Tag] = typedArrayTags[int8Tag] = typedArrayTags[int16Tag] = typedArrayTags[int32Tag] = typedArrayTags[uint8Tag] = typedArrayTags[uint8ClampedTag] = typedArrayTags[uint16Tag] = typedArrayTags[uint32Tag] = true; - typedArrayTags[argsTag] = typedArrayTags[arrayTag] = typedArrayTags[arrayBufferTag] = typedArrayTags[boolTag] = typedArrayTags[dataViewTag] = typedArrayTags[dateTag] = typedArrayTags[errorTag] = typedArrayTags[funcTag2] = typedArrayTags[mapTag] = typedArrayTags[numberTag] = typedArrayTags[objectTag] = typedArrayTags[regexpTag] = typedArrayTags[setTag] = typedArrayTags[stringTag] = typedArrayTags[weakMapTag] = false; - var freeGlobal2 = typeof commonjsGlobal == "object" && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal; - var freeSelf2 = typeof self == "object" && self && self.Object === Object && self; - var root2 = freeGlobal2 || freeSelf2 || Function("return this")(); - var freeExports = exports && !exports.nodeType && exports; - var freeModule = freeExports && true && module && !module.nodeType && module; - var moduleExports = freeModule && freeModule.exports === freeExports; - var freeProcess = moduleExports && freeGlobal2.process; - var nodeUtil = function() { - try { - return freeProcess && freeProcess.binding && freeProcess.binding("util"); - } catch (e2) { - } - }(); - var nodeIsTypedArray = nodeUtil && nodeUtil.isTypedArray; - function arrayFilter(array2, predicate) { - var index2 = -1, length = array2 == null ? 0 : array2.length, resIndex = 0, result = []; - while (++index2 < length) { - var value = array2[index2]; - if (predicate(value, index2, array2)) { - result[resIndex++] = value; - } - } - return result; - } - function arrayPush(array2, values) { - var index2 = -1, length = values.length, offset2 = array2.length; - while (++index2 < length) { - array2[offset2 + index2] = values[index2]; - } - return array2; - } - function arraySome(array2, predicate) { - var index2 = -1, length = array2 == null ? 0 : array2.length; - while (++index2 < length) { - if (predicate(array2[index2], index2, array2)) { - return true; - } - } - return false; - } - function baseTimes(n2, iteratee) { - var index2 = -1, result = Array(n2); - while (++index2 < n2) { - result[index2] = iteratee(index2); - } - return result; - } - function baseUnary(func) { - return function(value) { - return func(value); - }; - } - function cacheHas2(cache, key) { - return cache.has(key); - } - function getValue2(object2, key) { - return object2 == null ? void 0 : object2[key]; - } - function mapToArray(map) { - var index2 = -1, result = Array(map.size); - map.forEach(function(value, key) { - result[++index2] = [key, value]; - }); - return result; - } - function overArg(func, transform) { - return function(arg) { - return func(transform(arg)); - }; - } - function setToArray2(set2) { - var index2 = -1, result = Array(set2.size); - set2.forEach(function(value) { - result[++index2] = value; - }); - return result; - } - var arrayProto2 = Array.prototype, funcProto2 = Function.prototype, objectProto2 = Object.prototype; - var coreJsData2 = root2["__core-js_shared__"]; - var funcToString2 = funcProto2.toString; - var hasOwnProperty2 = objectProto2.hasOwnProperty; - var maskSrcKey2 = function() { - var uid2 = /[^.]+$/.exec(coreJsData2 && coreJsData2.keys && coreJsData2.keys.IE_PROTO || ""); - return uid2 ? "Symbol(src)_1." + uid2 : ""; - }(); - var nativeObjectToString = objectProto2.toString; - var reIsNative2 = RegExp( - "^" + funcToString2.call(hasOwnProperty2).replace(reRegExpChar2, "\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, "$1.*?") + "$" +function DefaultCollaboratorHint({ + className, + zoom, + point, + color, + viewport, + opacity = 1 +}) { + const rSvg = reactExports.useRef(null); + useTransform( + rSvg, + clamp$3(point.x, viewport.minX + 5 / zoom, viewport.maxX - 5 / zoom), + clamp$3(point.y, viewport.minY + 5 / zoom, viewport.maxY - 5 / zoom), + 1 / zoom, + Vec.Angle(viewport.center, point) ); - var Buffer2 = moduleExports ? root2.Buffer : void 0, Symbol2 = root2.Symbol, Uint8Array2 = root2.Uint8Array, propertyIsEnumerable2 = objectProto2.propertyIsEnumerable, splice2 = arrayProto2.splice, symToStringTag = Symbol2 ? Symbol2.toStringTag : void 0; - var nativeGetSymbols = Object.getOwnPropertySymbols, nativeIsBuffer = Buffer2 ? Buffer2.isBuffer : void 0, nativeKeys = overArg(Object.keys, Object); - var DataView2 = getNative2(root2, "DataView"), Map2 = getNative2(root2, "Map"), Promise2 = getNative2(root2, "Promise"), Set2 = getNative2(root2, "Set"), WeakMap2 = getNative2(root2, "WeakMap"), nativeCreate2 = getNative2(Object, "create"); - var dataViewCtorString = toSource2(DataView2), mapCtorString = toSource2(Map2), promiseCtorString = toSource2(Promise2), setCtorString = toSource2(Set2), weakMapCtorString = toSource2(WeakMap2); - var symbolProto = Symbol2 ? Symbol2.prototype : void 0, symbolValueOf = symbolProto ? symbolProto.valueOf : void 0; - function Hash2(entries) { - var index2 = -1, length = entries == null ? 0 : entries.length; - this.clear(); - while (++index2 < length) { - var entry2 = entries[index2]; - this.set(entry2[0], entry2[1]); - } - } - function hashClear2() { - this.__data__ = nativeCreate2 ? nativeCreate2(null) : {}; - this.size = 0; - } - function hashDelete2(key) { - var result = this.has(key) && delete this.__data__[key]; - this.size -= result ? 1 : 0; - return result; - } - function hashGet2(key) { - var data2 = this.__data__; - if (nativeCreate2) { - var result = data2[key]; - return result === HASH_UNDEFINED2 ? void 0 : result; - } - return hasOwnProperty2.call(data2, key) ? data2[key] : void 0; - } - function hashHas2(key) { - var data2 = this.__data__; - return nativeCreate2 ? data2[key] !== void 0 : hasOwnProperty2.call(data2, key); - } - function hashSet2(key, value) { - var data2 = this.__data__; - this.size += this.has(key) ? 0 : 1; - data2[key] = nativeCreate2 && value === void 0 ? HASH_UNDEFINED2 : value; - return this; - } - Hash2.prototype.clear = hashClear2; - Hash2.prototype["delete"] = hashDelete2; - Hash2.prototype.get = hashGet2; - Hash2.prototype.has = hashHas2; - Hash2.prototype.set = hashSet2; - function ListCache2(entries) { - var index2 = -1, length = entries == null ? 0 : entries.length; - this.clear(); - while (++index2 < length) { - var entry2 = entries[index2]; - this.set(entry2[0], entry2[1]); - } - } - function listCacheClear2() { - this.__data__ = []; - this.size = 0; - } - function listCacheDelete2(key) { - var data2 = this.__data__, index2 = assocIndexOf2(data2, key); - if (index2 < 0) { - return false; - } - var lastIndex = data2.length - 1; - if (index2 == lastIndex) { - data2.pop(); - } else { - splice2.call(data2, index2, 1); - } - --this.size; - return true; - } - function listCacheGet2(key) { - var data2 = this.__data__, index2 = assocIndexOf2(data2, key); - return index2 < 0 ? void 0 : data2[index2][1]; - } - function listCacheHas2(key) { - return assocIndexOf2(this.__data__, key) > -1; - } - function listCacheSet2(key, value) { - var data2 = this.__data__, index2 = assocIndexOf2(data2, key); - if (index2 < 0) { - ++this.size; - data2.push([key, value]); - } else { - data2[index2][1] = value; - } - return this; - } - ListCache2.prototype.clear = listCacheClear2; - ListCache2.prototype["delete"] = listCacheDelete2; - ListCache2.prototype.get = listCacheGet2; - ListCache2.prototype.has = listCacheHas2; - ListCache2.prototype.set = listCacheSet2; - function MapCache2(entries) { - var index2 = -1, length = entries == null ? 0 : entries.length; - this.clear(); - while (++index2 < length) { - var entry2 = entries[index2]; - this.set(entry2[0], entry2[1]); - } - } - function mapCacheClear2() { - this.size = 0; - this.__data__ = { - "hash": new Hash2(), - "map": new (Map2 || ListCache2)(), - "string": new Hash2() - }; - } - function mapCacheDelete2(key) { - var result = getMapData2(this, key)["delete"](key); - this.size -= result ? 1 : 0; - return result; - } - function mapCacheGet2(key) { - return getMapData2(this, key).get(key); - } - function mapCacheHas2(key) { - return getMapData2(this, key).has(key); - } - function mapCacheSet2(key, value) { - var data2 = getMapData2(this, key), size2 = data2.size; - data2.set(key, value); - this.size += data2.size == size2 ? 0 : 1; - return this; - } - MapCache2.prototype.clear = mapCacheClear2; - MapCache2.prototype["delete"] = mapCacheDelete2; - MapCache2.prototype.get = mapCacheGet2; - MapCache2.prototype.has = mapCacheHas2; - MapCache2.prototype.set = mapCacheSet2; - function SetCache2(values) { - var index2 = -1, length = values == null ? 0 : values.length; - this.__data__ = new MapCache2(); - while (++index2 < length) { - this.add(values[index2]); - } - } - function setCacheAdd2(value) { - this.__data__.set(value, HASH_UNDEFINED2); - return this; - } - function setCacheHas2(value) { - return this.__data__.has(value); - } - SetCache2.prototype.add = SetCache2.prototype.push = setCacheAdd2; - SetCache2.prototype.has = setCacheHas2; - function Stack(entries) { - var data2 = this.__data__ = new ListCache2(entries); - this.size = data2.size; - } - function stackClear() { - this.__data__ = new ListCache2(); - this.size = 0; - } - function stackDelete(key) { - var data2 = this.__data__, result = data2["delete"](key); - this.size = data2.size; - return result; - } - function stackGet(key) { - return this.__data__.get(key); - } - function stackHas(key) { - return this.__data__.has(key); - } - function stackSet(key, value) { - var data2 = this.__data__; - if (data2 instanceof ListCache2) { - var pairs = data2.__data__; - if (!Map2 || pairs.length < LARGE_ARRAY_SIZE2 - 1) { - pairs.push([key, value]); - this.size = ++data2.size; - return this; - } - data2 = this.__data__ = new MapCache2(pairs); - } - data2.set(key, value); - this.size = data2.size; - return this; - } - Stack.prototype.clear = stackClear; - Stack.prototype["delete"] = stackDelete; - Stack.prototype.get = stackGet; - Stack.prototype.has = stackHas; - Stack.prototype.set = stackSet; - function arrayLikeKeys(value, inherited) { - var isArr = isArray3(value), isArg = !isArr && isArguments(value), isBuff = !isArr && !isArg && isBuffer(value), isType = !isArr && !isArg && !isBuff && isTypedArray(value), skipIndexes = isArr || isArg || isBuff || isType, result = skipIndexes ? baseTimes(value.length, String) : [], length = result.length; - for (var key in value) { - if (hasOwnProperty2.call(value, key) && !(skipIndexes && // Safari 9 has enumerable `arguments.length` in strict mode. - (key == "length" || // Node.js 0.10 has enumerable non-index properties on buffers. - isBuff && (key == "offset" || key == "parent") || // PhantomJS 2 has enumerable non-index properties on typed arrays. - isType && (key == "buffer" || key == "byteLength" || key == "byteOffset") || // Skip index properties. - isIndex(key, length)))) { - result.push(key); - } - } - return result; - } - function assocIndexOf2(array2, key) { - var length = array2.length; - while (length--) { - if (eq2(array2[length][0], key)) { - return length; + const cursorHintId = useSharedSafeId("cursor_hint"); + return /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { ref: rSvg, className: classNames("tl-overlays__item", className), children: [ + /* @__PURE__ */ jsxRuntimeExports.jsx( + "use", + { + href: `#${cursorHintId}`, + color, + strokeWidth: 3, + stroke: "var(--color-background)" } - } - return -1; - } - function baseGetAllKeys(object2, keysFunc, symbolsFunc) { - var result = keysFunc(object2); - return isArray3(object2) ? result : arrayPush(result, symbolsFunc(object2)); - } - function baseGetTag(value) { - if (value == null) { - return value === void 0 ? undefinedTag : nullTag; - } - return symToStringTag && symToStringTag in Object(value) ? getRawTag(value) : objectToString2(value); - } - function baseIsArguments(value) { - return isObjectLike2(value) && baseGetTag(value) == argsTag; - } - function baseIsEqual(value, other, bitmask, customizer, stack2) { - if (value === other) { - return true; - } - if (value == null || other == null || !isObjectLike2(value) && !isObjectLike2(other)) { - return value !== value && other !== other; - } - return baseIsEqualDeep(value, other, bitmask, customizer, baseIsEqual, stack2); + ), + /* @__PURE__ */ jsxRuntimeExports.jsx("use", { href: `#${cursorHintId}`, color, opacity }) + ] }); +} +const DefaultCursor = reactExports.memo(function DefaultCursor2({ + className, + zoom, + point, + color, + name, + chatMessage +}) { + const rCursor = reactExports.useRef(null); + useTransform(rCursor, point == null ? void 0 : point.x, point == null ? void 0 : point.y, 1 / zoom); + const cursorId = useSharedSafeId("cursor"); + if (!point) return null; + return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { ref: rCursor, className: classNames("tl-overlays__item", className), children: [ + /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { className: "tl-cursor", children: /* @__PURE__ */ jsxRuntimeExports.jsx("use", { href: `#${cursorId}`, color }) }), + chatMessage ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ + name && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "tl-nametag-title", style: { color }, children: name }), + /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "tl-nametag-chat", style: { backgroundColor: color }, children: chatMessage }) + ] }) : name && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "tl-nametag", style: { backgroundColor: color }, children: name }) + ] }); +}); +function DefaultGrid({ x: x2, y: y2, z, size: size2 }) { + const id2 = useUniqueSafeId("grid"); + const editor = useEditor(); + const { gridSteps } = editor.options; + return /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { className: "tl-grid", version: "1.1", xmlns: "http://www.w3.org/2000/svg", children: [ + /* @__PURE__ */ jsxRuntimeExports.jsx("defs", { children: gridSteps.map(({ min: min2, mid, step }, i2) => { + const s2 = step * size2 * z; + const xo = 0.5 + x2 * z; + const yo = 0.5 + y2 * z; + const gxo = xo > 0 ? xo % s2 : s2 + xo % s2; + const gyo = yo > 0 ? yo % s2 : s2 + yo % s2; + const opacity = z < mid ? modulate(z, [min2, mid], [0, 1]) : 1; + return /* @__PURE__ */ jsxRuntimeExports.jsx( + "pattern", + { + id: suffixSafeId(id2, `${step}`), + width: s2, + height: s2, + patternUnits: "userSpaceOnUse", + children: /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { className: "tl-grid-dot", cx: gxo, cy: gyo, r: 1, opacity }) + }, + i2 + ); + }) }), + gridSteps.map(({ step }, i2) => /* @__PURE__ */ jsxRuntimeExports.jsx("rect", { width: "100%", height: "100%", fill: `url(#${id2}_${step})` }, i2)) + ] }); +} +function DefaultHandle({ handle, isCoarse, className, zoom }) { + const editor = useEditor(); + const br = (isCoarse ? editor.options.coarseHandleRadius : editor.options.handleRadius) / zoom; + if (handle.type === "clone") { + const fr2 = 3 / zoom; + const path = `M0,${-fr2} A${fr2},${fr2} 0 0,1 0,${fr2}`; + const index2 = SIDES.indexOf(handle.id); + return /* @__PURE__ */ jsxRuntimeExports.jsxs("g", { className: classNames(`tl-handle tl-handle__${handle.type}`, className), children: [ + /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { className: "tl-handle__bg", r: br }), + /* @__PURE__ */ jsxRuntimeExports.jsx("path", { className: "tl-handle__fg", d: path, transform: `rotate(${-90 + 90 * index2})` }) + ] }); } - function baseIsEqualDeep(object2, other, bitmask, customizer, equalFunc, stack2) { - var objIsArr = isArray3(object2), othIsArr = isArray3(other), objTag = objIsArr ? arrayTag : getTag(object2), othTag = othIsArr ? arrayTag : getTag(other); - objTag = objTag == argsTag ? objectTag : objTag; - othTag = othTag == argsTag ? objectTag : othTag; - var objIsObj = objTag == objectTag, othIsObj = othTag == objectTag, isSameTag = objTag == othTag; - if (isSameTag && isBuffer(object2)) { - if (!isBuffer(other)) { - return false; - } - objIsArr = true; - objIsObj = false; - } - if (isSameTag && !objIsObj) { - stack2 || (stack2 = new Stack()); - return objIsArr || isTypedArray(object2) ? equalArrays(object2, other, bitmask, customizer, equalFunc, stack2) : equalByTag(object2, other, objTag, bitmask, customizer, equalFunc, stack2); - } - if (!(bitmask & COMPARE_PARTIAL_FLAG)) { - var objIsWrapped = objIsObj && hasOwnProperty2.call(object2, "__wrapped__"), othIsWrapped = othIsObj && hasOwnProperty2.call(other, "__wrapped__"); - if (objIsWrapped || othIsWrapped) { - var objUnwrapped = objIsWrapped ? object2.value() : object2, othUnwrapped = othIsWrapped ? other.value() : other; - stack2 || (stack2 = new Stack()); - return equalFunc(objUnwrapped, othUnwrapped, bitmask, customizer, stack2); - } - } - if (!isSameTag) { - return false; - } - stack2 || (stack2 = new Stack()); - return equalObjects(object2, other, bitmask, customizer, equalFunc, stack2); + const fr = (handle.type === "create" && isCoarse ? 3 : 4) / Math.max(zoom, 0.25); + return /* @__PURE__ */ jsxRuntimeExports.jsxs("g", { className: classNames(`tl-handle tl-handle__${handle.type}`, className), children: [ + /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { className: "tl-handle__bg", r: br }), + /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { className: "tl-handle__fg", r: fr }) + ] }); +} +const DefaultHandles = ({ children }) => { + return /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { className: "tl-user-handles tl-overlays__item", children }); +}; +const DefaultLoadingScreen = () => { + const { Spinner: Spinner2 } = useEditorComponents(); + return /* @__PURE__ */ jsxRuntimeExports.jsx(LoadingScreen, { children: Spinner2 ? /* @__PURE__ */ jsxRuntimeExports.jsx(Spinner2, {}) : null }); +}; +function getSvgPathFromPoints(points, closed = true) { + const len = points.length; + if (len < 2) { + return ""; } - function baseIsNative2(value) { - if (!isObject2(value) || isMasked2(value)) { - return false; - } - var pattern = isFunction2(value) ? reIsNative2 : reIsHostCtor2; - return pattern.test(toSource2(value)); + let a2 = points[0]; + let b2 = points[1]; + if (len === 2) { + return `M${precise(a2)}L${precise(b2)}`; } - function baseIsTypedArray(value) { - return isObjectLike2(value) && isLength(value.length) && !!typedArrayTags[baseGetTag(value)]; + let result = ""; + for (let i2 = 2, max2 = len - 1; i2 < max2; i2++) { + a2 = points[i2]; + b2 = points[i2 + 1]; + result += average(a2, b2); } - function baseKeys(object2) { - if (!isPrototype(object2)) { - return nativeKeys(object2); - } - var result = []; - for (var key in Object(object2)) { - if (hasOwnProperty2.call(object2, key) && key != "constructor") { - result.push(key); - } - } - return result; + if (closed) { + return `M${average(points[0], points[1])}Q${precise(points[1])}${average( + points[1], + points[2] + )}T${result}${average(points[len - 1], points[0])}${average(points[0], points[1])}Z`; + } else { + return `M${precise(points[0])}Q${precise(points[1])}${average(points[1], points[2])}${points.length > 3 ? "T" : ""}${result}L${precise(points[len - 1])}`; } - function equalArrays(array2, other, bitmask, customizer, equalFunc, stack2) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG, arrLength = array2.length, othLength = other.length; - if (arrLength != othLength && !(isPartial && othLength > arrLength)) { - return false; +} +function DefaultScribble({ scribble, zoom, color, opacity, className }) { + if (!scribble.points.length) return null; + return /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { className: className ? classNames("tl-overlays__item", className) : className, children: /* @__PURE__ */ jsxRuntimeExports.jsx( + "path", + { + className: "tl-scribble", + d: getSvgPathFromPoints(scribble.points, false), + stroke: color ?? `var(--color-${scribble.color})`, + fill: "none", + strokeWidth: 8 / zoom, + opacity: opacity ?? scribble.opacity } - var stacked = stack2.get(array2); - if (stacked && stack2.get(other)) { - return stacked == other; + ) }); +} +function DefaultSelectionBackground({ bounds, rotation }) { + const rDiv = reactExports.useRef(null); + useTransform(rDiv, bounds.x, bounds.y, 1, rotation); + reactExports.useLayoutEffect(() => { + const div = rDiv.current; + if (!div) return; + div.style.width = toDomPrecision(Math.max(1, bounds.width)) + "px"; + div.style.height = toDomPrecision(Math.max(1, bounds.height)) + "px"; + }, [bounds.width, bounds.height]); + return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref: rDiv, className: "tl-selection__bg", draggable: false }); +} +function DefaultSelectionForeground({ bounds, rotation }) { + const editor = useEditor(); + const rSvg = reactExports.useRef(null); + const onlyShape = useValue("only selected shape", () => editor.getOnlySelectedShape(), [editor]); + const expandOutlineBy = onlyShape ? editor.getShapeUtil(onlyShape).expandSelectionOutlinePx(onlyShape) : 0; + useTransform(rSvg, bounds == null ? void 0 : bounds.x, bounds == null ? void 0 : bounds.y, 1, rotation, { + x: -expandOutlineBy, + y: -expandOutlineBy + }); + bounds = bounds.clone().expandBy(expandOutlineBy).zeroFix(); + return /* @__PURE__ */ jsxRuntimeExports.jsx( + "svg", + { + ref: rSvg, + className: "tl-overlays__item tl-selection__fg", + "data-testid": "selection-foreground", + children: /* @__PURE__ */ jsxRuntimeExports.jsx( + "rect", + { + className: classNames("tl-selection__fg__outline"), + width: toDomPrecision(bounds.width), + height: toDomPrecision(bounds.height) + } + ) } - var index2 = -1, result = true, seen = bitmask & COMPARE_UNORDERED_FLAG ? new SetCache2() : void 0; - stack2.set(array2, other); - stack2.set(other, array2); - while (++index2 < arrLength) { - var arrValue = array2[index2], othValue = other[index2]; - if (customizer) { - var compared = isPartial ? customizer(othValue, arrValue, index2, other, array2, stack2) : customizer(arrValue, othValue, index2, array2, other, stack2); - } - if (compared !== void 0) { - if (compared) { - continue; + ); +} +const DefaultShapeErrorFallback = () => { + return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "tl-shape-error-boundary" }); +}; +const EvenInnererIndicator = ({ shape, util }) => { + return useStateTracking( + "Indicator: " + shape.type, + () => ( + // always fetch the latest shape from the store even if the props/meta have not changed, to avoid + // calling the render method with stale data. + util.indicator(util.editor.store.unsafeGetWithoutCapture(shape.id)) + ) + ); +}; +const InnerIndicator = ({ editor, id: id2 }) => { + const shape = useValue("shape for indicator", () => editor.store.get(id2), [editor, id2]); + const { ShapeIndicatorErrorFallback } = useEditorComponents(); + if (!shape || shape.isLocked) return null; + return /* @__PURE__ */ jsxRuntimeExports.jsx( + OptionalErrorBoundary, + { + fallback: ShapeIndicatorErrorFallback, + onError: (error) => editor.annotateError(error, { origin: "react.shapeIndicator", willCrashApp: false }), + children: /* @__PURE__ */ jsxRuntimeExports.jsx(EvenInnererIndicator, { shape, util: editor.getShapeUtil(shape) }, shape.id) + } + ); +}; +const DefaultShapeIndicator = reactExports.memo(function DefaultShapeIndicator2({ + shapeId, + className, + color, + hidden, + opacity +}) { + const editor = useEditor(); + const rIndicator = reactExports.useRef(null); + useQuickReactor( + "indicator transform", + () => { + const elm = rIndicator.current; + if (!elm) return; + const pageTransform = editor.getShapePageTransform(shapeId); + if (!pageTransform) return; + elm.style.setProperty("transform", pageTransform.toCssString()); + }, + [editor, shapeId] + ); + reactExports.useLayoutEffect(() => { + const elm = rIndicator.current; + if (!elm) return; + elm.style.setProperty("display", hidden ? "none" : "block"); + }, [hidden]); + return /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { ref: rIndicator, className: classNames("tl-overlays__item", className), children: /* @__PURE__ */ jsxRuntimeExports.jsx("g", { className: "tl-shape-indicator", stroke: color ?? "var(--color-selected)", opacity, children: /* @__PURE__ */ jsxRuntimeExports.jsx(InnerIndicator, { editor, id: shapeId }) }) }); +}); +const DefaultShapeIndicatorErrorFallback = () => { + return /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: 4, cy: 4, r: 8, strokeWidth: "1", stroke: "red" }); +}; +const DefaultShapeIndicators = reactExports.memo(function DefaultShapeIndicators2() { + const editor = useEditor(); + const rPreviousSelectedShapeIds = reactExports.useRef(/* @__PURE__ */ new Set()); + const idsToDisplay = useValue( + "should display selected ids", + () => { + const prev = rPreviousSelectedShapeIds.current; + const next = /* @__PURE__ */ new Set(); + if ( + // We only show indicators when in the following states... + editor.isInAny( + "select.idle", + "select.brushing", + "select.scribble_brushing", + "select.editing_shape", + "select.pointing_shape", + "select.pointing_selection", + "select.pointing_handle" + ) && // ...but we hide indicators when we've just changed a style (so that the user can see the change) + !editor.getInstanceState().isChangingStyle + ) { + const selected = editor.getSelectedShapeIds(); + for (const id2 of selected) { + next.add(id2); } - result = false; - break; - } - if (seen) { - if (!arraySome(other, function(othValue2, othIndex) { - if (!cacheHas2(seen, othIndex) && (arrValue === othValue2 || equalFunc(arrValue, othValue2, bitmask, customizer, stack2))) { - return seen.push(othIndex); + if (editor.isInAny("select.idle", "select.editing_shape")) { + const instanceState = editor.getInstanceState(); + if (instanceState.isHoveringCanvas && !instanceState.isCoarsePointer) { + const hovered = editor.getHoveredShapeId(); + if (hovered) next.add(hovered); } - })) { - result = false; - break; } - } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, bitmask, customizer, stack2))) { - result = false; - break; } - } - stack2["delete"](array2); - stack2["delete"](other); - return result; - } - function equalByTag(object2, other, tag, bitmask, customizer, equalFunc, stack2) { - switch (tag) { - case dataViewTag: - if (object2.byteLength != other.byteLength || object2.byteOffset != other.byteOffset) { - return false; - } - object2 = object2.buffer; - other = other.buffer; - case arrayBufferTag: - if (object2.byteLength != other.byteLength || !equalFunc(new Uint8Array2(object2), new Uint8Array2(other))) { - return false; - } - return true; - case boolTag: - case dateTag: - case numberTag: - return eq2(+object2, +other); - case errorTag: - return object2.name == other.name && object2.message == other.message; - case regexpTag: - case stringTag: - return object2 == other + ""; - case mapTag: - var convert = mapToArray; - case setTag: - var isPartial = bitmask & COMPARE_PARTIAL_FLAG; - convert || (convert = setToArray2); - if (object2.size != other.size && !isPartial) { - return false; - } - var stacked = stack2.get(object2); - if (stacked) { - return stacked == other; - } - bitmask |= COMPARE_UNORDERED_FLAG; - stack2.set(object2, other); - var result = equalArrays(convert(object2), convert(other), bitmask, customizer, equalFunc, stack2); - stack2["delete"](object2); - return result; - case symbolTag2: - if (symbolValueOf) { - return symbolValueOf.call(object2) == symbolValueOf.call(other); - } - } - return false; - } - function equalObjects(object2, other, bitmask, customizer, equalFunc, stack2) { - var isPartial = bitmask & COMPARE_PARTIAL_FLAG, objProps = getAllKeys(object2), objLength = objProps.length, othProps = getAllKeys(other), othLength = othProps.length; - if (objLength != othLength && !isPartial) { - return false; - } - var index2 = objLength; - while (index2--) { - var key = objProps[index2]; - if (!(isPartial ? key in other : hasOwnProperty2.call(other, key))) { - return false; + if (prev.size !== next.size) { + rPreviousSelectedShapeIds.current = next; + return next; } - } - var stacked = stack2.get(object2); - if (stacked && stack2.get(other)) { - return stacked == other; - } - var result = true; - stack2.set(object2, other); - stack2.set(other, object2); - var skipCtor = isPartial; - while (++index2 < objLength) { - key = objProps[index2]; - var objValue = object2[key], othValue = other[key]; - if (customizer) { - var compared = isPartial ? customizer(othValue, objValue, key, other, object2, stack2) : customizer(objValue, othValue, key, object2, other, stack2); + for (const id2 of next) { + if (!prev.has(id2)) { + rPreviousSelectedShapeIds.current = next; + return next; + } } - if (!(compared === void 0 ? objValue === othValue || equalFunc(objValue, othValue, bitmask, customizer, stack2) : compared)) { - result = false; - break; + return prev; + }, + [editor] + ); + const renderingShapes = useValue("rendering shapes", () => editor.getRenderingShapes(), [editor]); + const { ShapeIndicator } = useEditorComponents(); + if (!ShapeIndicator) return null; + return renderingShapes.map(({ id: id2 }) => /* @__PURE__ */ jsxRuntimeExports.jsx(ShapeIndicator, { shapeId: id2, hidden: !idsToDisplay.has(id2) }, id2 + "_indicator")); +}); +function PointsSnapIndicator({ points, zoom }) { + const l2 = 2.5 / zoom; + const minX = points.reduce((acc, p2) => Math.min(acc, p2.x), Infinity); + const maxX = points.reduce((acc, p2) => Math.max(acc, p2.x), -Infinity); + const minY = points.reduce((acc, p2) => Math.min(acc, p2.y), Infinity); + const maxY = points.reduce((acc, p2) => Math.max(acc, p2.y), -Infinity); + const useNWtoSEdireciton = points.some((p2) => p2.x === minX && p2.y === minY); + let firstX, firstY, secondX, secondY; + if (useNWtoSEdireciton) { + firstX = minX; + firstY = minY; + secondX = maxX; + secondY = maxY; + } else { + firstX = minX; + firstY = maxY; + secondX = maxX; + secondY = minY; + } + return /* @__PURE__ */ jsxRuntimeExports.jsxs("g", { className: "tl-snap-indicator", stroke: "lime", children: [ + /* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: firstX, y1: firstY, x2: secondX, y2: secondY }), + points.map((p2, i2) => /* @__PURE__ */ jsxRuntimeExports.jsx("g", { transform: `translate(${p2.x},${p2.y})`, children: /* @__PURE__ */ jsxRuntimeExports.jsx( + "path", + { + className: "tl-snap-point", + d: `M ${-l2},${-l2} L ${l2},${l2} M ${-l2},${l2} L ${l2},${-l2}` } - skipCtor || (skipCtor = key == "constructor"); + ) }, i2)) + ] }); +} +function GapsSnapIndicator({ gaps, direction, zoom }) { + const l2 = 3.5 / zoom; + let edgeIntersection = [-Infinity, Infinity]; + let nextEdgeIntersection = null; + const horizontal = direction === "horizontal"; + for (const gap of gaps) { + nextEdgeIntersection = rangeIntersection( + edgeIntersection[0], + edgeIntersection[1], + horizontal ? gap.startEdge[0].y : gap.startEdge[0].x, + horizontal ? gap.startEdge[1].y : gap.startEdge[1].x + ); + if (nextEdgeIntersection) { + edgeIntersection = nextEdgeIntersection; + } else { + continue; } - if (result && !skipCtor) { - var objCtor = object2.constructor, othCtor = other.constructor; - if (objCtor != othCtor && ("constructor" in object2 && "constructor" in other) && !(typeof objCtor == "function" && objCtor instanceof objCtor && typeof othCtor == "function" && othCtor instanceof othCtor)) { - result = false; - } + nextEdgeIntersection = rangeIntersection( + edgeIntersection[0], + edgeIntersection[1], + horizontal ? gap.endEdge[0].y : gap.endEdge[0].x, + horizontal ? gap.endEdge[1].y : gap.endEdge[1].x + ); + if (nextEdgeIntersection) { + edgeIntersection = nextEdgeIntersection; + } else { + continue; } - stack2["delete"](object2); - stack2["delete"](other); - return result; - } - function getAllKeys(object2) { - return baseGetAllKeys(object2, keys3, getSymbols); - } - function getMapData2(map, key) { - var data2 = map.__data__; - return isKeyable2(key) ? data2[typeof key == "string" ? "string" : "hash"] : data2.map; - } - function getNative2(object2, key) { - var value = getValue2(object2, key); - return baseIsNative2(value) ? value : void 0; } - function getRawTag(value) { - var isOwn = hasOwnProperty2.call(value, symToStringTag), tag = value[symToStringTag]; - try { - value[symToStringTag] = void 0; - var unmasked = true; - } catch (e2) { - } - var result = nativeObjectToString.call(value); - if (unmasked) { - if (isOwn) { - value[symToStringTag] = tag; - } else { - delete value[symToStringTag]; - } - } - return result; + if (edgeIntersection === null) { + return null; } - var getSymbols = !nativeGetSymbols ? stubArray : function(object2) { - if (object2 == null) { - return []; - } - object2 = Object(object2); - return arrayFilter(nativeGetSymbols(object2), function(symbol) { - return propertyIsEnumerable2.call(object2, symbol); - }); - }; - var getTag = baseGetTag; - if (DataView2 && getTag(new DataView2(new ArrayBuffer(1))) != dataViewTag || Map2 && getTag(new Map2()) != mapTag || Promise2 && getTag(Promise2.resolve()) != promiseTag || Set2 && getTag(new Set2()) != setTag || WeakMap2 && getTag(new WeakMap2()) != weakMapTag) { - getTag = function(value) { - var result = baseGetTag(value), Ctor = result == objectTag ? value.constructor : void 0, ctorString = Ctor ? toSource2(Ctor) : ""; - if (ctorString) { - switch (ctorString) { - case dataViewCtorString: - return dataViewTag; - case mapCtorString: - return mapTag; - case promiseCtorString: - return promiseTag; - case setCtorString: - return setTag; - case weakMapCtorString: - return weakMapTag; + const midPoint2 = (edgeIntersection[0] + edgeIntersection[1]) / 2; + return /* @__PURE__ */ jsxRuntimeExports.jsx("g", { className: "tl-snap-indicator", stroke: "cyan", children: gaps.map(({ startEdge, endEdge }, i2) => /* @__PURE__ */ jsxRuntimeExports.jsx(reactExports.Fragment, { children: horizontal ? ( + // horizontal gap + /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ + /* @__PURE__ */ jsxRuntimeExports.jsx( + "line", + { + x1: startEdge[0].x, + y1: midPoint2 - 2 * l2, + x2: startEdge[1].x, + y2: midPoint2 + 2 * l2 + } + ), + /* @__PURE__ */ jsxRuntimeExports.jsx( + "line", + { + x1: endEdge[0].x, + y1: midPoint2 - 2 * l2, + x2: endEdge[1].x, + y2: midPoint2 + 2 * l2 + } + ), + /* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: startEdge[0].x, y1: midPoint2, x2: endEdge[0].x, y2: midPoint2 }), + /* @__PURE__ */ jsxRuntimeExports.jsx( + "line", + { + x1: (startEdge[0].x + endEdge[0].x) / 2, + y1: midPoint2 - l2, + x2: (startEdge[0].x + endEdge[0].x) / 2, + y2: midPoint2 + l2 + } + ) + ] }) + ) : ( + // vertical gap + /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ + /* @__PURE__ */ jsxRuntimeExports.jsx( + "line", + { + x1: midPoint2 - 2 * l2, + y1: startEdge[0].y, + x2: midPoint2 + 2 * l2, + y2: startEdge[1].y + } + ), + /* @__PURE__ */ jsxRuntimeExports.jsx( + "line", + { + x1: midPoint2 - 2 * l2, + y1: endEdge[0].y, + x2: midPoint2 + 2 * l2, + y2: endEdge[1].y + } + ), + /* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: midPoint2, y1: startEdge[0].y, x2: midPoint2, y2: endEdge[0].y }), + /* @__PURE__ */ jsxRuntimeExports.jsx( + "line", + { + x1: midPoint2 - l2, + y1: (startEdge[0].y + endEdge[0].y) / 2, + x2: midPoint2 + l2, + y2: (startEdge[0].y + endEdge[0].y) / 2 } + ) + ] }) + ) }, i2)) }); +} +function DefaultSnapIndicator({ className, line, zoom }) { + return /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { className: classNames("tl-overlays__item", className), children: line.type === "points" ? /* @__PURE__ */ jsxRuntimeExports.jsx(PointsSnapIndicator, { ...line, zoom }) : line.type === "gaps" ? /* @__PURE__ */ jsxRuntimeExports.jsx(GapsSnapIndicator, { ...line, zoom }) : null }); +} +function DefaultSpinner() { + return /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { width: 16, height: 16, viewBox: "0 0 16 16", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("g", { strokeWidth: 2, fill: "none", fillRule: "evenodd", children: [ + /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { strokeOpacity: 0.25, cx: 8, cy: 8, r: 7, stroke: "currentColor" }), + /* @__PURE__ */ jsxRuntimeExports.jsx("path", { strokeLinecap: "round", d: "M15 8c0-4.5-4.5-7-7-7", stroke: "currentColor", children: /* @__PURE__ */ jsxRuntimeExports.jsx( + "animateTransform", + { + attributeName: "transform", + type: "rotate", + from: "0 8 8", + to: "360 8 8", + dur: "1s", + repeatCount: "indefinite" } - return result; - }; + ) }) + ] }) }); +} +const DefaultSvgDefs = () => { + return null; +}; +function useIdentity(value, isEqual2) { + const ref = reactExports.useRef(value); + if (isEqual2(value, ref.current)) { + return ref.current; } - function isIndex(value, length) { - length = length == null ? MAX_SAFE_INTEGER2 : length; - return !!length && (typeof value == "number" || reIsUint.test(value)) && (value > -1 && value % 1 == 0 && value < length); + ref.current = value; + return value; +} +const areNullableArraysShallowEqual = (a2, b2) => { + a2 ?? (a2 = null); + b2 ?? (b2 = null); + if (a2 === b2) { + return true; } - function isKeyable2(value) { - var type = typeof value; - return type == "string" || type == "number" || type == "symbol" || type == "boolean" ? value !== "__proto__" : value === null; + if (!a2 || !b2) { + return false; } - function isMasked2(func) { - return !!maskSrcKey2 && maskSrcKey2 in func; + return areArraysShallowEqual(a2, b2); +}; +function useShallowArrayIdentity(arr) { + return useIdentity(arr, areNullableArraysShallowEqual); +} +const areNullableObjectsShallowEqual = (a2, b2) => { + a2 ?? (a2 = null); + b2 ?? (b2 = null); + if (a2 === b2) { + return true; } - function isPrototype(value) { - var Ctor = value && value.constructor, proto = typeof Ctor == "function" && Ctor.prototype || objectProto2; - return value === proto; + if (!a2 || !b2) { + return false; } - function objectToString2(value) { - return nativeObjectToString.call(value); + return areObjectsShallowEqual(a2, b2); +}; +function useShallowObjectIdentity(obj) { + return useIdentity(obj, areNullableObjectsShallowEqual); +} +const EditorComponentsContext = reactExports.createContext(null); +function EditorComponentsProvider({ + overrides = {}, + children +}) { + const _overrides = useShallowObjectIdentity(overrides); + const value = reactExports.useMemo( + () => ({ + Background: DefaultBackground, + SvgDefs: DefaultSvgDefs, + Brush: DefaultBrush, + ZoomBrush: DefaultBrush, + CollaboratorBrush: DefaultBrush, + Cursor: DefaultCursor, + CollaboratorCursor: DefaultCursor, + CollaboratorHint: DefaultCollaboratorHint, + CollaboratorShapeIndicator: DefaultShapeIndicator, + Grid: DefaultGrid, + Scribble: DefaultScribble, + SnapIndicator: DefaultSnapIndicator, + Handles: DefaultHandles, + Handle: DefaultHandle, + CollaboratorScribble: DefaultScribble, + ErrorFallback: DefaultErrorFallback, + ShapeErrorFallback: DefaultShapeErrorFallback, + ShapeIndicatorErrorFallback: DefaultShapeIndicatorErrorFallback, + Spinner: DefaultSpinner, + SelectionBackground: DefaultSelectionBackground, + SelectionForeground: DefaultSelectionForeground, + ShapeIndicators: DefaultShapeIndicators, + ShapeIndicator: DefaultShapeIndicator, + OnTheCanvas: null, + InFrontOfTheCanvas: null, + Canvas: DefaultCanvas, + LoadingScreen: DefaultLoadingScreen, + ..._overrides + }), + [_overrides] + ); + return /* @__PURE__ */ jsxRuntimeExports.jsx(EditorComponentsContext.Provider, { value, children }); +} +function useEditorComponents() { + const components = reactExports.useContext(EditorComponentsContext); + if (!components) { + throw new Error("useEditorComponents must be used inside of "); } - function toSource2(func) { - if (func != null) { + return components; +} +const runtime = { + openWindow(url, target) { + window.open(url, target, "noopener noreferrer"); + }, + refreshPage() { + window.location.reload(); + }, + async hardReset() { + var _a3; + return await ((_a3 = window.__tldraw__hardReset) == null ? void 0 : _a3.call(window)); + } +}; +function hardResetEditor() { + runtime.hardReset(); +} +function refreshPage() { + runtime.refreshPage(); +} +const BASE_ERROR_URL = "https://github.com/tldraw/tldraw/issues/new"; +const DefaultErrorFallback = ({ error, editor }) => { + const containerRef = reactExports.useRef(null); + const [shouldShowError, setShouldShowError] = reactExports.useState(true); + const [didCopy, setDidCopy] = reactExports.useState(false); + const [shouldShowResetConfirmation, setShouldShowResetConfirmation] = reactExports.useState(false); + let Canvas = null; + try { + const components = useEditorComponents(); + Canvas = components.Canvas ?? null; + } catch { + } + const errorMessage = error instanceof Error ? error.message : String(error); + const errorStack = error instanceof Error ? error.stack : null; + const isDarkModeFromApp = useValue( + "isDarkMode", + () => { try { - return funcToString2.call(func); - } catch (e2) { + if (editor) { + return editor.user.getIsDarkMode(); + } + } catch { } - try { - return func + ""; - } catch (e2) { + return null; + }, + [editor] + ); + const [isDarkMode, setIsDarkMode] = reactExports.useState(null); + reactExports.useLayoutEffect(() => { + var _a3; + if (isDarkModeFromApp !== null) { + setIsDarkMode(isDarkModeFromApp); + } + let parent = (_a3 = containerRef.current) == null ? void 0 : _a3.parentElement; + let foundParentThemeClass = false; + while (parent) { + if (parent.classList.contains("tl-theme__dark") || parent.classList.contains("tl-theme__light")) { + foundParentThemeClass = true; + break; } + parent = parent.parentElement; } - return ""; - } - function eq2(value, other) { - return value === other || value !== value && other !== other; - } - var isArguments = baseIsArguments(/* @__PURE__ */ function() { - return arguments; - }()) ? baseIsArguments : function(value) { - return isObjectLike2(value) && hasOwnProperty2.call(value, "callee") && !propertyIsEnumerable2.call(value, "callee"); + if (foundParentThemeClass) { + setIsDarkMode(null); + return; + } + if (typeof window !== "undefined" && "matchMedia" in window) { + setIsDarkMode(window.matchMedia("(prefers-color-scheme: dark)").matches); + } + }, [isDarkModeFromApp]); + reactExports.useEffect(() => { + if (didCopy) { + const timeout = editor == null ? void 0 : editor.timers.setTimeout(() => { + setDidCopy(false); + }, 2e3); + return () => clearTimeout(timeout); + } + }, [didCopy, editor]); + const copyError = () => { + const textarea = document.createElement("textarea"); + textarea.value = errorStack ?? errorMessage; + document.body.appendChild(textarea); + textarea.select(); + document.execCommand("copy"); + textarea.remove(); + setDidCopy(true); }; - var isArray3 = Array.isArray; - function isArrayLike(value) { - return value != null && isLength(value.length) && !isFunction2(value); - } - var isBuffer = nativeIsBuffer || stubFalse; - function isEqual2(value, other) { - return baseIsEqual(value, other); - } - function isFunction2(value) { - if (!isObject2(value)) { - return false; + const refresh = () => { + refreshPage(); + }; + const resetLocalState = async () => { + hardResetEditor(); + }; + const url = new URL(BASE_ERROR_URL); + url.searchParams.set("title", errorMessage); + url.searchParams.set("labels", `bug`); + url.searchParams.set( + "body", + `Hey, I ran into an error while using tldraw: + +\`\`\`js +${errorStack ?? errorMessage} +\`\`\` + +My browser: ${navigator.userAgent}` + ); + return /* @__PURE__ */ jsxRuntimeExports.jsxs( + "div", + { + ref: containerRef, + className: classNames( + "tl-container tl-error-boundary", + // error-boundary is sometimes used outside of the theme + // container, so we need to provide it with a theme for our + // styles to work correctly + isDarkMode === null ? "" : isDarkMode ? "tl-theme__dark" : "tl-theme__light" + ), + children: [ + /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "tl-error-boundary__overlay" }), + editor && // opportunistically attempt to render the canvas to reassure + // the user that their document is still there. there's a good + // chance this won't work (ie the error that we're currently + // notifying the user about originates in the canvas) so it's + // not a big deal if it doesn't work - in that case we just have + // a plain grey background. + /* @__PURE__ */ jsxRuntimeExports.jsx(ErrorBoundary, { onError: noop$2, fallback: () => null, children: /* @__PURE__ */ jsxRuntimeExports.jsx(EditorProvider, { editor, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "tl-overlay tl-error-boundary__canvas", children: Canvas ? /* @__PURE__ */ jsxRuntimeExports.jsx(Canvas, {}) : null }) }) }), + /* @__PURE__ */ jsxRuntimeExports.jsx( + "div", + { + className: classNames("tl-modal", "tl-error-boundary__content", { + "tl-error-boundary__content__expanded": shouldShowError && !shouldShowResetConfirmation + }), + children: shouldShowResetConfirmation ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ + /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { children: "Are you sure?" }), + /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: "Resetting your data will delete your drawing and cannot be undone." }), + /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "tl-error-boundary__content__actions", children: [ + /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setShouldShowResetConfirmation(false), children: "Cancel" }), + /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "tl-error-boundary__reset", onClick: resetLocalState, children: "Reset data" }) + ] }) + ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ + /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { children: "Something's gone wrong." }), + /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { children: [ + "Sorry, we encountered an error. Please refresh the page to continue. If you keep seeing this error, you can ", + /* @__PURE__ */ jsxRuntimeExports.jsx("a", { href: url.toString(), children: "create a GitHub issue" }), + " or", + " ", + /* @__PURE__ */ jsxRuntimeExports.jsx("a", { href: "https://discord.gg/Cq6cPsTfNy", children: "ask for help on Discord" }), + "." + ] }), + shouldShowError && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ + "Message:", + /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { children: /* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: errorMessage }) }), + "Stack trace:", + /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "tl-error-boundary__content__error", children: [ + /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { children: /* @__PURE__ */ jsxRuntimeExports.jsx("code", { children: errorStack ?? errorMessage }) }), + /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: copyError, children: didCopy ? "Copied!" : "Copy" }) + ] }) + ] }), + /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "tl-error-boundary__content__actions", children: [ + /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => setShouldShowError(!shouldShowError), children: shouldShowError ? "Hide details" : "Show details" }), + /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "tl-error-boundary__content__actions__group", children: [ + /* @__PURE__ */ jsxRuntimeExports.jsx( + "button", + { + className: "tl-error-boundary__reset", + onClick: () => setShouldShowResetConfirmation(true), + children: "Reset data" + } + ), + /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "tl-error-boundary__refresh", onClick: refresh, children: "Refresh Page" }) + ] }) + ] }) + ] }) + } + ) + ] } - var tag = baseGetTag(value); - return tag == funcTag2 || tag == genTag2 || tag == asyncTag || tag == proxyTag; + ); +}; +const USER_DATA_KEY = "TLDRAW_USER_DATA_v3"; +const userTypeValidator = object({ + id: string, + name: string.nullable().optional(), + color: string.nullable().optional(), + // N.B. These are duplicated in TLdrawAppUser. + locale: string.nullable().optional(), + animationSpeed: number.nullable().optional(), + edgeScrollSpeed: number.nullable().optional(), + colorScheme: literalEnum("light", "dark", "system").optional(), + isSnapMode: boolean.nullable().optional(), + isWrapMode: boolean.nullable().optional(), + isDynamicSizeMode: boolean.nullable().optional(), + isPasteAtCursorMode: boolean.nullable().optional() +}); +const Versions$1 = { + AddAnimationSpeed: 1, + AddIsSnapMode: 2, + MakeFieldsNullable: 3, + AddEdgeScrollSpeed: 4, + AddExcalidrawSelectMode: 5, + AddDynamicSizeMode: 6, + AllowSystemColorScheme: 7, + AddPasteAtCursor: 8 +}; +const CURRENT_VERSION = Math.max(...Object.values(Versions$1)); +function migrateSnapshot(data2) { + if (data2.version < Versions$1.AddAnimationSpeed) { + data2.user.animationSpeed = 1; } - function isLength(value) { - return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER2; + if (data2.version < Versions$1.AddIsSnapMode) { + data2.user.isSnapMode = false; } - function isObject2(value) { - var type = typeof value; - return value != null && (type == "object" || type == "function"); + if (data2.version < Versions$1.MakeFieldsNullable) ; + if (data2.version < Versions$1.AddEdgeScrollSpeed) { + data2.user.edgeScrollSpeed = 1; } - function isObjectLike2(value) { - return value != null && typeof value == "object"; + if (data2.version < Versions$1.AddExcalidrawSelectMode) { + data2.user.isWrapMode = false; } - var isTypedArray = nodeIsTypedArray ? baseUnary(nodeIsTypedArray) : baseIsTypedArray; - function keys3(object2) { - return isArrayLike(object2) ? arrayLikeKeys(object2) : baseKeys(object2); + if (data2.version < Versions$1.AllowSystemColorScheme) { + if (data2.user.isDarkMode === true) { + data2.user.colorScheme = "dark"; + } else if (data2.user.isDarkMode === false) { + data2.user.colorScheme = "light"; + } + delete data2.user.isDarkMode; } - function stubArray() { - return []; + if (data2.version < Versions$1.AddDynamicSizeMode) { + data2.user.isDynamicSizeMode = false; } - function stubFalse() { - return false; + if (data2.version < Versions$1.AddPasteAtCursor) { + data2.user.isPasteAtCursorMode = false; } - module.exports = isEqual2; -})(lodash_isequal, lodash_isequal.exports); -var lodash_isequalExports = lodash_isequal.exports; -const isEqual = /* @__PURE__ */ getDefaultExportFromCjs(lodash_isequalExports); -function intersectSets(sets) { - if (sets.length === 0) return /* @__PURE__ */ new Set(); - const first = sets[0]; - const rest = sets.slice(1); - const result = /* @__PURE__ */ new Set(); - for (const val of first) { - if (rest.every((set2) => set2.has(val))) { - result.add(val); - } + data2.version = CURRENT_VERSION; +} +const USER_COLORS = [ + "#FF802B", + "#EC5E41", + "#F2555A", + "#F04F88", + "#E34BA9", + "#BD54C6", + "#9D5BD2", + "#7B66DC", + "#02B1CC", + "#11B3A3", + "#39B178", + "#55B467" +]; +function getRandomColor() { + return USER_COLORS[Math.floor(Math.random() * USER_COLORS.length)]; +} +function userPrefersReducedMotion() { + var _a3, _b2; + if (typeof window !== "undefined" && "matchMedia" in window) { + return ((_b2 = (_a3 = window.matchMedia) == null ? void 0 : _a3.call(window, "(prefers-reduced-motion: reduce)")) == null ? void 0 : _b2.matches) ?? false; } - return result; + return false; } -function diffSets(prev, next) { - const result = {}; - for (const val of next) { - if (!prev.has(val)) { - result.added ?? (result.added = /* @__PURE__ */ new Set()); - result.added.add(val); - } +const defaultUserPreferences = Object.freeze({ + name: "New User", + locale: getDefaultTranslationLocale(), + color: getRandomColor(), + // N.B. These are duplicated in TLdrawAppUser. + edgeScrollSpeed: 1, + animationSpeed: userPrefersReducedMotion() ? 0 : 1, + isSnapMode: false, + isWrapMode: false, + isDynamicSizeMode: false, + isPasteAtCursorMode: false, + colorScheme: "system" +}); +function getFreshUserPreferences() { + return { + id: uniqueId(), + color: getRandomColor() + }; +} +function migrateUserPreferences(userData) { + if (userData === null || typeof userData !== "object") { + return getFreshUserPreferences(); } - for (const val of prev) { - if (!next.has(val)) { - result.removed ?? (result.removed = /* @__PURE__ */ new Set()); - result.removed.add(val); - } + if (!("version" in userData) || !("user" in userData) || typeof userData.version !== "number") { + return getFreshUserPreferences(); + } + const snapshot = structuredClone(userData); + migrateSnapshot(snapshot); + try { + return userTypeValidator.validate(snapshot.user); + } catch { + return getFreshUserPreferences(); } - return result.added || result.removed ? result : void 0; } -function objectMatchesQuery(query, object2) { - for (const [key, _matcher] of Object.entries(query)) { - const matcher = _matcher; - const value = object2[key]; - if ("eq" in matcher && value !== matcher.eq) return false; - if ("neq" in matcher && value === matcher.neq) return false; - if ("gt" in matcher && (typeof value !== "number" || value <= matcher.gt)) return false; +function loadUserPreferences() { + const userData = JSON.parse(getFromLocalStorage(USER_DATA_KEY) || "null") ?? null; + return migrateUserPreferences(userData); +} +const globalUserPreferences = atom("globalUserData", null); +function storeUserPreferences() { + setInLocalStorage( + USER_DATA_KEY, + JSON.stringify({ + version: CURRENT_VERSION, + user: globalUserPreferences.get() + }) + ); +} +function setUserPreferences(user) { + userTypeValidator.validate(user); + globalUserPreferences.set(user); + storeUserPreferences(); + broadcastUserPreferencesChange(); +} +const isTest = typeof process !== "undefined" && false; +const channel = typeof BroadcastChannel !== "undefined" && !isTest ? new BroadcastChannel("tldraw-user-sync") : null; +channel == null ? void 0 : channel.addEventListener("message", (e2) => { + const data2 = e2.data; + if ((data2 == null ? void 0 : data2.type) === broadcastEventKey && (data2 == null ? void 0 : data2.origin) !== getBroadcastOrigin()) { + globalUserPreferences.set(migrateUserPreferences(data2.data)); + } +}); +let _broadcastOrigin = null; +function getBroadcastOrigin() { + if (_broadcastOrigin === null) { + _broadcastOrigin = uniqueId(); } - return true; + return _broadcastOrigin; } -function executeQuery(store, typeName, query) { - const matchIds = Object.fromEntries(Object.keys(query).map((key) => [key, /* @__PURE__ */ new Set()])); - for (const [k2, matcher] of Object.entries(query)) { - if ("eq" in matcher) { - const index2 = store.index(typeName, k2); - const ids = index2.get().get(matcher.eq); - if (ids) { - for (const id2 of ids) { - matchIds[k2].add(id2); - } - } - } else if ("neq" in matcher) { - const index2 = store.index(typeName, k2); - for (const [value, ids] of index2.get()) { - if (value !== matcher.neq) { - for (const id2 of ids) { - matchIds[k2].add(id2); - } - } - } - } else if ("gt" in matcher) { - const index2 = store.index(typeName, k2); - for (const [value, ids] of index2.get()) { - if (value > matcher.gt) { - for (const id2 of ids) { - matchIds[k2].add(id2); - } - } - } +const broadcastEventKey = "tldraw-user-preferences-change"; +function broadcastUserPreferencesChange() { + channel == null ? void 0 : channel.postMessage({ + type: broadcastEventKey, + origin: getBroadcastOrigin(), + data: { + user: getUserPreferences(), + version: CURRENT_VERSION } + }); +} +function getUserPreferences() { + let prefs = globalUserPreferences.get(); + if (!prefs) { + prefs = loadUserPreferences(); + setUserPreferences(prefs); } - return intersectSets(Object.values(matchIds)); + return prefs; } -class StoreQueries { - constructor(atoms, history) { - /** - * A cache of derivations (indexes). - * - * @internal - */ - __publicField(this, "indexCache", /* @__PURE__ */ new Map()); - /** - * A cache of derivations (filtered histories). - * - * @internal - */ - __publicField(this, "historyCache", /* @__PURE__ */ new Map()); - this.atoms = atoms; - this.history = history; +const defaultLocalStorageUserPrefs = computed( + "defaultLocalStorageUserPrefs", + () => getUserPreferences() +); +function createTLUser(opts = {}) { + return { + userPreferences: opts.userPreferences ?? defaultLocalStorageUserPrefs, + setUserPreferences: opts.setUserPreferences ?? setUserPreferences + }; +} +var eventemitter3 = { exports: {} }; +(function(module) { + var has2 = Object.prototype.hasOwnProperty, prefix = "~"; + function Events() { } - /** - * Create a derivation that contains the history for a given type - * - * @param typeName - The name of the type to filter by. - * @returns A derivation that returns the ids of all records of the given type. - * @public - */ - filterHistory(typeName) { - if (this.historyCache.has(typeName)) { - return this.historyCache.get(typeName); - } - const filtered = computed( - "filterHistory:" + typeName, - (lastValue, lastComputedEpoch) => { - if (isUninitialized(lastValue)) { - return this.history.get(); - } - const diff = this.history.getDiffSince(lastComputedEpoch); - if (diff === RESET_VALUE) return this.history.get(); - const res = { added: {}, removed: {}, updated: {} }; - let numAdded = 0; - let numRemoved = 0; - let numUpdated = 0; - for (const changes of diff) { - for (const added of objectMapValues(changes.added)) { - if (added.typeName === typeName) { - if (res.removed[added.id]) { - const original = res.removed[added.id]; - delete res.removed[added.id]; - numRemoved--; - if (original !== added) { - res.updated[added.id] = [original, added]; - numUpdated++; - } - } else { - res.added[added.id] = added; - numAdded++; - } - } - } - for (const [from, to] of objectMapValues(changes.updated)) { - if (to.typeName === typeName) { - if (res.added[to.id]) { - res.added[to.id] = to; - } else if (res.updated[to.id]) { - res.updated[to.id] = [res.updated[to.id][0], to]; - } else { - res.updated[to.id] = [from, to]; - numUpdated++; - } - } - } - for (const removed of objectMapValues(changes.removed)) { - if (removed.typeName === typeName) { - if (res.added[removed.id]) { - delete res.added[removed.id]; - numAdded--; - } else if (res.updated[removed.id]) { - res.removed[removed.id] = res.updated[removed.id][0]; - delete res.updated[removed.id]; - numUpdated--; - numRemoved++; - } else { - res.removed[removed.id] = removed; - numRemoved++; - } - } - } - } - if (numAdded || numRemoved || numUpdated) { - return withDiff(this.history.get(), res); - } else { - return lastValue; - } - }, - { historyLength: 100 } - ); - this.historyCache.set(typeName, filtered); - return filtered; + if (Object.create) { + Events.prototype = /* @__PURE__ */ Object.create(null); + if (!new Events().__proto__) prefix = false; } - /** - * Create a derivation that returns an index on a property for the given type. - * - * @param typeName - The name of the type. - * @param property - The name of the property. - * @public - */ - index(typeName, property) { - const cacheKey = typeName + ":" + property; - if (this.indexCache.has(cacheKey)) { - return this.indexCache.get(cacheKey); - } - const index2 = this.__uncached_createIndex(typeName, property); - this.indexCache.set(cacheKey, index2); - return index2; + function EE(fn, context, once) { + this.fn = fn; + this.context = context; + this.once = once || false; } - /** - * Create a derivation that returns an index on a property for the given type. - * - * @param typeName - The name of the type?. - * @param property - The name of the property?. - * @internal - */ - __uncached_createIndex(typeName, property) { - const typeHistory = this.filterHistory(typeName); - const fromScratch = () => { - typeHistory.get(); - const res = /* @__PURE__ */ new Map(); - for (const atom2 of objectMapValues(this.atoms.get())) { - const record = atom2.get(); - if (record.typeName === typeName) { - const value = record[property]; - if (!res.has(value)) { - res.set(value, /* @__PURE__ */ new Set()); - } - res.get(value).add(record.id); - } - } - return res; - }; - return computed( - "index:" + typeName + ":" + property, - (prevValue, lastComputedEpoch) => { - if (isUninitialized(prevValue)) return fromScratch(); - const history = typeHistory.getDiffSince(lastComputedEpoch); - if (history === RESET_VALUE) { - return fromScratch(); - } - const setConstructors = /* @__PURE__ */ new Map(); - const add = (value, id2) => { - let setConstructor = setConstructors.get(value); - if (!setConstructor) - setConstructor = new IncrementalSetConstructor( - prevValue.get(value) ?? /* @__PURE__ */ new Set() - ); - setConstructor.add(id2); - setConstructors.set(value, setConstructor); - }; - const remove2 = (value, id2) => { - let set2 = setConstructors.get(value); - if (!set2) set2 = new IncrementalSetConstructor(prevValue.get(value) ?? /* @__PURE__ */ new Set()); - set2.remove(id2); - setConstructors.set(value, set2); - }; - for (const changes of history) { - for (const record of objectMapValues(changes.added)) { - if (record.typeName === typeName) { - const value = record[property]; - add(value, record.id); - } - } - for (const [from, to] of objectMapValues(changes.updated)) { - if (to.typeName === typeName) { - const prev = from[property]; - const next = to[property]; - if (prev !== next) { - remove2(prev, to.id); - add(next, to.id); - } - } - } - for (const record of objectMapValues(changes.removed)) { - if (record.typeName === typeName) { - const value = record[property]; - remove2(value, record.id); - } - } - } - let nextValue = void 0; - let nextDiff = void 0; - for (const [value, setConstructor] of setConstructors) { - const result = setConstructor.get(); - if (!result) continue; - if (!nextValue) nextValue = new Map(prevValue); - if (!nextDiff) nextDiff = /* @__PURE__ */ new Map(); - if (result.value.size === 0) { - nextValue.delete(value); - } else { - nextValue.set(value, result.value); - } - nextDiff.set(value, result.diff); - } - if (nextValue && nextDiff) { - return withDiff(nextValue, nextDiff); - } - return prevValue; - }, - { historyLength: 100 } - ); + function addListener(emitter, event, fn, context, once) { + if (typeof fn !== "function") { + throw new TypeError("The listener must be a function"); + } + var listener = new EE(fn, context || emitter, once), evt = prefix ? prefix + event : event; + if (!emitter._events[evt]) emitter._events[evt] = listener, emitter._eventsCount++; + else if (!emitter._events[evt].fn) emitter._events[evt].push(listener); + else emitter._events[evt] = [emitter._events[evt], listener]; + return emitter; } - /** - * Create a derivation that will return a signle record matching the given query. - * - * It will return undefined if there is no matching record - * - * @param typeName - The name of the type? - * @param queryCreator - A function that returns the query expression. - * @param name - (optinal) The name of the query. - */ - record(typeName, queryCreator = () => ({}), name = "record:" + typeName + (queryCreator ? ":" + queryCreator.toString() : "")) { - const ids = this.ids(typeName, queryCreator, name); - return computed(name, () => { - var _a3; - for (const id2 of ids.get()) { - return (_a3 = this.atoms.get()[id2]) == null ? void 0 : _a3.get(); - } - return void 0; - }); + function clearEvent(emitter, evt) { + if (--emitter._eventsCount === 0) emitter._events = new Events(); + else delete emitter._events[evt]; } - /** - * Create a derivation that will return an array of records matching the given query - * - * @param typeName - The name of the type? - * @param queryCreator - A function that returns the query expression. - * @param name - (optinal) The name of the query. - */ - records(typeName, queryCreator = () => ({}), name = "records:" + typeName + (queryCreator ? ":" + queryCreator.toString() : "")) { - const ids = this.ids(typeName, queryCreator, "ids:" + name); - return computed(name, () => { - return [...ids.get()].map((id2) => { - const atom2 = this.atoms.get()[id2]; - if (!atom2) { - throw new Error("no atom found for record id: " + id2); - } - return atom2.get(); - }); - }); + function EventEmitter2() { + this._events = new Events(); + this._eventsCount = 0; } - /** - * Create a derivation that will return the ids of all records of the given type. - * - * @param typeName - The name of the type. - * @param queryCreator - A function that returns the query expression. - * @param name - (optinal) The name of the query. - */ - ids(typeName, queryCreator = () => ({}), name = "ids:" + typeName + (queryCreator ? ":" + queryCreator.toString() : "")) { - const typeHistory = this.filterHistory(typeName); - const fromScratch = () => { - typeHistory.get(); - const query = queryCreator(); - if (Object.keys(query).length === 0) { - return new Set( - objectMapValues(this.atoms.get()).flatMap((v2) => { - const r2 = v2.get(); - if (r2.typeName === typeName) { - return r2.id; - } else { - return []; - } - }) - ); + EventEmitter2.prototype.eventNames = function eventNames() { + var names = [], events, name; + if (this._eventsCount === 0) return names; + for (name in events = this._events) { + if (has2.call(events, name)) names.push(prefix ? name.slice(1) : name); + } + if (Object.getOwnPropertySymbols) { + return names.concat(Object.getOwnPropertySymbols(events)); + } + return names; + }; + EventEmitter2.prototype.listeners = function listeners(event) { + var evt = prefix ? prefix + event : event, handlers = this._events[evt]; + if (!handlers) return []; + if (handlers.fn) return [handlers.fn]; + for (var i2 = 0, l2 = handlers.length, ee = new Array(l2); i2 < l2; i2++) { + ee[i2] = handlers[i2].fn; + } + return ee; + }; + EventEmitter2.prototype.listenerCount = function listenerCount(event) { + var evt = prefix ? prefix + event : event, listeners = this._events[evt]; + if (!listeners) return 0; + if (listeners.fn) return 1; + return listeners.length; + }; + EventEmitter2.prototype.emit = function emit(event, a1, a2, a3, a4, a5) { + var evt = prefix ? prefix + event : event; + if (!this._events[evt]) return false; + var listeners = this._events[evt], len = arguments.length, args, i2; + if (listeners.fn) { + if (listeners.once) this.removeListener(event, listeners.fn, void 0, true); + switch (len) { + case 1: + return listeners.fn.call(listeners.context), true; + case 2: + return listeners.fn.call(listeners.context, a1), true; + case 3: + return listeners.fn.call(listeners.context, a1, a2), true; + case 4: + return listeners.fn.call(listeners.context, a1, a2, a3), true; + case 5: + return listeners.fn.call(listeners.context, a1, a2, a3, a4), true; + case 6: + return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true; } - return executeQuery(this, typeName, query); - }; - const fromScratchWithDiff = (prevValue) => { - const nextValue = fromScratch(); - const diff = diffSets(prevValue, nextValue); - if (diff) { - return withDiff(nextValue, diff); - } else { - return prevValue; + for (i2 = 1, args = new Array(len - 1); i2 < len; i2++) { + args[i2 - 1] = arguments[i2]; } - }; - const cachedQuery = computed("ids_query:" + name, queryCreator, { - isEqual - }); - return computed( - "query:" + name, - (prevValue, lastComputedEpoch) => { - const query = cachedQuery.get(); - if (isUninitialized(prevValue)) { - return fromScratch(); - } - if (lastComputedEpoch < cachedQuery.lastChangedEpoch) { - return fromScratchWithDiff(prevValue); - } - const history = typeHistory.getDiffSince(lastComputedEpoch); - if (history === RESET_VALUE) { - return fromScratchWithDiff(prevValue); - } - const setConstructor = new IncrementalSetConstructor( - prevValue - ); - for (const changes of history) { - for (const added of objectMapValues(changes.added)) { - if (added.typeName === typeName && objectMatchesQuery(query, added)) { - setConstructor.add(added.id); - } - } - for (const [_2, updated] of objectMapValues(changes.updated)) { - if (updated.typeName === typeName) { - if (objectMatchesQuery(query, updated)) { - setConstructor.add(updated.id); - } else { - setConstructor.remove(updated.id); - } - } - } - for (const removed of objectMapValues(changes.removed)) { - if (removed.typeName === typeName) { - setConstructor.remove(removed.id); + listeners.fn.apply(listeners.context, args); + } else { + var length = listeners.length, j2; + for (i2 = 0; i2 < length; i2++) { + if (listeners[i2].once) this.removeListener(event, listeners[i2].fn, void 0, true); + switch (len) { + case 1: + listeners[i2].fn.call(listeners[i2].context); + break; + case 2: + listeners[i2].fn.call(listeners[i2].context, a1); + break; + case 3: + listeners[i2].fn.call(listeners[i2].context, a1, a2); + break; + case 4: + listeners[i2].fn.call(listeners[i2].context, a1, a2, a3); + break; + default: + if (!args) for (j2 = 1, args = new Array(len - 1); j2 < len; j2++) { + args[j2 - 1] = arguments[j2]; } - } + listeners[i2].fn.apply(listeners[i2].context, args); } - const result = setConstructor.get(); - if (!result) { - return prevValue; + } + } + return true; + }; + EventEmitter2.prototype.on = function on(event, fn, context) { + return addListener(this, event, fn, context, false); + }; + EventEmitter2.prototype.once = function once(event, fn, context) { + return addListener(this, event, fn, context, true); + }; + EventEmitter2.prototype.removeListener = function removeListener(event, fn, context, once) { + var evt = prefix ? prefix + event : event; + if (!this._events[evt]) return this; + if (!fn) { + clearEvent(this, evt); + return this; + } + var listeners = this._events[evt]; + if (listeners.fn) { + if (listeners.fn === fn && (!once || listeners.once) && (!context || listeners.context === context)) { + clearEvent(this, evt); + } + } else { + for (var i2 = 0, events = [], length = listeners.length; i2 < length; i2++) { + if (listeners[i2].fn !== fn || once && !listeners[i2].once || context && listeners[i2].context !== context) { + events.push(listeners[i2]); } - return withDiff(result.value, result.diff); - }, - { historyLength: 50 } - ); - } - exec(typeName, query) { - const ids = executeQuery(this, typeName, query); - if (ids.size === 0) { - return EMPTY_ARRAY; + } + if (events.length) this._events[evt] = events.length === 1 ? events[0] : events; + else clearEvent(this, evt); } - const atoms = this.atoms.get(); - return [...ids].map((id2) => atoms[id2].get()); + return this; + }; + EventEmitter2.prototype.removeAllListeners = function removeAllListeners(event) { + var evt; + if (event) { + evt = prefix ? prefix + event : event; + if (this._events[evt]) clearEvent(this, evt); + } else { + this._events = new Events(); + this._eventsCount = 0; + } + return this; + }; + EventEmitter2.prototype.off = EventEmitter2.prototype.removeListener; + EventEmitter2.prototype.addListener = EventEmitter2.prototype.on; + EventEmitter2.prefixed = prefix; + EventEmitter2.EventEmitter = EventEmitter2; + { + module.exports = EventEmitter2; } +})(eventemitter3); +var eventemitter3Exports = eventemitter3.exports; +const EventEmitter = /* @__PURE__ */ getDefaultExportFromCjs(eventemitter3Exports); +const tabIdKey = "TLDRAW_TAB_ID_v2"; +const window$1 = globalThis.window; +function iOS() { + if (!window$1) return false; + return ["iPad Simulator", "iPhone Simulator", "iPod Simulator", "iPad", "iPhone", "iPod"].includes( + // eslint-disable-next-line @typescript-eslint/no-deprecated + window$1.navigator.platform + ) || // iPad on iOS 13 detection + tlenv.isDarwin && "ontouchend" in document; } -class StoreSideEffects { - constructor(store) { - __publicField(this, "_beforeCreateHandlers", {}); - __publicField(this, "_afterCreateHandlers", {}); - __publicField(this, "_beforeChangeHandlers", {}); - __publicField(this, "_afterChangeHandlers", {}); - __publicField(this, "_beforeDeleteHandlers", {}); - __publicField(this, "_afterDeleteHandlers", {}); - __publicField(this, "_operationCompleteHandlers", []); - __publicField(this, "_isEnabled", true); - this.store = store; +const TAB_ID = window$1 ? window$1[tabIdKey] ?? getFromSessionStorage(tabIdKey) ?? `TLDRAW_INSTANCE_STATE_V1_` + uniqueId() : ""; +if (window$1) { + window$1[tabIdKey] = TAB_ID; + if (iOS()) { + setInSessionStorage(tabIdKey, TAB_ID); + } else { + deleteFromSessionStorage(tabIdKey); } - /** @internal */ - isEnabled() { - return this._isEnabled; +} +window$1 == null ? void 0 : window$1.addEventListener("beforeunload", () => { + setInSessionStorage(tabIdKey, TAB_ID); +}); +const Versions = { + Initial: 0 +}; +const CURRENT_SESSION_STATE_SNAPSHOT_VERSION = Math.max(...Object.values(Versions)); +function migrate(snapshot) { + if (snapshot.version < Versions.Initial) ; + snapshot.version = CURRENT_SESSION_STATE_SNAPSHOT_VERSION; +} +const sessionStateSnapshotValidator = object({ + version: number, + currentPageId: pageIdValidator.optional(), + isFocusMode: boolean.optional(), + exportBackground: boolean.optional(), + isDebugMode: boolean.optional(), + isToolLocked: boolean.optional(), + isGridMode: boolean.optional(), + pageStates: arrayOf( + object({ + pageId: pageIdValidator, + camera: object({ + x: number, + y: number, + z: number + }).optional(), + selectedShapeIds: arrayOf(shapeIdValidator).optional(), + focusedGroupId: shapeIdValidator.nullable().optional() + }) + ).optional() +}); +function migrateAndValidateSessionStateSnapshot(state) { + if (!state || typeof state !== "object") { + console.warn("Invalid instance state"); + return null; } - /** @internal */ - setIsEnabled(enabled) { - this._isEnabled = enabled; + if (!("version" in state) || typeof state.version !== "number") { + console.warn("No version in instance state"); + return null; } - /** @internal */ - handleBeforeCreate(record, source) { - if (!this._isEnabled) return record; - const handlers = this._beforeCreateHandlers[record.typeName]; - if (handlers) { - let r2 = record; - for (const handler of handlers) { - r2 = handler(r2, source); - } - return r2; - } - return record; + if (state.version !== CURRENT_SESSION_STATE_SNAPSHOT_VERSION) { + state = structuredClone(state); + migrate(state); } - /** @internal */ - handleAfterCreate(record, source) { - if (!this._isEnabled) return; - const handlers = this._afterCreateHandlers[record.typeName]; - if (handlers) { - for (const handler of handlers) { - handler(record, source); - } - } + try { + return sessionStateSnapshotValidator.validate(state); + } catch (e2) { + console.warn(e2); + return null; } - /** @internal */ - handleBeforeChange(prev, next, source) { - if (!this._isEnabled) return next; - const handlers = this._beforeChangeHandlers[next.typeName]; - if (handlers) { - let r2 = next; - for (const handler of handlers) { - r2 = handler(prev, r2, source); - } - return r2; +} +function createSessionStateSnapshotSignal(store) { + const $allPageIds = store.query.ids("page"); + return computed( + "sessionStateSnapshot", + () => { + const instanceState = store.get(TLINSTANCE_ID); + if (!instanceState) return null; + const allPageIds = [...$allPageIds.get()]; + return { + version: CURRENT_SESSION_STATE_SNAPSHOT_VERSION, + currentPageId: instanceState.currentPageId, + exportBackground: instanceState.exportBackground, + isFocusMode: instanceState.isFocusMode, + isDebugMode: instanceState.isDebugMode, + isToolLocked: instanceState.isToolLocked, + isGridMode: instanceState.isGridMode, + pageStates: allPageIds.map((id2) => { + const ps = store.get(InstancePageStateRecordType.createId(id2)); + const camera = store.get(CameraRecordType.createId(id2)); + return { + pageId: id2, + camera: { + x: (camera == null ? void 0 : camera.x) ?? 0, + y: (camera == null ? void 0 : camera.y) ?? 0, + z: (camera == null ? void 0 : camera.z) ?? 1 + }, + selectedShapeIds: (ps == null ? void 0 : ps.selectedShapeIds) ?? [], + focusedGroupId: (ps == null ? void 0 : ps.focusedGroupId) ?? null + }; + }) + }; + }, + { isEqual } + ); +} +function loadSessionStateSnapshotIntoStore(store, snapshot, opts) { + const res = migrateAndValidateSessionStateSnapshot(snapshot); + if (!res) return; + const preserved = pluckPreservingValues(store.get(TLINSTANCE_ID)); + const primary = (opts == null ? void 0 : opts.forceOverwrite) ? res : preserved; + const secondary = (opts == null ? void 0 : opts.forceOverwrite) ? preserved : res; + const instanceState = store.schema.types.instance.create({ + id: TLINSTANCE_ID, + ...preserved, + // the integrity checker will ensure that the currentPageId is valid + currentPageId: res.currentPageId, + isDebugMode: (primary == null ? void 0 : primary.isDebugMode) ?? (secondary == null ? void 0 : secondary.isDebugMode), + isFocusMode: (primary == null ? void 0 : primary.isFocusMode) ?? (secondary == null ? void 0 : secondary.isFocusMode), + isToolLocked: (primary == null ? void 0 : primary.isToolLocked) ?? (secondary == null ? void 0 : secondary.isToolLocked), + isGridMode: (primary == null ? void 0 : primary.isGridMode) ?? (secondary == null ? void 0 : secondary.isGridMode), + exportBackground: (primary == null ? void 0 : primary.exportBackground) ?? (secondary == null ? void 0 : secondary.exportBackground) + }); + store.atomic(() => { + var _a3, _b2, _c2; + for (const ps of res.pageStates ?? []) { + if (!store.has(ps.pageId)) continue; + const cameraId = CameraRecordType.createId(ps.pageId); + const instancePageState = InstancePageStateRecordType.createId(ps.pageId); + const previousCamera = store.get(cameraId); + const previousInstanceState = store.get(instancePageState); + store.put([ + CameraRecordType.create({ + id: cameraId, + x: ((_a3 = ps.camera) == null ? void 0 : _a3.x) ?? (previousCamera == null ? void 0 : previousCamera.x), + y: ((_b2 = ps.camera) == null ? void 0 : _b2.y) ?? (previousCamera == null ? void 0 : previousCamera.y), + z: ((_c2 = ps.camera) == null ? void 0 : _c2.z) ?? (previousCamera == null ? void 0 : previousCamera.z) + }), + InstancePageStateRecordType.create({ + id: instancePageState, + pageId: ps.pageId, + selectedShapeIds: ps.selectedShapeIds ?? (previousInstanceState == null ? void 0 : previousInstanceState.selectedShapeIds), + focusedGroupId: ps.focusedGroupId ?? (previousInstanceState == null ? void 0 : previousInstanceState.focusedGroupId) + }) + ]); } - return next; - } - /** @internal */ - handleAfterChange(prev, next, source) { - if (!this._isEnabled) return; - const handlers = this._afterChangeHandlers[next.typeName]; - if (handlers) { - for (const handler of handlers) { - handler(prev, next, source); - } + store.put([instanceState]); + store.ensureStoreIsUsable(); + }); +} +function extractSessionStateFromLegacySnapshot(store) { + var _a3; + const instanceRecords = []; + for (const record of Object.values(store)) { + if ((_a3 = record.typeName) == null ? void 0 : _a3.match(/^(instance.*|pointer|camera)$/)) { + instanceRecords.push(record); } } - /** @internal */ - handleBeforeDelete(record, source) { - if (!this._isEnabled) return true; - const handlers = this._beforeDeleteHandlers[record.typeName]; - if (handlers) { - for (const handler of handlers) { - if (handler(record, source) === false) { - return false; - } - } - } - return true; + const oldInstance = instanceRecords.filter( + (r) => r.typeName === "instance" && r.id !== TLINSTANCE_ID + )[0]; + if (!oldInstance) return null; + const result = { + version: CURRENT_SESSION_STATE_SNAPSHOT_VERSION, + currentPageId: oldInstance.currentPageId, + exportBackground: !!oldInstance.exportBackground, + isFocusMode: !!oldInstance.isFocusMode, + isDebugMode: !!oldInstance.isDebugMode, + isToolLocked: !!oldInstance.isToolLocked, + isGridMode: false, + pageStates: instanceRecords.filter((r) => r.typeName === "instance_page_state" && r.instanceId === oldInstance.id).map((ps) => { + const camera = store[ps.cameraId] ?? { x: 0, y: 0, z: 1 }; + return { + pageId: ps.pageId, + camera: { + x: camera.x, + y: camera.y, + z: camera.z + }, + selectedShapeIds: ps.selectedShapeIds, + focusedGroupId: ps.focusedGroupId + }; + }) + }; + try { + sessionStateSnapshotValidator.validate(result); + return result; + } catch { + return null; } - /** @internal */ - handleAfterDelete(record, source) { - if (!this._isEnabled) return; - const handlers = this._afterDeleteHandlers[record.typeName]; - if (handlers) { - for (const handler of handlers) { - handler(record, source); - } +} +function loadSnapshot(store, _snapshot, opts) { + let snapshot = {}; + if ("store" in _snapshot) { + const migrationResult = store.schema.migrateStoreSnapshot(_snapshot); + if (migrationResult.type !== "success") { + throw new Error("Failed to migrate store snapshot: " + migrationResult.reason); } + snapshot.document = { + schema: store.schema.serialize(), + store: filterEntries( + migrationResult.value, + (_2, { typeName }) => store.scopedTypes.document.has(typeName) + ) + }; + } else { + snapshot = _snapshot; } - /** @internal */ - handleOperationComplete(source) { - if (!this._isEnabled) return; - for (const handler of this._operationCompleteHandlers) { - handler(source); + const preservingInstanceState = pluckPreservingValues(store.get(TLINSTANCE_ID)); + const preservingSessionState = sessionStateCache.get(store, createSessionStateSnapshotSignal).get(); + store.atomic(() => { + if (snapshot.document) { + store.loadStoreSnapshot(snapshot.document); } - } - /** - * Internal helper for registering a bunch of side effects at once and keeping them organized. - * @internal - */ - register(handlersByType) { - const disposes = []; - for (const [type, handlers] of Object.entries(handlersByType)) { - if (handlers == null ? void 0 : handlers.beforeCreate) { - disposes.push(this.registerBeforeCreateHandler(type, handlers.beforeCreate)); - } - if (handlers == null ? void 0 : handlers.afterCreate) { - disposes.push(this.registerAfterCreateHandler(type, handlers.afterCreate)); - } - if (handlers == null ? void 0 : handlers.beforeChange) { - disposes.push(this.registerBeforeChangeHandler(type, handlers.beforeChange)); - } - if (handlers == null ? void 0 : handlers.afterChange) { - disposes.push(this.registerAfterChangeHandler(type, handlers.afterChange)); - } - if (handlers == null ? void 0 : handlers.beforeDelete) { - disposes.push(this.registerBeforeDeleteHandler(type, handlers.beforeDelete)); - } - if (handlers == null ? void 0 : handlers.afterDelete) { - disposes.push(this.registerAfterDeleteHandler(type, handlers.afterDelete)); - } + if (preservingInstanceState) { + store.update(TLINSTANCE_ID, (r) => ({ ...r, ...preservingInstanceState })); } - return () => { - for (const dispose of disposes) dispose(); - }; - } - /** - * Register a handler to be called before a record of a certain type is created. Return a - * modified record from the handler to change the record that will be created. - * - * Use this handle only to modify the creation of the record itself. If you want to trigger a - * side-effect on a different record (for example, moving one shape when another is created), - * use {@link StoreSideEffects.registerAfterCreateHandler} instead. - * - * @example - * ```ts - * editor.sideEffects.registerBeforeCreateHandler('shape', (shape, source) => { - * // only modify shapes created by the user - * if (source !== 'user') return shape - * - * //by default, arrow shapes have no label. Let's make sure they always have a label. - * if (shape.type === 'arrow') { - * return {...shape, props: {...shape.props, text: 'an arrow'}} - * } - * - * // other shapes get returned unmodified - * return shape - * }) - * ``` - * - * @param typeName - The type of record to listen for - * @param handler - The handler to call - * - * @returns A callback that removes the handler. - */ - registerBeforeCreateHandler(typeName, handler) { - const handlers = this._beforeCreateHandlers[typeName]; - if (!handlers) this._beforeCreateHandlers[typeName] = []; - this._beforeCreateHandlers[typeName].push(handler); - return () => remove(this._beforeCreateHandlers[typeName], handler); - } - /** - * Register a handler to be called after a record is created. This is useful for side-effects - * that would update _other_ records. If you want to modify the record being created use - * {@link StoreSideEffects.registerBeforeCreateHandler} instead. - * - * @example - * ```ts - * editor.sideEffects.registerAfterCreateHandler('page', (page, source) => { - * // Automatically create a shape when a page is created - * editor.createShape({ - * id: createShapeId(), - * type: 'text', - * props: { text: page.name }, - * }) - * }) - * ``` - * - * @param typeName - The type of record to listen for - * @param handler - The handler to call - * - * @returns A callback that removes the handler. - */ - registerAfterCreateHandler(typeName, handler) { - const handlers = this._afterCreateHandlers[typeName]; - if (!handlers) this._afterCreateHandlers[typeName] = []; - this._afterCreateHandlers[typeName].push(handler); - return () => remove(this._afterCreateHandlers[typeName], handler); + if (preservingSessionState) { + loadSessionStateSnapshotIntoStore(store, preservingSessionState); + } + if (snapshot.session) { + loadSessionStateSnapshotIntoStore(store, snapshot.session, { + forceOverwrite: opts == null ? void 0 : opts.forceOverwriteSessionState + }); + } + }); +} +const sessionStateCache = new WeakCache(); +function getSnapshot(store) { + const sessionState$ = sessionStateCache.get(store, createSessionStateSnapshotSignal); + const session = sessionState$.get(); + if (!session) { + throw new Error("Session state is not ready yet"); } - /** - * Register a handler to be called before a record is changed. The handler is given the old and - * new record - you can return a modified record to apply a different update, or the old record - * to block the update entirely. - * - * Use this handler only for intercepting updates to the record itself. If you want to update - * other records in response to a change, use - * {@link StoreSideEffects.registerAfterChangeHandler} instead. - * - * @example - * ```ts - * editor.sideEffects.registerBeforeChangeHandler('shape', (prev, next, source) => { - * if (next.isLocked && !prev.isLocked) { - * // prevent shapes from ever being locked: - * return prev - * } - * // other types of change are allowed - * return next - * }) - * ``` - * - * @param typeName - The type of record to listen for - * @param handler - The handler to call - * - * @returns A callback that removes the handler. - */ - registerBeforeChangeHandler(typeName, handler) { - const handlers = this._beforeChangeHandlers[typeName]; - if (!handlers) this._beforeChangeHandlers[typeName] = []; - this._beforeChangeHandlers[typeName].push(handler); - return () => remove(this._beforeChangeHandlers[typeName], handler); + return { + document: store.getStoreSnapshot(), + session + }; +} +function checkBindings(customBindings) { + const bindings = []; + const addedCustomBindingTypes = /* @__PURE__ */ new Set(); + for (const customBinding of customBindings) { + if (addedCustomBindingTypes.has(customBinding.type)) { + throw new Error(`Binding type "${customBinding.type}" is defined more than once`); + } + bindings.push(customBinding); + addedCustomBindingTypes.add(customBinding.type); } - /** - * Register a handler to be called after a record is changed. This is useful for side-effects - * that would update _other_ records - if you want to modify the record being changed, use - * {@link StoreSideEffects.registerBeforeChangeHandler} instead. - * - * @example - * ```ts - * editor.sideEffects.registerAfterChangeHandler('shape', (prev, next, source) => { - * if (next.props.color === 'red') { - * // there can only be one red shape at a time: - * const otherRedShapes = editor.getCurrentPageShapes().filter(s => s.props.color === 'red' && s.id !== next.id) - * editor.updateShapes(otherRedShapes.map(s => ({...s, props: {...s.props, color: 'blue'}}))) - * } - * }) - * ``` - * - * @param typeName - The type of record to listen for - * @param handler - The handler to call - * - * @returns A callback that removes the handler. - */ - registerAfterChangeHandler(typeName, handler) { - const handlers = this._afterChangeHandlers[typeName]; - if (!handlers) this._afterChangeHandlers[typeName] = []; - this._afterChangeHandlers[typeName].push(handler); - return () => remove(this._afterChangeHandlers[typeName], handler); + return bindings; +} +function SVGContainer({ children, className = "", ...rest }) { + return /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { ...rest, className: classNames("tl-svg-container", className), children }); +} +function intersectLineSegmentLineSegment(a1, a2, b1, b2) { + const ABx = a1.x - b1.x; + const ABy = a1.y - b1.y; + const BVx = b2.x - b1.x; + const BVy = b2.y - b1.y; + const AVx = a2.x - a1.x; + const AVy = a2.y - a1.y; + const ua_t = BVx * ABy - BVy * ABx; + const ub_t = AVx * ABy - AVy * ABx; + const u_b = BVy * AVx - BVx * AVy; + if (ua_t === 0 || ub_t === 0) return null; + if (u_b === 0) return null; + if (u_b !== 0) { + const ua = ua_t / u_b; + const ub = ub_t / u_b; + if (0 <= ua && ua <= 1 && 0 <= ub && ub <= 1) { + return Vec.AddXY(a1, ua * AVx, ua * AVy); + } } - /** - * Register a handler to be called before a record is deleted. The handler can return `false` to - * prevent the deletion. - * - * Use this handler only for intercepting deletions of the record itself. If you want to do - * something to other records in response to a deletion, use - * {@link StoreSideEffects.registerAfterDeleteHandler} instead. - * - * @example - * ```ts - * editor.sideEffects.registerBeforeDeleteHandler('shape', (shape, source) => { - * if (shape.props.color === 'red') { - * // prevent red shapes from being deleted - * return false - * } - * }) - * ``` - * - * @param typeName - The type of record to listen for - * @param handler - The handler to call - * - * @returns A callback that removes the handler. - */ - registerBeforeDeleteHandler(typeName, handler) { - const handlers = this._beforeDeleteHandlers[typeName]; - if (!handlers) this._beforeDeleteHandlers[typeName] = []; - this._beforeDeleteHandlers[typeName].push(handler); - return () => remove(this._beforeDeleteHandlers[typeName], handler); + return null; +} +function intersectLineSegmentCircle(a1, a2, c2, r) { + const a3 = (a2.x - a1.x) * (a2.x - a1.x) + (a2.y - a1.y) * (a2.y - a1.y); + const b2 = 2 * ((a2.x - a1.x) * (a1.x - c2.x) + (a2.y - a1.y) * (a1.y - c2.y)); + const cc = c2.x * c2.x + c2.y * c2.y + a1.x * a1.x + a1.y * a1.y - 2 * (c2.x * a1.x + c2.y * a1.y) - r * r; + const deter = b2 * b2 - 4 * a3 * cc; + if (deter < 0) return null; + if (deter === 0) return null; + const e2 = Math.sqrt(deter); + const u1 = (-b2 + e2) / (2 * a3); + const u2 = (-b2 - e2) / (2 * a3); + if ((u1 < 0 || u1 > 1) && (u2 < 0 || u2 > 1)) { + return null; } - /** - * Register a handler to be called after a record is deleted. This is useful for side-effects - * that would update _other_ records - if you want to block the deletion of the record itself, - * use {@link StoreSideEffects.registerBeforeDeleteHandler} instead. - * - * @example - * ```ts - * editor.sideEffects.registerAfterDeleteHandler('shape', (shape, source) => { - * // if the last shape in a frame is deleted, delete the frame too: - * const parentFrame = editor.getShape(shape.parentId) - * if (!parentFrame || parentFrame.type !== 'frame') return - * - * const siblings = editor.getSortedChildIdsForParent(parentFrame) - * if (siblings.length === 0) { - * editor.deleteShape(parentFrame.id) - * } - * }) - * ``` - * - * @param typeName - The type of record to listen for - * @param handler - The handler to call - * - * @returns A callback that removes the handler. - */ - registerAfterDeleteHandler(typeName, handler) { - const handlers = this._afterDeleteHandlers[typeName]; - if (!handlers) this._afterDeleteHandlers[typeName] = []; - this._afterDeleteHandlers[typeName].push(handler); - return () => remove(this._afterDeleteHandlers[typeName], handler); + const result = []; + if (0 <= u1 && u1 <= 1) result.push(Vec.Lrp(a1, a2, u1)); + if (0 <= u2 && u2 <= 1) result.push(Vec.Lrp(a1, a2, u2)); + if (result.length === 0) return null; + return result; +} +function intersectLineSegmentPolyline(a1, a2, points) { + const result = []; + let segmentIntersection; + for (let i2 = 0, n = points.length - 1; i2 < n; i2++) { + segmentIntersection = intersectLineSegmentLineSegment(a1, a2, points[i2], points[i2 + 1]); + if (segmentIntersection) result.push(segmentIntersection); } - /** - * Register a handler to be called when a store completes an atomic operation. - * - * @example - * ```ts - * let count = 0 - * - * editor.sideEffects.registerOperationCompleteHandler(() => count++) - * - * editor.selectAll() - * expect(count).toBe(1) - * - * editor.store.atomic(() => { - * editor.selectNone() - * editor.selectAll() - * }) - * - * expect(count).toBe(2) - * ``` - * - * @param handler - The handler to call - * - * @returns A callback that removes the handler. - * - * @public - */ - registerOperationCompleteHandler(handler) { - this._operationCompleteHandlers.push(handler); - return () => remove(this._operationCompleteHandlers, handler); + if (result.length === 0) return null; + return result; +} +function intersectLineSegmentPolygon(a1, a2, points) { + const result = []; + let segmentIntersection; + for (let i2 = 1, n = points.length; i2 < n + 1; i2++) { + segmentIntersection = intersectLineSegmentLineSegment( + a1, + a2, + points[i2 - 1], + points[i2 % points.length] + ); + if (segmentIntersection) result.push(segmentIntersection); } + if (result.length === 0) return null; + return result; } -function remove(array2, item) { - const index2 = array2.indexOf(item); - if (index2 >= 0) { - array2.splice(index2, 1); +function intersectCircleCircle(c1, r1, c2, r2) { + let dx = c2.x - c1.x; + let dy = c2.y - c1.y; + const d2 = Math.sqrt(dx * dx + dy * dy), x2 = (d2 * d2 - r2 * r2 + r1 * r1) / (2 * d2), y2 = Math.sqrt(r1 * r1 - x2 * x2); + dx /= d2; + dy /= d2; + return [ + new Vec(c1.x + dx * x2 - dy * y2, c1.y + dy * x2 + dx * y2), + new Vec(c1.x + dx * x2 + dy * y2, c1.y + dy * x2 - dx * y2) + ]; +} +function intersectCirclePolygon(c2, r, points) { + const result = []; + let a2, b2, int; + for (let i2 = 0, n = points.length; i2 < n; i2++) { + a2 = points[i2]; + b2 = points[(i2 + 1) % points.length]; + int = intersectLineSegmentCircle(a2, b2, c2, r); + if (int) result.push(...int); } + if (result.length === 0) return null; + return result; } -function devFreeze(object2) { - { - return object2; +function intersectCirclePolyline(c2, r, points) { + const result = []; + let a2, b2, int; + for (let i2 = 1, n = points.length; i2 < n; i2++) { + a2 = points[i2 - 1]; + b2 = points[i2]; + int = intersectLineSegmentCircle(a2, b2, c2, r); + if (int) result.push(...int); } + if (result.length === 0) return null; + return result; } -class Store { - constructor(config) { - /** - * The random id of the store. - */ - __publicField(this, "id"); - /** - * An atom containing the store's atoms. - * - * @internal - * @readonly - */ - __publicField(this, "atoms", atom("store_atoms", {})); - /** - * An atom containing the store's history. - * - * @public - * @readonly - */ - __publicField(this, "history", atom("history", 0, { - historyLength: 1e3 - })); - /** - * A StoreQueries instance for this store. - * - * @public - * @readonly - */ - __publicField(this, "query", new StoreQueries(this.atoms, this.history)); - /** - * A set containing listeners that have been added to this store. - * - * @internal - */ - __publicField(this, "listeners", /* @__PURE__ */ new Set()); - /** - * An array of history entries that have not yet been flushed. - * - * @internal - */ - __publicField(this, "historyAccumulator", new HistoryAccumulator()); - /** - * A reactor that responds to changes to the history by squashing the accumulated history and - * notifying listeners of the changes. - * - * @internal - */ - __publicField(this, "historyReactor"); - __publicField(this, "schema"); - __publicField(this, "props"); - __publicField(this, "scopedTypes"); - __publicField(this, "sideEffects", new StoreSideEffects(this)); - __publicField(this, "isMergingRemoteChanges", false); - __publicField(this, "_integrityChecker"); - __publicField(this, "_isPossiblyCorrupted", false); - __publicField(this, "pendingAfterEvents", null); - __publicField(this, "_isInAtomicOp", false); - const { initialData, schema, id: id2 } = config; - this.id = id2 ?? uniqueId(); - this.schema = schema; - this.props = config.props; - if (initialData) { - this.atoms.set( - objectMapFromEntries( - objectMapEntries(initialData).map(([id22, record]) => [ - id22, - atom( - "atom:" + id22, - devFreeze(this.schema.validateRecord(this, record, "initialize", null)) - ) - ]) - ) - ); +function ccw(A, B2, C2) { + return (C2.y - A.y) * (B2.x - A.x) > (B2.y - A.y) * (C2.x - A.x); +} +function linesIntersect(A, B2, C2, D) { + return ccw(A, C2, D) !== ccw(B2, C2, D) && ccw(A, B2, C2) !== ccw(A, B2, D); +} +function intersectPolygonPolygon(polygonA, polygonB) { + const result = /* @__PURE__ */ new Map(); + let a2, b2, c2, d2; + for (let i2 = 0, n = polygonA.length; i2 < n; i2++) { + a2 = polygonA[i2]; + if (pointInPolygon(a2, polygonB)) { + const id2 = getPointId(a2); + if (!result.has(id2)) { + result.set(id2, a2); + } } - this.historyReactor = reactor( - "Store.historyReactor", - () => { - this.history.get(); - this._flushHistory(); - }, - { scheduleEffect: (cb2) => this.cancelHistoryReactor = throttleToNextFrame$1(cb2) } - ); - this.scopedTypes = { - document: new Set( - objectMapValues(this.schema.types).filter((t2) => t2.scope === "document").map((t2) => t2.typeName) - ), - session: new Set( - objectMapValues(this.schema.types).filter((t2) => t2.scope === "session").map((t2) => t2.typeName) - ), - presence: new Set( - objectMapValues(this.schema.types).filter((t2) => t2.scope === "presence").map((t2) => t2.typeName) - ) - }; } - /** - * Function to dispose of any in-flight timeouts. - * - * @internal - */ - cancelHistoryReactor() { + for (let i2 = 0, n = polygonB.length; i2 < n; i2++) { + a2 = polygonB[i2]; + if (pointInPolygon(a2, polygonA)) { + const id2 = getPointId(a2); + if (!result.has(id2)) { + result.set(id2, a2); + } + } } - _flushHistory() { - if (this.historyAccumulator.hasChanges()) { - const entries = this.historyAccumulator.flush(); - for (const { changes, source } of entries) { - let instanceChanges = null; - let documentChanges = null; - let presenceChanges = null; - for (const { onHistory, filters } of this.listeners) { - if (filters.source !== "all" && filters.source !== source) { - continue; - } - if (filters.scope !== "all") { - if (filters.scope === "document") { - documentChanges ?? (documentChanges = this.filterChangesByScope(changes, "document")); - if (!documentChanges) continue; - onHistory({ changes: documentChanges, source }); - } else if (filters.scope === "session") { - instanceChanges ?? (instanceChanges = this.filterChangesByScope(changes, "session")); - if (!instanceChanges) continue; - onHistory({ changes: instanceChanges, source }); - } else { - presenceChanges ?? (presenceChanges = this.filterChangesByScope(changes, "presence")); - if (!presenceChanges) continue; - onHistory({ changes: presenceChanges, source }); - } - } else { - onHistory({ changes, source }); - } + for (let i2 = 0, n = polygonA.length; i2 < n; i2++) { + a2 = polygonA[i2]; + b2 = polygonA[(i2 + 1) % polygonA.length]; + for (let j2 = 0, m2 = polygonB.length; j2 < m2; j2++) { + c2 = polygonB[j2]; + d2 = polygonB[(j2 + 1) % polygonB.length]; + const intersection = intersectLineSegmentLineSegment(a2, b2, c2, d2); + if (intersection !== null) { + const id2 = getPointId(intersection); + if (!result.has(id2)) { + result.set(id2, intersection); } } } } - dispose() { - this.cancelHistoryReactor(); + if (result.size === 0) return null; + return orderClockwise([...result.values()]); +} +function getPointId(point) { + return `${point.x},${point.y}`; +} +function orderClockwise(points) { + const C2 = Vec.Average(points); + return points.sort((A, B2) => Vec.Angle(C2, A) - Vec.Angle(C2, B2)); +} +function polygonsIntersect(a2, b2) { + let a0, a1, b0, b1; + for (let i2 = 0, n = a2.length; i2 < n; i2++) { + a0 = a2[i2]; + a1 = a2[(i2 + 1) % n]; + for (let j2 = 0, m2 = b2.length; j2 < m2; j2++) { + b0 = b2[j2]; + b1 = b2[(j2 + 1) % m2]; + if (linesIntersect(a0, a1, b0, b1)) return true; + } } - /** - * Filters out non-document changes from a diff. Returns null if there are no changes left. - * @param change - the records diff - * @param scope - the records scope - * @returns - */ - filterChangesByScope(change, scope) { - const result = { - added: filterEntries(change.added, (_2, r2) => this.scopedTypes[scope].has(r2.typeName)), - updated: filterEntries(change.updated, (_2, r2) => this.scopedTypes[scope].has(r2[1].typeName)), - removed: filterEntries(change.removed, (_2, r2) => this.scopedTypes[scope].has(r2.typeName)) - }; - if (Object.keys(result.added).length === 0 && Object.keys(result.updated).length === 0 && Object.keys(result.removed).length === 0) { - return null; + return false; +} +function polygonIntersectsPolyline(polygon, polyline) { + let a2, b2, c2, d2; + for (let i2 = 0, n = polygon.length; i2 < n; i2++) { + a2 = polygon[i2]; + b2 = polygon[(i2 + 1) % n]; + for (let j2 = 1, m2 = polyline.length; j2 < m2; j2++) { + c2 = polyline[j2 - 1]; + d2 = polyline[j2]; + if (linesIntersect(a2, b2, c2, d2)) return true; } - return result; } - /** - * Update the history with a diff of changes. - * - * @param changes - The changes to add to the history. - */ - updateHistory(changes) { - this.historyAccumulator.add({ - changes, - source: this.isMergingRemoteChanges ? "remote" : "user" - }); - if (this.listeners.size === 0) { - this.historyAccumulator.clear(); + return false; +} +class Edge2d extends Geometry2d { + constructor(config) { + super({ ...config, isClosed: false, isFilled: false }); + __publicField(this, "start"); + __publicField(this, "end"); + __publicField(this, "d"); + __publicField(this, "u"); + __publicField(this, "ul"); + const { start, end } = config; + this.start = start; + this.end = end; + this.d = start.clone().sub(end); + this.u = this.d.clone().uni(); + this.ul = this.u.len(); + } + getLength() { + return this.d.len(); + } + midPoint() { + return this.start.lrp(this.end, 0.5); + } + getVertices() { + return [this.start, this.end]; + } + nearestPoint(point) { + const { start, end, d: d2, u: u2, ul: l2 } = this; + if (d2.len() === 0) return start; + if (l2 === 0) return start; + const k = Vec.Sub(point, start).dpr(u2) / l2; + const cx = start.x + u2.x * k; + if (cx < Math.min(start.x, end.x)) return start.x < end.x ? start : end; + if (cx > Math.max(start.x, end.x)) return start.x > end.x ? start : end; + const cy = start.y + u2.y * k; + if (cy < Math.min(start.y, end.y)) return start.y < end.y ? start : end; + if (cy > Math.max(start.y, end.y)) return start.y > end.y ? start : end; + return new Vec(cx, cy); + } + hitTestLineSegment(A, B2, distance = 0) { + return linesIntersect(A, B2, this.start, this.end) || this.distanceToLineSegment(A, B2) <= distance; + } + getSvgPathData(first = true) { + const { start, end } = this; + return `${first ? `M${start.toFixed()}` : ``} L${end.toFixed()}`; + } +} +class Polyline2d extends Geometry2d { + constructor(config) { + super({ isClosed: false, isFilled: false, ...config }); + __publicField(this, "points"); + __publicField(this, "_segments"); + const { points } = config; + this.points = points; + } + // eslint-disable-next-line no-restricted-syntax + get segments() { + if (!this._segments) { + this._segments = []; + const { vertices } = this; + for (let i2 = 0, n = vertices.length - 1; i2 < n; i2++) { + const start = vertices[i2]; + const end = vertices[i2 + 1]; + this._segments.push(new Edge2d({ start, end })); + } + if (this.isClosed) { + this._segments.push(new Edge2d({ start: vertices[vertices.length - 1], end: vertices[0] })); + } } - this.history.set(this.history.get() + 1, changes); + return this._segments; } - validate(phase) { - this.allRecords().forEach((record) => this.schema.validateRecord(this, record, phase, null)); + getLength() { + return this.segments.reduce((acc, segment) => acc + segment.length, 0); } - /** - * Add some records to the store. It's an error if they already exist. - * - * @param records - The records to add. - * @param phaseOverride - The phase override. - * @public - */ - put(records, phaseOverride) { - this.atomic(() => { - const updates = {}; - const additions = {}; - const currentMap = this.atoms.__unsafe__getWithoutCapture(); - let map = null; - let record; - let didChange = false; - const source = this.isMergingRemoteChanges ? "remote" : "user"; - for (let i2 = 0, n2 = records.length; i2 < n2; i2++) { - record = records[i2]; - const recordAtom = (map ?? currentMap)[record.id]; - if (recordAtom) { - const initialValue = recordAtom.__unsafe__getWithoutCapture(); - record = this.sideEffects.handleBeforeChange(initialValue, record, source); - const validated = this.schema.validateRecord( - this, - record, - phaseOverride ?? "updateRecord", - initialValue - ); - if (validated === initialValue) continue; - recordAtom.set(devFreeze(record)); - didChange = true; - const updated = recordAtom.__unsafe__getWithoutCapture(); - updates[record.id] = [initialValue, updated]; - this.addDiffForAfterEvent(initialValue, updated); - } else { - record = this.sideEffects.handleBeforeCreate(record, source); - didChange = true; - record = this.schema.validateRecord( - this, - record, - phaseOverride ?? "createRecord", - null - ); - additions[record.id] = record; - this.addDiffForAfterEvent(null, record); - if (!map) { - map = { ...currentMap }; - } - map[record.id] = atom("atom:" + record.id, record); - } + getVertices() { + return this.points; + } + nearestPoint(A) { + const { segments } = this; + let nearest = this.points[0]; + let dist = Infinity; + let p2; + let d2; + for (let i2 = 0; i2 < segments.length; i2++) { + p2 = segments[i2].nearestPoint(A); + d2 = Vec.Dist2(p2, A); + if (d2 < dist) { + nearest = p2; + dist = d2; } - if (map) { - this.atoms.set(map); + } + if (!nearest) throw Error("nearest point not found"); + return nearest; + } + hitTestLineSegment(A, B2, distance = 0) { + const { segments } = this; + for (let i2 = 0, n = segments.length; i2 < n; i2++) { + if (segments[i2].hitTestLineSegment(A, B2, distance)) { + return true; } - if (!didChange) return; - this.updateHistory({ - added: additions, - updated: updates, - removed: {} - }); + } + return false; + } + getSvgPathData() { + const { vertices } = this; + if (vertices.length < 2) return ""; + return vertices.reduce((acc, vertex, i2) => { + if (i2 === 0) return `M ${vertex.x} ${vertex.y}`; + return `${acc} L ${vertex.x} ${vertex.y}`; + }, ""); + } +} +class Polygon2d extends Polyline2d { + constructor(config) { + super({ ...config }); + this.isClosed = true; + } +} +class Rectangle2d extends Polygon2d { + constructor(config) { + const { x: x2 = 0, y: y2 = 0, width, height } = config; + super({ + ...config, + points: [ + new Vec(x2, y2), + new Vec(x2 + width, y2), + new Vec(x2 + width, y2 + height), + new Vec(x2, y2 + height) + ] }); + __publicField(this, "x"); + __publicField(this, "y"); + __publicField(this, "w"); + __publicField(this, "h"); + this.x = x2; + this.y = y2; + this.w = width; + this.h = height; + } + getBounds() { + return new Box(this.x, this.y, this.w, this.h); + } + getSvgPathData() { + const { x: x2, y: y2, w: w2, h: h2 } = this; + return `M${x2},${y2} h${w2} v${h2} h-${w2}z`; + } +} +class ShapeUtil { + constructor(editor) { + this.editor = editor; } /** - * Remove some records from the store via their ids. + * Whether the shape can be snapped to by another shape. * - * @param ids - The ids of the records to remove. * @public */ - remove(ids) { - this.atomic(() => { - const cancelled = /* @__PURE__ */ new Set(); - const source = this.isMergingRemoteChanges ? "remote" : "user"; - if (this.sideEffects.isEnabled()) { - for (const id2 of ids) { - const atom2 = this.atoms.__unsafe__getWithoutCapture()[id2]; - if (!atom2) continue; - if (this.sideEffects.handleBeforeDelete(atom2.get(), source) === false) { - cancelled.add(id2); - } - } - } - let removed = void 0; - this.atoms.update((atoms) => { - let result = void 0; - for (const id2 of ids) { - if (cancelled.has(id2)) continue; - if (!(id2 in atoms)) continue; - if (!result) result = { ...atoms }; - if (!removed) removed = {}; - delete result[id2]; - const record = atoms[id2].get(); - removed[id2] = record; - this.addDiffForAfterEvent(record, null); - } - return result ?? atoms; - }); - if (!removed) return; - this.updateHistory({ added: {}, updated: {}, removed }); - }); + canSnap(_shape) { + return true; } /** - * Get the value of a store record by its id. + * Whether the shape can be scrolled while editing. * - * @param id - The id of the record to get. * @public */ - get(id2) { - var _a3; - return (_a3 = this.atoms.get()[id2]) == null ? void 0 : _a3.get(); + canScroll(_shape) { + return false; } /** - * Get the value of a store record by its id without updating its epoch. + * Whether the shape can be bound to. See {@link TLShapeUtilCanBindOpts} for details. * - * @param id - The id of the record to get. * @public */ - unsafeGetWithoutCapture(id2) { - var _a3; - return (_a3 = this.atoms.__unsafe__getWithoutCapture()[id2]) == null ? void 0 : _a3.__unsafe__getWithoutCapture(); + canBind(_opts) { + return true; } /** - * Creates a JSON payload from the record store. + * Whether the shape can be double clicked to edit. * - * @param scope - The scope of records to serialize. Defaults to 'document'. - * @returns The record store snapshot as a JSON payload. + * @public */ - serialize(scope = "document") { - const result = {}; - for (const [id2, atom2] of objectMapEntries(this.atoms.get())) { - const record = atom2.get(); - if (scope === "all" || this.scopedTypes[scope].has(record.typeName)) { - result[id2] = record; - } - } - return result; + canEdit(_shape) { + return false; } /** - * Get a serialized snapshot of the store and its schema. - * - * ```ts - * const snapshot = store.getStoreSnapshot() - * store.loadStoreSnapshot(snapshot) - * ``` - * - * @param scope - The scope of records to serialize. Defaults to 'document'. + * Whether the shape can be resized. * * @public */ - getStoreSnapshot(scope = "document") { - return { - store: this.serialize(scope), - schema: this.schema.serialize() - }; - } - /** - * @deprecated use `getSnapshot` from the 'tldraw' package instead. - */ - getSnapshot(scope = "document") { - console.warn( - "[tldraw] `Store.getSnapshot` is deprecated and will be removed in a future release. Use `getSnapshot` from the `tldraw` package instead." - ); - return this.getStoreSnapshot(scope); + canResize(_shape) { + return true; } /** - * Migrate a serialized snapshot of the store and its schema. - * - * ```ts - * const snapshot = store.getSnapshot() - * store.migrateSnapshot(snapshot) - * ``` + * Whether the shape can be edited in read-only mode. * - * @param snapshot - The snapshot to load. * @public */ - migrateSnapshot(snapshot) { - const migrationResult = this.schema.migrateStoreSnapshot(snapshot); - if (migrationResult.type === "error") { - throw new Error(`Failed to migrate snapshot: ${migrationResult.reason}`); - } - return { - store: migrationResult.value, - schema: this.schema.serialize() - }; + canEditInReadOnly(_shape) { + return false; } /** - * Load a serialized snapshot. - * - * ```ts - * const snapshot = store.getStoreSnapshot() - * store.loadStoreSnapshot(snapshot) - * ``` + * Whether the shape can be cropped. * - * @param snapshot - The snapshot to load. * @public */ - loadStoreSnapshot(snapshot) { - const migrationResult = this.schema.migrateStoreSnapshot(snapshot); - if (migrationResult.type === "error") { - throw new Error(`Failed to migrate snapshot: ${migrationResult.reason}`); - } - const prevSideEffectsEnabled = this.sideEffects.isEnabled(); - try { - this.sideEffects.setIsEnabled(false); - this.atomic(() => { - this.clear(); - this.put(Object.values(migrationResult.value)); - this.ensureStoreIsUsable(); - }); - } finally { - this.sideEffects.setIsEnabled(prevSideEffectsEnabled); - } + canCrop(_shape) { + return false; } /** + * Whether the shape participates in stacking, aligning, and distributing. + * * @public - * @deprecated use `loadSnapshot` from the 'tldraw' package instead. */ - loadSnapshot(snapshot) { - console.warn( - "[tldraw] `Store.loadSnapshot` is deprecated and will be removed in a future release. Use `loadSnapshot` from the 'tldraw' package instead." - ); - this.loadStoreSnapshot(snapshot); + canBeLaidOut(_shape) { + return true; } /** - * Get an array of all values in the store. + * Does this shape provide a background for its children? If this is true, + * then any children with a `renderBackground` method will have their + * backgrounds rendered _above_ this shape. Otherwise, the children's + * backgrounds will be rendered above either the next ancestor that provides + * a background, or the canvas background. * - * @returns An array of all values in the store. - * @public + * @internal */ - allRecords() { - return objectMapValues(this.atoms.get()).map((atom2) => atom2.get()); + providesBackgroundForChildren(_shape) { + return false; } /** - * Removes all records from the store. + * Whether the shape should hide its resize handles when selected. * * @public */ - clear() { - this.remove(objectMapKeys(this.atoms.get())); + hideResizeHandles(_shape) { + return false; } /** - * Update a record. To update multiple records at once, use the `update` method of the - * `TypedStore` class. + * Whether the shape should hide its rotation handles when selected. * - * @param id - The id of the record to update. - * @param updater - A function that updates the record. + * @public */ - update(id2, updater) { - const atom2 = this.atoms.get()[id2]; - if (!atom2) { - console.error(`Record ${id2} not found. This is probably an error`); - return; - } - this.put([updater(atom2.__unsafe__getWithoutCapture())]); + hideRotateHandle(_shape) { + return false; } /** - * Get whether the record store has a id. + * Whether the shape should hide its selection bounds background when selected. * - * @param id - The id of the record to check. * @public */ - has(id2) { - return !!this.atoms.get()[id2]; + hideSelectionBoundsBg(_shape) { + return false; } /** - * Add a new listener to the store. + * Whether the shape should hide its selection bounds foreground when selected. * - * @param onHistory - The listener to call when the store updates. - * @param filters - Filters to apply to the listener. - * @returns A function to remove the listener. + * @public */ - listen(onHistory, filters) { - this._flushHistory(); - const listener = { - onHistory, - filters: { - source: (filters == null ? void 0 : filters.source) ?? "all", - scope: (filters == null ? void 0 : filters.scope) ?? "all" - } - }; - this.listeners.add(listener); - if (!this.historyReactor.scheduler.isActivelyListening) { - this.historyReactor.start(); - } - return () => { - this.listeners.delete(listener); - if (this.listeners.size === 0) { - this.historyReactor.stop(); - } - }; + hideSelectionBoundsFg(_shape) { + return false; } /** - * Merge changes from a remote source without triggering listeners. + * Whether the shape's aspect ratio is locked. * - * @param fn - A function that merges the external changes. * @public */ - mergeRemoteChanges(fn) { - if (this.isMergingRemoteChanges) { - return fn(); - } - if (this._isInAtomicOp) { - throw new Error("Cannot merge remote changes while in atomic operation"); - } - try { - this.isMergingRemoteChanges = true; - transact(fn); - } finally { - this.isMergingRemoteChanges = false; - } - } - /** - * Run `fn` and return a {@link RecordsDiff} of the changes that occurred as a result. - */ - extractingChanges(fn) { - const changes = []; - const dispose = this.historyAccumulator.addInterceptor((entry2) => changes.push(entry2.changes)); - try { - transact(fn); - return squashRecordDiffs(changes); - } finally { - dispose(); - } - } - applyDiff(diff, { - runCallbacks = true, - ignoreEphemeralKeys = false - } = {}) { - this.atomic(() => { - const toPut = objectMapValues(diff.added); - for (const [_from, to] of objectMapValues(diff.updated)) { - const type = this.schema.getType(to.typeName); - if (ignoreEphemeralKeys && type.ephemeralKeySet.size) { - const existing = this.get(to.id); - if (!existing) { - toPut.push(to); - continue; - } - let changed = null; - for (const [key, value] of Object.entries(to)) { - if (type.ephemeralKeySet.has(key) || Object.is(value, getOwnProperty(existing, key))) { - continue; - } - if (!changed) changed = { ...existing }; - changed[key] = value; - } - if (changed) toPut.push(changed); - } else { - toPut.push(to); - } - } - const toRemove = objectMapKeys(diff.removed); - if (toPut.length) { - this.put(toPut); - } - if (toRemove.length) { - this.remove(toRemove); - } - }, runCallbacks); + isAspectRatioLocked(_shape) { + return false; } /** - * Create a computed cache. + * Get whether the shape can receive children of a given type. * - * @param name - The name of the derivation cache. - * @param derive - A function used to derive the value of the cache. - * @param isEqual - A function that determins equality between two records. + * @param shape - The shape. + * @param type - The shape type. * @public */ - createComputedCache(name, derive, isEqual2) { - const cache = new WeakCache(); - return { - get: (id2) => { - const atom2 = this.atoms.get()[id2]; - if (!atom2) { - return void 0; - } - return cache.get(atom2, () => { - const recordSignal = isEqual2 ? computed(atom2.name + ":equals", () => atom2.get(), { isEqual: isEqual2 }) : atom2; - return computed(name + ":" + id2, () => { - return derive(recordSignal.get()); - }); - }).get(); - } - }; + canReceiveNewChildrenOfType(_shape, _type) { + return false; } /** - * Create a computed cache from a selector + * Get whether the shape can receive children of a given type. * - * @param name - The name of the derivation cache. - * @param selector - A function that returns a subset of the original shape - * @param derive - A function used to derive the value of the cache. + * @param shape - The shape type. + * @param shapes - The shapes that are being dropped. * @public */ - createSelectedComputedCache(name, selector, derive) { - const cache = new WeakCache(); - return { - get: (id2) => { - const atom2 = this.atoms.get()[id2]; - if (!atom2) { - return void 0; - } - return cache.get(atom2, () => { - const d2 = computed( - name + ":" + id2 + ":selector", - () => selector(atom2.get()) - ); - return computed(name + ":" + id2, () => derive(d2.get())); - }).get(); - } - }; - } - /** @internal */ - ensureStoreIsUsable() { - this.atomic(() => { - var _a3; - this._integrityChecker ?? (this._integrityChecker = this.schema.createIntegrityChecker(this)); - (_a3 = this._integrityChecker) == null ? void 0 : _a3.call(this); - }); - } - /** @internal */ - markAsPossiblyCorrupted() { - this._isPossiblyCorrupted = true; + canDropShapes(_shape, _shapes) { + return false; } /** @internal */ - isPossiblyCorrupted() { - return this._isPossiblyCorrupted; - } - addDiffForAfterEvent(before, after) { - assert(this.pendingAfterEvents, "must be in event operation"); - if (before === after) return; - if (before && after) assert(before.id === after.id); - if (!before && !after) return; - const id2 = (before || after).id; - const existing = this.pendingAfterEvents.get(id2); - if (existing) { - existing.after = after; - } else { - this.pendingAfterEvents.set(id2, { before, after }); - } + expandSelectionOutlinePx(shape) { + return 0; } - flushAtomicCallbacks() { - let updateDepth = 0; - const source = this.isMergingRemoteChanges ? "remote" : "user"; - while (this.pendingAfterEvents) { - const events = this.pendingAfterEvents; - this.pendingAfterEvents = null; - if (!this.sideEffects.isEnabled()) continue; - updateDepth++; - if (updateDepth > 100) { - throw new Error("Maximum store update depth exceeded, bailing out"); - } - for (const { before, after } of events.values()) { - if (before && after) { - this.sideEffects.handleAfterChange(before, after, source); - } else if (before && !after) { - this.sideEffects.handleAfterDelete(before, source); - } else if (!before && after) { - this.sideEffects.handleAfterCreate(after, source); - } - } - if (!this.pendingAfterEvents) { - this.sideEffects.handleOperationComplete(source); - } - } + /** + * Return elements to be added to the \ section of the canvases SVG context. This can be + * used to define SVG content (e.g. patterns & masks) that can be referred to by ID from svg + * elements returned by `component`. + * + * Each def should have a unique `key`. If multiple defs from different shapes all have the same + * key, only one will be used. + */ + getCanvasSvgDefs() { + return []; } - /** @internal */ - atomic(fn, runCallbacks = true) { - return transact(() => { - if (this._isInAtomicOp) { - if (!this.pendingAfterEvents) this.pendingAfterEvents = /* @__PURE__ */ new Map(); - return fn(); - } - this.pendingAfterEvents = /* @__PURE__ */ new Map(); - const prevSideEffectsEnabled = this.sideEffects.isEnabled(); - this.sideEffects.setIsEnabled(runCallbacks ?? prevSideEffectsEnabled); - this._isInAtomicOp = true; - try { - const result = fn(); - this.flushAtomicCallbacks(); - return result; - } finally { - this.pendingAfterEvents = null; - this.sideEffects.setIsEnabled(prevSideEffectsEnabled); - this._isInAtomicOp = false; - } - }); + /** + * Get the geometry to use when snapping to this this shape in translate/resize operations. See + * {@link BoundsSnapGeometry} for details. + */ + getBoundsSnapGeometry(_shape) { + return {}; } - /** @internal */ - addHistoryInterceptor(fn) { - return this.historyAccumulator.addInterceptor( - (entry2) => fn(entry2, this.isMergingRemoteChanges ? "remote" : "user") - ); + /** + * Get the geometry to use when snapping handles to this shape. See {@link HandleSnapGeometry} + * for details. + */ + getHandleSnapGeometry(_shape) { + return {}; } -} -function squashHistoryEntries(entries) { - if (entries.length === 0) return []; - const chunked = []; - let chunk = [entries[0]]; - let entry2; - for (let i2 = 1, n2 = entries.length; i2 < n2; i2++) { - entry2 = entries[i2]; - if (chunk[0].source !== entry2.source) { - chunked.push(chunk); - chunk = []; - } - chunk.push(entry2); + getText(_shape) { + return void 0; } - chunked.push(chunk); - return devFreeze( - chunked.map((chunk2) => ({ - source: chunk2[0].source, - changes: squashRecordDiffs(chunk2.map((e2) => e2.changes)) - })) - ); } -class HistoryAccumulator { - constructor() { - __publicField(this, "_history", []); - __publicField(this, "_interceptors", /* @__PURE__ */ new Set()); - } - addInterceptor(fn) { - this._interceptors.add(fn); - return () => { - this._interceptors.delete(fn); +/** + * Props allow you to define the shape's properties in a way that the editor can understand. + * This has two main uses: + * + * 1. Validation. Shapes will be validated using these props to stop bad data from being saved. + * 2. Styles. Each {@link @tldraw/tlschema#StyleProp} in the props can be set on many shapes at + * once, and will be remembered from one shape to the next. + * + * @example + * ```tsx + * import {T, TLBaseShape, TLDefaultColorStyle, DefaultColorStyle, ShapeUtil} from 'tldraw' + * + * type MyShape = TLBaseShape<'mine', { + * color: TLDefaultColorStyle, + * text: string, + * }> + * + * class MyShapeUtil extends ShapeUtil { + * static props = { + * // we use tldraw's built-in color style: + * color: DefaultColorStyle, + * // validate that the text prop is a string: + * text: T.string, + * } + * } + * ``` + */ +__publicField(ShapeUtil, "props"); +/** + * Migrations allow you to make changes to a shape's props over time. Read the + * {@link https://www.tldraw.dev/docs/persistence#Shape-props-migrations | shape prop migrations} + * guide for more information. + */ +__publicField(ShapeUtil, "migrations"); +/** + * The type of the shape util, which should match the shape's type. + * + * @public + */ +__publicField(ShapeUtil, "type"); +function getPerfectDashProps(totalLength, strokeWidth, opts = {}) { + const { + closed = false, + snap = 1, + start = "outset", + end = "outset", + lengthRatio = 2, + style = "dashed", + forceSolid = false + } = opts; + let dashLength = 0; + let dashCount = 0; + let ratio = 1; + let gapLength = 0; + let strokeDashoffset = 0; + if (forceSolid) { + return { + strokeDasharray: "none", + strokeDashoffset: "none" }; } - add(entry2) { - this._history.push(entry2); - for (const interceptor of this._interceptors) { - interceptor(entry2); + switch (style) { + case "dashed": { + ratio = 1; + dashLength = Math.min(strokeWidth * lengthRatio, totalLength / 4); + break; + } + case "dotted": { + ratio = 100; + dashLength = strokeWidth / ratio; + break; + } + default: { + return { + strokeDasharray: "none", + strokeDashoffset: "none" + }; } } - flush() { - const history = squashHistoryEntries(this._history); - this._history = []; - return history; - } - clear() { - this._history = []; - } - hasChanges() { - return this._history.length > 0; + if (!closed) { + if (start === "outset") { + totalLength += dashLength / 2; + strokeDashoffset += dashLength / 2; + } else if (start === "skip") { + totalLength -= dashLength; + strokeDashoffset -= dashLength; + } + if (end === "outset") { + totalLength += dashLength / 2; + } else if (end === "skip") { + totalLength -= dashLength; + } } -} -function createComputedCache(name, derive, isEqual2) { - const cache = new WeakCache(); - return { - get(context, id2) { - const computedCache = cache.get(context, () => { - const store = context instanceof Store ? context : context.store; - return store.createComputedCache(name, (record) => derive(context, record), isEqual2); - }); - return computedCache.get(id2); + dashCount = Math.floor(totalLength / dashLength / (2 * ratio)); + dashCount -= dashCount % snap; + if (dashCount < 3 && style === "dashed") { + if (totalLength / strokeWidth < 4) { + dashLength = totalLength; + dashCount = 1; + gapLength = 0; + } else { + dashLength = totalLength * (1 / 3); + gapLength = totalLength * (1 / 3); } - }; -} -function squashDependsOn(sequence) { - const result = []; - for (let i2 = sequence.length - 1; i2 >= 0; i2--) { - const elem = sequence[i2]; - if (!("id" in elem)) { - const dependsOn = elem.dependsOn; - const prev = result[0]; - if (prev) { - result[0] = { - ...prev, - dependsOn: dependsOn.concat(prev.dependsOn ?? []) - }; - } + } else { + dashLength = totalLength / dashCount / (2 * ratio); + if (closed) { + strokeDashoffset = dashLength / 2; + gapLength = (totalLength - dashCount * dashLength) / dashCount; } else { - result.unshift(elem); + gapLength = (totalLength - dashCount * dashLength) / Math.max(1, dashCount - 1); } } - return result; -} -function createMigrationSequence({ - sequence, - sequenceId, - retroactive = true -}) { - const migrations = { - sequenceId, - retroactive, - sequence: squashDependsOn(sequence) + return { + strokeDasharray: [dashLength, gapLength].join(" "), + strokeDashoffset: strokeDashoffset.toString() }; - validateMigrations(migrations); - return migrations; -} -function createMigrationIds(sequenceId, versions2) { - return Object.fromEntries( - objectMapEntries(versions2).map(([key, version2]) => [key, `${sequenceId}/${version2}`]) - ); -} -function createRecordMigrationSequence(opts) { - const sequenceId = opts.sequenceId; - return createMigrationSequence({ - sequenceId, - retroactive: opts.retroactive ?? true, - sequence: opts.sequence.map( - (m2) => "id" in m2 ? { - ...m2, - scope: "record", - filter: (r2) => { - var _a3, _b2; - return r2.typeName === opts.recordType && (((_a3 = m2.filter) == null ? void 0 : _a3.call(m2, r2)) ?? true) && (((_b2 = opts.filter) == null ? void 0 : _b2.call(opts, r2)) ?? true); - } - } : m2 - ) - }); } -function sortMigrations(migrations) { - const byId = new Map(migrations.map((m2) => [m2.id, m2])); - const isProcessing = /* @__PURE__ */ new Set(); - const result = []; - function process2(m2) { - assert(!isProcessing.has(m2.id), `Circular dependency in migrations: ${m2.id}`); - isProcessing.add(m2.id); - const { version: version2, sequenceId } = parseMigrationId(m2.id); - const parent = byId.get(`${sequenceId}/${version2 - 1}`); - if (parent) { - process2(parent); - } - if (m2.dependsOn) { - for (const dep of m2.dependsOn) { - const depMigration = byId.get(dep); - if (depMigration) { - process2(depMigration); - } +function DashedOutlineBox({ bounds, className }) { + const editor = useEditor(); + const zoomLevel = useValue("zoom level", () => editor.getZoomLevel(), [editor]); + return /* @__PURE__ */ jsxRuntimeExports.jsx("g", { className, pointerEvents: "none", strokeLinecap: "round", strokeLinejoin: "round", children: bounds.sides.map((side, i2) => { + const { strokeDasharray, strokeDashoffset } = getPerfectDashProps( + side[0].dist(side[1]), + 1 / zoomLevel, + { + style: "dashed", + lengthRatio: 4 } - } - byId.delete(m2.id); - result.push(m2); + ); + return /* @__PURE__ */ jsxRuntimeExports.jsx( + "line", + { + x1: side[0].x, + y1: side[0].y, + x2: side[1].x, + y2: side[1].y, + strokeDasharray, + strokeDashoffset + }, + i2 + ); + }) }); +} +class GroupShapeUtil extends ShapeUtil { + hideSelectionBoundsFg() { + return true; } - for (const m2 of byId.values()) { - process2(m2); + canBind() { + return false; } - return result; -} -function parseMigrationId(id2) { - const [sequenceId, version2] = id2.split("/"); - return { sequenceId, version: parseInt(version2) }; -} -function validateMigrationId(id2, expectedSequenceId) { - if (expectedSequenceId) { - assert( - id2.startsWith(expectedSequenceId + "/"), - `Every migration in sequence '${expectedSequenceId}' must have an id starting with '${expectedSequenceId}/'. Got invalid id: '${id2}'` - ); + getDefaultProps() { + return {}; } - assert(id2.match(/^(.*?)\/(0|[1-9]\d*)$/), `Invalid migration id: '${id2}'`); -} -function validateMigrations(migrations) { - assert( - !migrations.sequenceId.includes("/"), - `sequenceId cannot contain a '/', got ${migrations.sequenceId}` - ); - assert(migrations.sequenceId.length, "sequenceId must be a non-empty string"); - if (migrations.sequence.length === 0) { - return; + getGeometry(shape) { + const children = this.editor.getSortedChildIdsForParent(shape.id); + if (children.length === 0) { + return new Rectangle2d({ width: 1, height: 1, isFilled: false }); + } + return new Group2d({ + children: children.map((childId) => { + const shape2 = this.editor.getShape(childId); + const geometry = this.editor.getShapeGeometry(childId); + const points = this.editor.getShapeLocalTransform(shape2).applyToPoints(geometry.vertices); + if (geometry.isClosed) { + return new Polygon2d({ + points, + isFilled: true + }); + } + return new Polyline2d({ + points + }); + }) + }); } - validateMigrationId(migrations.sequence[0].id, migrations.sequenceId); - let n2 = parseMigrationId(migrations.sequence[0].id).version; - assert( - n2 === 1, - `Expected the first migrationId to be '${migrations.sequenceId}/1' but got '${migrations.sequence[0].id}'` - ); - for (let i2 = 1; i2 < migrations.sequence.length; i2++) { - const id2 = migrations.sequence[i2].id; - validateMigrationId(id2, migrations.sequenceId); - const m2 = parseMigrationId(id2).version; - assert( - m2 === n2 + 1, - `Migration id numbers must increase in increments of 1, expected ${migrations.sequenceId}/${n2 + 1} but got '${migrations.sequence[i2].id}'` + component(shape) { + const isErasing = this.editor.getErasingShapeIds().includes(shape.id); + const { hintingShapeIds } = this.editor.getCurrentPageState(); + const isHintingOtherGroup = hintingShapeIds.length > 0 && hintingShapeIds.some( + (id2) => id2 !== shape.id && this.editor.isShapeOfType(this.editor.getShape(id2), "group") ); - n2 = m2; - } -} -var MigrationFailureReason = /* @__PURE__ */ ((MigrationFailureReason2) => { - MigrationFailureReason2["IncompatibleSubtype"] = "incompatible-subtype"; - MigrationFailureReason2["UnknownType"] = "unknown-type"; - MigrationFailureReason2["TargetVersionTooNew"] = "target-version-too-new"; - MigrationFailureReason2["TargetVersionTooOld"] = "target-version-too-old"; - MigrationFailureReason2["MigrationError"] = "migration-error"; - MigrationFailureReason2["UnrecognizedSubtype"] = "unrecognized-subtype"; - return MigrationFailureReason2; -})(MigrationFailureReason || {}); -function upgradeSchema(schema) { - if (schema.schemaVersion > 2 || schema.schemaVersion < 1) return Result.err("Bad schema version"); - if (schema.schemaVersion === 2) return Result.ok(schema); - const result = { - schemaVersion: 2, - sequences: { - "com.tldraw.store": schema.storeVersion + const isFocused = this.editor.getCurrentPageState().focusedGroupId !== shape.id; + if (!isErasing && // always show the outline while we're erasing the group + // show the outline while the group is focused unless something outside of the group is being hinted + // this happens dropping shapes from a group onto some outside group + (isFocused || isHintingOtherGroup)) { + return null; } - }; - for (const [typeName, recordVersion] of Object.entries(schema.recordVersions)) { - result.sequences[`com.tldraw.${typeName}`] = recordVersion.version; - if ("subTypeKey" in recordVersion) { - for (const [subType, version2] of Object.entries(recordVersion.subTypeVersions)) { - result.sequences[`com.tldraw.${typeName}.${subType}`] = version2; + const bounds = this.editor.getShapeGeometry(shape).bounds; + return /* @__PURE__ */ jsxRuntimeExports.jsx(SVGContainer, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(DashedOutlineBox, { className: "tl-group", bounds }) }); + } + indicator(shape) { + const bounds = this.editor.getShapeGeometry(shape).bounds; + return /* @__PURE__ */ jsxRuntimeExports.jsx(DashedOutlineBox, { className: "", bounds }); + } + onChildrenChange(group) { + const children = this.editor.getSortedChildIdsForParent(group.id); + if (children.length === 0) { + if (this.editor.getCurrentPageState().focusedGroupId === group.id) { + this.editor.popFocusedGroupId(); } + this.editor.deleteShapes([group.id]); + return; + } else if (children.length === 1) { + if (this.editor.getCurrentPageState().focusedGroupId === group.id) { + this.editor.popFocusedGroupId(); + } + this.editor.reparentShapes(children, group.parentId); + this.editor.deleteShapes([group.id]); + return; } } - return Result.ok(result); } -class StoreSchema { - constructor(types, options) { - __publicField(this, "migrations", {}); - __publicField(this, "sortedMigrations"); - var _a3; - this.types = types; - this.options = options; - for (const m2 of options.migrations ?? []) { - assert(!this.migrations[m2.sequenceId], `Duplicate migration sequenceId ${m2.sequenceId}`); - validateMigrations(m2); - this.migrations[m2.sequenceId] = m2; +__publicField(GroupShapeUtil, "type", "group"); +__publicField(GroupShapeUtil, "props", groupShapeProps); +__publicField(GroupShapeUtil, "migrations", groupShapeMigrations); +const coreShapes = [ + // created by grouping interactions, probably the corest core shape that we have + GroupShapeUtil +]; +const coreShapeTypes = new Set(coreShapes.map((s2) => s2.type)); +function checkShapesAndAddCore(customShapes) { + const shapes = [...coreShapes]; + const addedCustomShapeTypes = /* @__PURE__ */ new Set(); + for (const customShape of customShapes) { + if (coreShapeTypes.has(customShape.type)) { + throw new Error( + `Shape type "${customShape.type}" is a core shapes type and cannot be overridden` + ); } - const allMigrations = Object.values(this.migrations).flatMap((m2) => m2.sequence); - this.sortedMigrations = sortMigrations(allMigrations); - for (const migration of this.sortedMigrations) { - if (!((_a3 = migration.dependsOn) == null ? void 0 : _a3.length)) continue; - for (const dep of migration.dependsOn) { - const depMigration = allMigrations.find((m2) => m2.id === dep); - assert(depMigration, `Migration '${migration.id}' depends on missing migration '${dep}'`); - } + if (addedCustomShapeTypes.has(customShape.type)) { + throw new Error(`Shape type "${customShape.type}" is defined more than once`); } + shapes.push(customShape); + addedCustomShapeTypes.add(customShape.type); } - static create(types, options) { - return new StoreSchema(types, options ?? {}); - } - validateRecord(store, record, phase, recordBefore) { - try { - const recordType = getOwnProperty(this.types, record.typeName); - if (!recordType) { - throw new Error(`Missing definition for record type ${record.typeName}`); + return shapes; +} +var reactDom = { exports: {} }; +var reactDom_development = {}; +var scheduler = { exports: {} }; +var scheduler_development = {}; +(function(exports) { + /** + * @license React + * scheduler.development.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + { + (function() { + if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart === "function") { + __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error()); + } + var enableSchedulerDebugging = false; + var enableProfiling = false; + var frameYieldMs = 5; + function push2(heap, node) { + var index2 = heap.length; + heap.push(node); + siftUp(heap, node, index2); + } + function peek(heap) { + return heap.length === 0 ? null : heap[0]; + } + function pop(heap) { + if (heap.length === 0) { + return null; + } + var first = heap[0]; + var last2 = heap.pop(); + if (last2 !== first) { + heap[0] = last2; + siftDown(heap, last2, 0); + } + return first; + } + function siftUp(heap, node, i2) { + var index2 = i2; + while (index2 > 0) { + var parentIndex = index2 - 1 >>> 1; + var parent = heap[parentIndex]; + if (compare(parent, node) > 0) { + heap[parentIndex] = node; + heap[index2] = parent; + index2 = parentIndex; + } else { + return; + } + } } - return recordType.validate(record, recordBefore ?? void 0); - } catch (error) { - if (this.options.onValidationFailure) { - return this.options.onValidationFailure({ - store, - record, - phase, - recordBefore, - error - }); + function siftDown(heap, node, i2) { + var index2 = i2; + var length = heap.length; + var halfLength = length >>> 1; + while (index2 < halfLength) { + var leftIndex = (index2 + 1) * 2 - 1; + var left = heap[leftIndex]; + var rightIndex = leftIndex + 1; + var right = heap[rightIndex]; + if (compare(left, node) < 0) { + if (rightIndex < length && compare(right, left) < 0) { + heap[index2] = right; + heap[rightIndex] = node; + index2 = rightIndex; + } else { + heap[index2] = left; + heap[leftIndex] = node; + index2 = leftIndex; + } + } else if (rightIndex < length && compare(right, node) < 0) { + heap[index2] = right; + heap[rightIndex] = node; + index2 = rightIndex; + } else { + return; + } + } + } + function compare(a2, b2) { + var diff = a2.sortIndex - b2.sortIndex; + return diff !== 0 ? diff : a2.id - b2.id; + } + var ImmediatePriority = 1; + var UserBlockingPriority = 2; + var NormalPriority = 3; + var LowPriority = 4; + var IdlePriority = 5; + function markTaskErrored(task, ms) { + } + var hasPerformanceNow = typeof performance === "object" && typeof performance.now === "function"; + if (hasPerformanceNow) { + var localPerformance = performance; + exports.unstable_now = function() { + return localPerformance.now(); + }; } else { - throw error; + var localDate = Date; + var initialTime = localDate.now(); + exports.unstable_now = function() { + return localDate.now() - initialTime; + }; } - } + var maxSigned31BitInt = 1073741823; + var IMMEDIATE_PRIORITY_TIMEOUT = -1; + var USER_BLOCKING_PRIORITY_TIMEOUT = 250; + var NORMAL_PRIORITY_TIMEOUT = 5e3; + var LOW_PRIORITY_TIMEOUT = 1e4; + var IDLE_PRIORITY_TIMEOUT = maxSigned31BitInt; + var taskQueue = []; + var timerQueue = []; + var taskIdCounter = 1; + var currentTask = null; + var currentPriorityLevel = NormalPriority; + var isPerformingWork = false; + var isHostCallbackScheduled = false; + var isHostTimeoutScheduled = false; + var localSetTimeout = typeof setTimeout === "function" ? setTimeout : null; + var localClearTimeout = typeof clearTimeout === "function" ? clearTimeout : null; + var localSetImmediate = typeof setImmediate !== "undefined" ? setImmediate : null; + typeof navigator !== "undefined" && navigator.scheduling !== void 0 && navigator.scheduling.isInputPending !== void 0 ? navigator.scheduling.isInputPending.bind(navigator.scheduling) : null; + function advanceTimers(currentTime) { + var timer = peek(timerQueue); + while (timer !== null) { + if (timer.callback === null) { + pop(timerQueue); + } else if (timer.startTime <= currentTime) { + pop(timerQueue); + timer.sortIndex = timer.expirationTime; + push2(taskQueue, timer); + } else { + return; + } + timer = peek(timerQueue); + } + } + function handleTimeout(currentTime) { + isHostTimeoutScheduled = false; + advanceTimers(currentTime); + if (!isHostCallbackScheduled) { + if (peek(taskQueue) !== null) { + isHostCallbackScheduled = true; + requestHostCallback(flushWork); + } else { + var firstTimer = peek(timerQueue); + if (firstTimer !== null) { + requestHostTimeout(handleTimeout, firstTimer.startTime - currentTime); + } + } + } + } + function flushWork(hasTimeRemaining, initialTime2) { + isHostCallbackScheduled = false; + if (isHostTimeoutScheduled) { + isHostTimeoutScheduled = false; + cancelHostTimeout(); + } + isPerformingWork = true; + var previousPriorityLevel = currentPriorityLevel; + try { + var currentTime; + if (enableProfiling) ; + else { + return workLoop(hasTimeRemaining, initialTime2); + } + } finally { + currentTask = null; + currentPriorityLevel = previousPriorityLevel; + isPerformingWork = false; + } + } + function workLoop(hasTimeRemaining, initialTime2) { + var currentTime = initialTime2; + advanceTimers(currentTime); + currentTask = peek(taskQueue); + while (currentTask !== null && !enableSchedulerDebugging) { + if (currentTask.expirationTime > currentTime && (!hasTimeRemaining || shouldYieldToHost())) { + break; + } + var callback = currentTask.callback; + if (typeof callback === "function") { + currentTask.callback = null; + currentPriorityLevel = currentTask.priorityLevel; + var didUserCallbackTimeout = currentTask.expirationTime <= currentTime; + var continuationCallback = callback(didUserCallbackTimeout); + currentTime = exports.unstable_now(); + if (typeof continuationCallback === "function") { + currentTask.callback = continuationCallback; + } else { + if (currentTask === peek(taskQueue)) { + pop(taskQueue); + } + } + advanceTimers(currentTime); + } else { + pop(taskQueue); + } + currentTask = peek(taskQueue); + } + if (currentTask !== null) { + return true; + } else { + var firstTimer = peek(timerQueue); + if (firstTimer !== null) { + requestHostTimeout(handleTimeout, firstTimer.startTime - currentTime); + } + return false; + } + } + function unstable_runWithPriority(priorityLevel, eventHandler2) { + switch (priorityLevel) { + case ImmediatePriority: + case UserBlockingPriority: + case NormalPriority: + case LowPriority: + case IdlePriority: + break; + default: + priorityLevel = NormalPriority; + } + var previousPriorityLevel = currentPriorityLevel; + currentPriorityLevel = priorityLevel; + try { + return eventHandler2(); + } finally { + currentPriorityLevel = previousPriorityLevel; + } + } + function unstable_next(eventHandler2) { + var priorityLevel; + switch (currentPriorityLevel) { + case ImmediatePriority: + case UserBlockingPriority: + case NormalPriority: + priorityLevel = NormalPriority; + break; + default: + priorityLevel = currentPriorityLevel; + break; + } + var previousPriorityLevel = currentPriorityLevel; + currentPriorityLevel = priorityLevel; + try { + return eventHandler2(); + } finally { + currentPriorityLevel = previousPriorityLevel; + } + } + function unstable_wrapCallback(callback) { + var parentPriorityLevel = currentPriorityLevel; + return function() { + var previousPriorityLevel = currentPriorityLevel; + currentPriorityLevel = parentPriorityLevel; + try { + return callback.apply(this, arguments); + } finally { + currentPriorityLevel = previousPriorityLevel; + } + }; + } + function unstable_scheduleCallback(priorityLevel, callback, options) { + var currentTime = exports.unstable_now(); + var startTime2; + if (typeof options === "object" && options !== null) { + var delay = options.delay; + if (typeof delay === "number" && delay > 0) { + startTime2 = currentTime + delay; + } else { + startTime2 = currentTime; + } + } else { + startTime2 = currentTime; + } + var timeout; + switch (priorityLevel) { + case ImmediatePriority: + timeout = IMMEDIATE_PRIORITY_TIMEOUT; + break; + case UserBlockingPriority: + timeout = USER_BLOCKING_PRIORITY_TIMEOUT; + break; + case IdlePriority: + timeout = IDLE_PRIORITY_TIMEOUT; + break; + case LowPriority: + timeout = LOW_PRIORITY_TIMEOUT; + break; + case NormalPriority: + default: + timeout = NORMAL_PRIORITY_TIMEOUT; + break; + } + var expirationTime = startTime2 + timeout; + var newTask = { + id: taskIdCounter++, + callback, + priorityLevel, + startTime: startTime2, + expirationTime, + sortIndex: -1 + }; + if (startTime2 > currentTime) { + newTask.sortIndex = startTime2; + push2(timerQueue, newTask); + if (peek(taskQueue) === null && newTask === peek(timerQueue)) { + if (isHostTimeoutScheduled) { + cancelHostTimeout(); + } else { + isHostTimeoutScheduled = true; + } + requestHostTimeout(handleTimeout, startTime2 - currentTime); + } + } else { + newTask.sortIndex = expirationTime; + push2(taskQueue, newTask); + if (!isHostCallbackScheduled && !isPerformingWork) { + isHostCallbackScheduled = true; + requestHostCallback(flushWork); + } + } + return newTask; + } + function unstable_pauseExecution() { + } + function unstable_continueExecution() { + if (!isHostCallbackScheduled && !isPerformingWork) { + isHostCallbackScheduled = true; + requestHostCallback(flushWork); + } + } + function unstable_getFirstCallbackNode() { + return peek(taskQueue); + } + function unstable_cancelCallback(task) { + task.callback = null; + } + function unstable_getCurrentPriorityLevel() { + return currentPriorityLevel; + } + var isMessageLoopRunning = false; + var scheduledHostCallback = null; + var taskTimeoutID = -1; + var frameInterval = frameYieldMs; + var startTime = -1; + function shouldYieldToHost() { + var timeElapsed = exports.unstable_now() - startTime; + if (timeElapsed < frameInterval) { + return false; + } + return true; + } + function requestPaint() { + } + function forceFrameRate(fps) { + if (fps < 0 || fps > 125) { + console["error"]("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported"); + return; + } + if (fps > 0) { + frameInterval = Math.floor(1e3 / fps); + } else { + frameInterval = frameYieldMs; + } + } + var performWorkUntilDeadline = function() { + if (scheduledHostCallback !== null) { + var currentTime = exports.unstable_now(); + startTime = currentTime; + var hasTimeRemaining = true; + var hasMoreWork = true; + try { + hasMoreWork = scheduledHostCallback(hasTimeRemaining, currentTime); + } finally { + if (hasMoreWork) { + schedulePerformWorkUntilDeadline(); + } else { + isMessageLoopRunning = false; + scheduledHostCallback = null; + } + } + } else { + isMessageLoopRunning = false; + } + }; + var schedulePerformWorkUntilDeadline; + if (typeof localSetImmediate === "function") { + schedulePerformWorkUntilDeadline = function() { + localSetImmediate(performWorkUntilDeadline); + }; + } else if (typeof MessageChannel !== "undefined") { + var channel2 = new MessageChannel(); + var port = channel2.port2; + channel2.port1.onmessage = performWorkUntilDeadline; + schedulePerformWorkUntilDeadline = function() { + port.postMessage(null); + }; + } else { + schedulePerformWorkUntilDeadline = function() { + localSetTimeout(performWorkUntilDeadline, 0); + }; + } + function requestHostCallback(callback) { + scheduledHostCallback = callback; + if (!isMessageLoopRunning) { + isMessageLoopRunning = true; + schedulePerformWorkUntilDeadline(); + } + } + function requestHostTimeout(callback, ms) { + taskTimeoutID = localSetTimeout(function() { + callback(exports.unstable_now()); + }, ms); + } + function cancelHostTimeout() { + localClearTimeout(taskTimeoutID); + taskTimeoutID = -1; + } + var unstable_requestPaint = requestPaint; + var unstable_Profiling = null; + exports.unstable_IdlePriority = IdlePriority; + exports.unstable_ImmediatePriority = ImmediatePriority; + exports.unstable_LowPriority = LowPriority; + exports.unstable_NormalPriority = NormalPriority; + exports.unstable_Profiling = unstable_Profiling; + exports.unstable_UserBlockingPriority = UserBlockingPriority; + exports.unstable_cancelCallback = unstable_cancelCallback; + exports.unstable_continueExecution = unstable_continueExecution; + exports.unstable_forceFrameRate = forceFrameRate; + exports.unstable_getCurrentPriorityLevel = unstable_getCurrentPriorityLevel; + exports.unstable_getFirstCallbackNode = unstable_getFirstCallbackNode; + exports.unstable_next = unstable_next; + exports.unstable_pauseExecution = unstable_pauseExecution; + exports.unstable_requestPaint = unstable_requestPaint; + exports.unstable_runWithPriority = unstable_runWithPriority; + exports.unstable_scheduleCallback = unstable_scheduleCallback; + exports.unstable_shouldYield = shouldYieldToHost; + exports.unstable_wrapCallback = unstable_wrapCallback; + if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop === "function") { + __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error()); + } + })(); } - // TODO: use a weakmap to store the result of this function - getMigrationsSince(persistedSchema) { - const upgradeResult = upgradeSchema(persistedSchema); - if (!upgradeResult.ok) { - return upgradeResult; +})(scheduler_development); +{ + scheduler.exports = scheduler_development; +} +var schedulerExports = scheduler.exports; +/** + * @license React + * react-dom.development.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +{ + (function() { + if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart === "function") { + __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error()); + } + var React2 = reactExports; + var Scheduler = schedulerExports; + var ReactSharedInternals = React2.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; + var suppressWarning = false; + function setSuppressWarning(newSuppressWarning) { + { + suppressWarning = newSuppressWarning; + } } - const schema = upgradeResult.value; - const sequenceIdsToInclude = new Set( - // start with any shared sequences - Object.keys(schema.sequences).filter((sequenceId) => this.migrations[sequenceId]) - ); - for (const sequenceId in this.migrations) { - if (schema.sequences[sequenceId] === void 0 && this.migrations[sequenceId].retroactive) { - sequenceIdsToInclude.add(sequenceId); + function warn(format2) { + { + if (!suppressWarning) { + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + printWarning("warn", format2, args); + } } } - if (sequenceIdsToInclude.size === 0) { - return Result.ok([]); + function error(format2) { + { + if (!suppressWarning) { + for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + args[_key2 - 1] = arguments[_key2]; + } + printWarning("error", format2, args); + } + } } - const allMigrationsToInclude = /* @__PURE__ */ new Set(); - for (const sequenceId of sequenceIdsToInclude) { - const theirVersion = schema.sequences[sequenceId]; - if (typeof theirVersion !== "number" && this.migrations[sequenceId].retroactive || theirVersion === 0) { - for (const migration of this.migrations[sequenceId].sequence) { - allMigrationsToInclude.add(migration.id); + function printWarning(level, format2, args) { + { + var ReactDebugCurrentFrame2 = ReactSharedInternals.ReactDebugCurrentFrame; + var stack2 = ReactDebugCurrentFrame2.getStackAddendum(); + if (stack2 !== "") { + format2 += "%s"; + args = args.concat([stack2]); + } + var argsWithFormat = args.map(function(item) { + return String(item); + }); + argsWithFormat.unshift("Warning: " + format2); + Function.prototype.apply.call(console[level], console, argsWithFormat); + } + } + var FunctionComponent = 0; + var ClassComponent = 1; + var IndeterminateComponent = 2; + var HostRoot = 3; + var HostPortal = 4; + var HostComponent = 5; + var HostText = 6; + var Fragment = 7; + var Mode = 8; + var ContextConsumer = 9; + var ContextProvider = 10; + var ForwardRef = 11; + var Profiler = 12; + var SuspenseComponent = 13; + var MemoComponent = 14; + var SimpleMemoComponent = 15; + var LazyComponent = 16; + var IncompleteClassComponent = 17; + var DehydratedFragment = 18; + var SuspenseListComponent = 19; + var ScopeComponent = 21; + var OffscreenComponent = 22; + var LegacyHiddenComponent = 23; + var CacheComponent = 24; + var TracingMarkerComponent = 25; + var enableClientRenderFallbackOnTextMismatch = true; + var enableNewReconciler = false; + var enableLazyContextPropagation = false; + var enableLegacyHidden = false; + var enableSuspenseAvoidThisFallback = false; + var disableCommentsAsDOMContainers = true; + var enableCustomElementPropertySupport = false; + var warnAboutStringRefs = true; + var enableSchedulingProfiler = true; + var enableProfilerTimer = true; + var enableProfilerCommitHooks = true; + var allNativeEvents = /* @__PURE__ */ new Set(); + var registrationNameDependencies = {}; + var possibleRegistrationNames = {}; + function registerTwoPhaseEvent(registrationName, dependencies) { + registerDirectEvent(registrationName, dependencies); + registerDirectEvent(registrationName + "Capture", dependencies); + } + function registerDirectEvent(registrationName, dependencies) { + { + if (registrationNameDependencies[registrationName]) { + error("EventRegistry: More than one plugin attempted to publish the same registration name, `%s`.", registrationName); } - continue; } - const theirVersionId = `${sequenceId}/${theirVersion}`; - const idx = this.migrations[sequenceId].sequence.findIndex((m2) => m2.id === theirVersionId); - if (idx === -1) { - return Result.err("Incompatible schema?"); + registrationNameDependencies[registrationName] = dependencies; + { + var lowerCasedName = registrationName.toLowerCase(); + possibleRegistrationNames[lowerCasedName] = registrationName; + if (registrationName === "onDoubleClick") { + possibleRegistrationNames.ondblclick = registrationName; + } } - for (const migration of this.migrations[sequenceId].sequence.slice(idx + 1)) { - allMigrationsToInclude.add(migration.id); + for (var i2 = 0; i2 < dependencies.length; i2++) { + allNativeEvents.add(dependencies[i2]); } } - return Result.ok(this.sortedMigrations.filter(({ id: id2 }) => allMigrationsToInclude.has(id2))); - } - migratePersistedRecord(record, persistedSchema, direction = "up") { - const migrations = this.getMigrationsSince(persistedSchema); - if (!migrations.ok) { - console.error("Error migrating record", migrations.error); - return { type: "error", reason: MigrationFailureReason.MigrationError }; - } - let migrationsToApply = migrations.value; - if (migrationsToApply.length === 0) { - return { type: "success", value: record }; - } - if (migrationsToApply.some((m2) => m2.scope === "store")) { - return { - type: "error", - reason: direction === "down" ? MigrationFailureReason.TargetVersionTooOld : MigrationFailureReason.TargetVersionTooNew - }; - } - if (direction === "down") { - if (!migrationsToApply.every((m2) => m2.down)) { - return { - type: "error", - reason: MigrationFailureReason.TargetVersionTooOld - }; + var canUseDOM = !!(typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined"); + var hasOwnProperty2 = Object.prototype.hasOwnProperty; + function typeName(value) { + { + var hasToStringTag = typeof Symbol === "function" && Symbol.toStringTag; + var type = hasToStringTag && value[Symbol.toStringTag] || value.constructor.name || "Object"; + return type; } - migrationsToApply = migrationsToApply.slice().reverse(); } - record = structuredClone(record); - try { - for (const migration of migrationsToApply) { - if (migration.scope === "store") throw new Error( - /* won't happen, just for TS */ - ); - const shouldApply = migration.filter ? migration.filter(record) : true; - if (!shouldApply) continue; - const result = migration[direction](record); - if (result) { - record = structuredClone(result); + function willCoercionThrow(value) { + { + try { + testStringCoercion(value); + return false; + } catch (e2) { + return true; } } - } catch (e2) { - console.error("Error migrating record", e2); - return { type: "error", reason: MigrationFailureReason.MigrationError }; - } - return { type: "success", value: record }; - } - migrateStoreSnapshot(snapshot) { - let { store } = snapshot; - const migrations = this.getMigrationsSince(snapshot.schema); - if (!migrations.ok) { - console.error("Error migrating store", migrations.error); - return { type: "error", reason: MigrationFailureReason.MigrationError }; } - const migrationsToApply = migrations.value; - if (migrationsToApply.length === 0) { - return { type: "success", value: store }; + function testStringCoercion(value) { + return "" + value; } - store = structuredClone(store); - try { - for (const migration of migrationsToApply) { - if (migration.scope === "record") { - for (const [id2, record] of Object.entries(store)) { - const shouldApply = migration.filter ? migration.filter(record) : true; - if (!shouldApply) continue; - const result = migration.up(record); - if (result) { - store[id2] = structuredClone(result); - } - } - } else if (migration.scope === "store") { - const result = migration.up(store); - if (result) { - store = structuredClone(result); - } - } else { - exhaustiveSwitchError(migration); + function checkAttributeStringCoercion(value, attributeName) { + { + if (willCoercionThrow(value)) { + error("The provided `%s` attribute is an unsupported type %s. This value must be coerced to a string before before using it here.", attributeName, typeName(value)); + return testStringCoercion(value); } } - } catch (e2) { - console.error("Error migrating store", e2); - return { type: "error", reason: MigrationFailureReason.MigrationError }; } - return { type: "success", value: store }; - } - /** @internal */ - createIntegrityChecker(store) { - var _a3, _b2; - return ((_b2 = (_a3 = this.options).createIntegrityChecker) == null ? void 0 : _b2.call(_a3, store)) ?? void 0; - } - serialize() { - return { - schemaVersion: 2, - sequences: Object.fromEntries( - Object.values(this.migrations).map(({ sequenceId, sequence }) => [ - sequenceId, - sequence.length ? parseMigrationId(sequence.at(-1).id).version : 0 - ]) - ) - }; - } - /** - * @deprecated This is only here for legacy reasons, don't use it unless you have david's blessing! - */ - serializeEarliestVersion() { - return { - schemaVersion: 2, - sequences: Object.fromEntries( - Object.values(this.migrations).map(({ sequenceId }) => [sequenceId, 0]) - ) - }; - } - /** @internal */ - getType(typeName) { - const type = getOwnProperty(this.types, typeName); - assert(type, "record type does not exists"); - return type; - } -} -registerTldrawLibraryVersion( - "@tldraw/store", - "3.4.1", - "esm" -); -function formatPath(path) { - if (!path.length) { - return null; - } - let formattedPath = ""; - for (const item of path) { - if (typeof item === "number") { - formattedPath += `.${item}`; - } else if (item.startsWith("(")) { - if (formattedPath.endsWith(")")) { - formattedPath = `${formattedPath.slice(0, -1)}, ${item.slice(1)}`; - } else { - formattedPath += item; + function checkKeyStringCoercion(value) { + { + if (willCoercionThrow(value)) { + error("The provided key is an unsupported type %s. This value must be coerced to a string before before using it here.", typeName(value)); + return testStringCoercion(value); + } } - } else { - formattedPath += `.${item}`; } - } - formattedPath = formattedPath.replace(/id = [^,]+, /, "").replace(/id = [^)]+/, ""); - if (formattedPath.startsWith(".")) { - return formattedPath.slice(1); - } - return formattedPath; -} -class ValidationError extends Error { - constructor(rawMessage, path = []) { - const formattedPath = formatPath(path); - const indentedMessage = rawMessage.split("\n").map((line, i2) => i2 === 0 ? line : ` ${line}`).join("\n"); - super(path ? `At ${formattedPath}: ${indentedMessage}` : indentedMessage); - __publicField(this, "name", "ValidationError"); - this.rawMessage = rawMessage; - this.path = path; - } -} -function prefixError(path, fn) { - try { - return fn(); - } catch (err) { - if (err instanceof ValidationError) { - throw new ValidationError(err.rawMessage, [path, ...err.path]); + function checkPropStringCoercion(value, propName) { + { + if (willCoercionThrow(value)) { + error("The provided `%s` prop is an unsupported type %s. This value must be coerced to a string before before using it here.", propName, typeName(value)); + return testStringCoercion(value); + } + } } - throw new ValidationError(err.toString(), [path]); - } -} -function typeToString(value) { - if (value === null) return "null"; - if (Array.isArray(value)) return "an array"; - const type = typeof value; - switch (type) { - case "bigint": - case "boolean": - case "function": - case "number": - case "string": - case "symbol": - return `a ${type}`; - case "object": - return `an ${type}`; - case "undefined": - return "undefined"; - default: - exhaustiveSwitchError(type); - } -} -class Validator { - constructor(validationFn, validateUsingKnownGoodVersionFn) { - this.validationFn = validationFn; - this.validateUsingKnownGoodVersionFn = validateUsingKnownGoodVersionFn; - } - /** - * Asserts that the passed value is of the correct type and returns it. The returned value is - * guaranteed to be referentially equal to the passed value. - */ - validate(value) { - const validated = this.validationFn(value); - return validated; - } - validateUsingKnownGoodVersion(knownGoodValue, newValue) { - if (Object.is(knownGoodValue, newValue)) { - return knownGoodValue; + function checkCSSPropertyStringCoercion(value, propName) { + { + if (willCoercionThrow(value)) { + error("The provided `%s` CSS property is an unsupported type %s. This value must be coerced to a string before before using it here.", propName, typeName(value)); + return testStringCoercion(value); + } + } } - if (this.validateUsingKnownGoodVersionFn) { - return this.validateUsingKnownGoodVersionFn(knownGoodValue, newValue); + function checkHtmlStringCoercion(value) { + { + if (willCoercionThrow(value)) { + error("The provided HTML markup uses a value of unsupported type %s. This value must be coerced to a string before before using it here.", typeName(value)); + return testStringCoercion(value); + } + } } - return this.validate(newValue); - } - /** Checks that the passed value is of the correct type. */ - isValid(value) { - try { - this.validate(value); - return true; - } catch { + function checkFormFieldValueStringCoercion(value) { + { + if (willCoercionThrow(value)) { + error("Form field values (value, checked, defaultValue, or defaultChecked props) must be strings, not %s. This value must be coerced to a string before before using it here.", typeName(value)); + return testStringCoercion(value); + } + } + } + var RESERVED = 0; + var STRING = 1; + var BOOLEANISH_STRING = 2; + var BOOLEAN = 3; + var OVERLOADED_BOOLEAN = 4; + var NUMERIC = 5; + var POSITIVE_NUMERIC = 6; + var ATTRIBUTE_NAME_START_CHAR = ":A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD"; + var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + "\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040"; + var VALID_ATTRIBUTE_NAME_REGEX = new RegExp("^[" + ATTRIBUTE_NAME_START_CHAR + "][" + ATTRIBUTE_NAME_CHAR + "]*$"); + var illegalAttributeNameCache = {}; + var validatedAttributeNameCache = {}; + function isAttributeNameSafe(attributeName) { + if (hasOwnProperty2.call(validatedAttributeNameCache, attributeName)) { + return true; + } + if (hasOwnProperty2.call(illegalAttributeNameCache, attributeName)) { + return false; + } + if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) { + validatedAttributeNameCache[attributeName] = true; + return true; + } + illegalAttributeNameCache[attributeName] = true; + { + error("Invalid attribute name: `%s`", attributeName); + } return false; } - } - /** - * Returns a new validator that also accepts null or undefined. The resulting value will always be - * null. - */ - nullable() { - return nullable(this); - } - /** - * Returns a new validator that also accepts null or undefined. The resulting value will always be - * null. - */ - optional() { - return optional(this); - } - /** - * Refine this validation to a new type. The passed-in validation function should throw an error - * if the value can't be converted to the new type, or return the new type otherwise. - */ - refine(otherValidationFn) { - return new Validator( - (value) => { - return otherValidationFn(this.validate(value)); - }, - (knownGoodValue, newValue) => { - const validated = this.validateUsingKnownGoodVersion(knownGoodValue, newValue); - if (Object.is(knownGoodValue, validated)) { - return knownGoodValue; - } - return otherValidationFn(validated); + function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) { + if (propertyInfo !== null) { + return propertyInfo.type === RESERVED; } - ); - } - check(nameOrCheckFn, checkFn) { - if (typeof nameOrCheckFn === "string") { - return this.refine((value) => { - prefixError(`(check ${nameOrCheckFn})`, () => checkFn(value)); - return value; - }); - } else { - return this.refine((value) => { - nameOrCheckFn(value); - return value; - }); + if (isCustomComponentTag) { + return false; + } + if (name.length > 2 && (name[0] === "o" || name[0] === "O") && (name[1] === "n" || name[1] === "N")) { + return true; + } + return false; } - } -} -class ArrayOfValidator extends Validator { - constructor(itemValidator) { - super( - (value) => { - const arr = array.validate(value); - for (let i2 = 0; i2 < arr.length; i2++) { - prefixError(i2, () => itemValidator.validate(arr[i2])); - } - return arr; - }, - (knownGoodValue, newValue) => { - if (!itemValidator.validateUsingKnownGoodVersion) return this.validate(newValue); - const arr = array.validate(newValue); - let isDifferent = knownGoodValue.length !== arr.length; - for (let i2 = 0; i2 < arr.length; i2++) { - const item = arr[i2]; - if (i2 >= knownGoodValue.length) { - isDifferent = true; - prefixError(i2, () => itemValidator.validate(item)); - continue; - } - if (Object.is(knownGoodValue[i2], item)) { - continue; + function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) { + if (propertyInfo !== null && propertyInfo.type === RESERVED) { + return false; + } + switch (typeof value) { + case "function": + case "symbol": + return true; + case "boolean": { + if (isCustomComponentTag) { + return false; } - const checkedItem = prefixError( - i2, - () => itemValidator.validateUsingKnownGoodVersion(knownGoodValue[i2], item) - ); - if (!Object.is(checkedItem, knownGoodValue[i2])) { - isDifferent = true; + if (propertyInfo !== null) { + return !propertyInfo.acceptsBooleans; + } else { + var prefix2 = name.toLowerCase().slice(0, 5); + return prefix2 !== "data-" && prefix2 !== "aria-"; } } - return isDifferent ? newValue : knownGoodValue; + default: + return false; } - ); - this.itemValidator = itemValidator; - } - nonEmpty() { - return this.check((value) => { - if (value.length === 0) { - throw new ValidationError("Expected a non-empty array"); + } + function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) { + if (value === null || typeof value === "undefined") { + return true; } - }); - } - lengthGreaterThan1() { - return this.check((value) => { - if (value.length <= 1) { - throw new ValidationError("Expected an array with length greater than 1"); + if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) { + return true; } - }); - } -} -class ObjectValidator extends Validator { - constructor(config, shouldAllowUnknownProperties = false) { - super( - (object2) => { - if (typeof object2 !== "object" || object2 === null) { - throw new ValidationError(`Expected object, got ${typeToString(object2)}`); + if (isCustomComponentTag) { + return false; + } + if (propertyInfo !== null) { + switch (propertyInfo.type) { + case BOOLEAN: + return !value; + case OVERLOADED_BOOLEAN: + return value === false; + case NUMERIC: + return isNaN(value); + case POSITIVE_NUMERIC: + return isNaN(value) || value < 1; } - for (const [key, validator] of Object.entries(config)) { - prefixError(key, () => { - ; - validator.validate(getOwnProperty(object2, key)); - }); + } + return false; + } + function getPropertyInfo(name) { + return properties.hasOwnProperty(name) ? properties[name] : null; + } + function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace, sanitizeURL2, removeEmptyString) { + this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN; + this.attributeName = attributeName; + this.attributeNamespace = attributeNamespace; + this.mustUseProperty = mustUseProperty; + this.propertyName = name; + this.type = type; + this.sanitizeURL = sanitizeURL2; + this.removeEmptyString = removeEmptyString; + } + var properties = {}; + var reservedProps = [ + "children", + "dangerouslySetInnerHTML", + // TODO: This prevents the assignment of defaultValue to regular + // elements (not just inputs). Now that ReactDOMInput assigns to the + // defaultValue property -- do we need this? + "defaultValue", + "defaultChecked", + "innerHTML", + "suppressContentEditableWarning", + "suppressHydrationWarning", + "style" + ]; + reservedProps.forEach(function(name) { + properties[name] = new PropertyInfoRecord( + name, + RESERVED, + false, + // mustUseProperty + name, + // attributeName + null, + // attributeNamespace + false, + // sanitizeURL + false + ); + }); + [["acceptCharset", "accept-charset"], ["className", "class"], ["htmlFor", "for"], ["httpEquiv", "http-equiv"]].forEach(function(_ref) { + var name = _ref[0], attributeName = _ref[1]; + properties[name] = new PropertyInfoRecord( + name, + STRING, + false, + // mustUseProperty + attributeName, + // attributeName + null, + // attributeNamespace + false, + // sanitizeURL + false + ); + }); + ["contentEditable", "draggable", "spellCheck", "value"].forEach(function(name) { + properties[name] = new PropertyInfoRecord( + name, + BOOLEANISH_STRING, + false, + // mustUseProperty + name.toLowerCase(), + // attributeName + null, + // attributeNamespace + false, + // sanitizeURL + false + ); + }); + ["autoReverse", "externalResourcesRequired", "focusable", "preserveAlpha"].forEach(function(name) { + properties[name] = new PropertyInfoRecord( + name, + BOOLEANISH_STRING, + false, + // mustUseProperty + name, + // attributeName + null, + // attributeNamespace + false, + // sanitizeURL + false + ); + }); + [ + "allowFullScreen", + "async", + // Note: there is a special case that prevents it from being written to the DOM + // on the client side because the browsers are inconsistent. Instead we call focus(). + "autoFocus", + "autoPlay", + "controls", + "default", + "defer", + "disabled", + "disablePictureInPicture", + "disableRemotePlayback", + "formNoValidate", + "hidden", + "loop", + "noModule", + "noValidate", + "open", + "playsInline", + "readOnly", + "required", + "reversed", + "scoped", + "seamless", + // Microdata + "itemScope" + ].forEach(function(name) { + properties[name] = new PropertyInfoRecord( + name, + BOOLEAN, + false, + // mustUseProperty + name.toLowerCase(), + // attributeName + null, + // attributeNamespace + false, + // sanitizeURL + false + ); + }); + [ + "checked", + // Note: `option.selected` is not updated if `select.multiple` is + // disabled with `removeAttribute`. We have special logic for handling this. + "multiple", + "muted", + "selected" + // NOTE: if you add a camelCased prop to this list, + // you'll need to set attributeName to name.toLowerCase() + // instead in the assignment below. + ].forEach(function(name) { + properties[name] = new PropertyInfoRecord( + name, + BOOLEAN, + true, + // mustUseProperty + name, + // attributeName + null, + // attributeNamespace + false, + // sanitizeURL + false + ); + }); + [ + "capture", + "download" + // NOTE: if you add a camelCased prop to this list, + // you'll need to set attributeName to name.toLowerCase() + // instead in the assignment below. + ].forEach(function(name) { + properties[name] = new PropertyInfoRecord( + name, + OVERLOADED_BOOLEAN, + false, + // mustUseProperty + name, + // attributeName + null, + // attributeNamespace + false, + // sanitizeURL + false + ); + }); + [ + "cols", + "rows", + "size", + "span" + // NOTE: if you add a camelCased prop to this list, + // you'll need to set attributeName to name.toLowerCase() + // instead in the assignment below. + ].forEach(function(name) { + properties[name] = new PropertyInfoRecord( + name, + POSITIVE_NUMERIC, + false, + // mustUseProperty + name, + // attributeName + null, + // attributeNamespace + false, + // sanitizeURL + false + ); + }); + ["rowSpan", "start"].forEach(function(name) { + properties[name] = new PropertyInfoRecord( + name, + NUMERIC, + false, + // mustUseProperty + name.toLowerCase(), + // attributeName + null, + // attributeNamespace + false, + // sanitizeURL + false + ); + }); + var CAMELIZE = /[\-\:]([a-z])/g; + var capitalize2 = function(token) { + return token[1].toUpperCase(); + }; + [ + "accent-height", + "alignment-baseline", + "arabic-form", + "baseline-shift", + "cap-height", + "clip-path", + "clip-rule", + "color-interpolation", + "color-interpolation-filters", + "color-profile", + "color-rendering", + "dominant-baseline", + "enable-background", + "fill-opacity", + "fill-rule", + "flood-color", + "flood-opacity", + "font-family", + "font-size", + "font-size-adjust", + "font-stretch", + "font-style", + "font-variant", + "font-weight", + "glyph-name", + "glyph-orientation-horizontal", + "glyph-orientation-vertical", + "horiz-adv-x", + "horiz-origin-x", + "image-rendering", + "letter-spacing", + "lighting-color", + "marker-end", + "marker-mid", + "marker-start", + "overline-position", + "overline-thickness", + "paint-order", + "panose-1", + "pointer-events", + "rendering-intent", + "shape-rendering", + "stop-color", + "stop-opacity", + "strikethrough-position", + "strikethrough-thickness", + "stroke-dasharray", + "stroke-dashoffset", + "stroke-linecap", + "stroke-linejoin", + "stroke-miterlimit", + "stroke-opacity", + "stroke-width", + "text-anchor", + "text-decoration", + "text-rendering", + "underline-position", + "underline-thickness", + "unicode-bidi", + "unicode-range", + "units-per-em", + "v-alphabetic", + "v-hanging", + "v-ideographic", + "v-mathematical", + "vector-effect", + "vert-adv-y", + "vert-origin-x", + "vert-origin-y", + "word-spacing", + "writing-mode", + "xmlns:xlink", + "x-height" + // NOTE: if you add a camelCased prop to this list, + // you'll need to set attributeName to name.toLowerCase() + // instead in the assignment below. + ].forEach(function(attributeName) { + var name = attributeName.replace(CAMELIZE, capitalize2); + properties[name] = new PropertyInfoRecord( + name, + STRING, + false, + // mustUseProperty + attributeName, + null, + // attributeNamespace + false, + // sanitizeURL + false + ); + }); + [ + "xlink:actuate", + "xlink:arcrole", + "xlink:role", + "xlink:show", + "xlink:title", + "xlink:type" + // NOTE: if you add a camelCased prop to this list, + // you'll need to set attributeName to name.toLowerCase() + // instead in the assignment below. + ].forEach(function(attributeName) { + var name = attributeName.replace(CAMELIZE, capitalize2); + properties[name] = new PropertyInfoRecord( + name, + STRING, + false, + // mustUseProperty + attributeName, + "http://www.w3.org/1999/xlink", + false, + // sanitizeURL + false + ); + }); + [ + "xml:base", + "xml:lang", + "xml:space" + // NOTE: if you add a camelCased prop to this list, + // you'll need to set attributeName to name.toLowerCase() + // instead in the assignment below. + ].forEach(function(attributeName) { + var name = attributeName.replace(CAMELIZE, capitalize2); + properties[name] = new PropertyInfoRecord( + name, + STRING, + false, + // mustUseProperty + attributeName, + "http://www.w3.org/XML/1998/namespace", + false, + // sanitizeURL + false + ); + }); + ["tabIndex", "crossOrigin"].forEach(function(attributeName) { + properties[attributeName] = new PropertyInfoRecord( + attributeName, + STRING, + false, + // mustUseProperty + attributeName.toLowerCase(), + // attributeName + null, + // attributeNamespace + false, + // sanitizeURL + false + ); + }); + var xlinkHref = "xlinkHref"; + properties[xlinkHref] = new PropertyInfoRecord( + "xlinkHref", + STRING, + false, + // mustUseProperty + "xlink:href", + "http://www.w3.org/1999/xlink", + true, + // sanitizeURL + false + ); + ["src", "href", "action", "formAction"].forEach(function(attributeName) { + properties[attributeName] = new PropertyInfoRecord( + attributeName, + STRING, + false, + // mustUseProperty + attributeName.toLowerCase(), + // attributeName + null, + // attributeNamespace + true, + // sanitizeURL + true + ); + }); + var isJavaScriptProtocol = /^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*\:/i; + var didWarn = false; + function sanitizeURL(url) { + { + if (!didWarn && isJavaScriptProtocol.test(url)) { + didWarn = true; + error("A future version of React will block javascript: URLs as a security precaution. Use event handlers instead if you can. If you need to generate unsafe HTML try using dangerouslySetInnerHTML instead. React was passed %s.", JSON.stringify(url)); } - if (!shouldAllowUnknownProperties) { - for (const key of Object.keys(object2)) { - if (!hasOwnProperty$1(config, key)) { - throw new ValidationError(`Unexpected property`, [key]); + } + } + function getValueForProperty(node, name, expected, propertyInfo) { + { + if (propertyInfo.mustUseProperty) { + var propertyName = propertyInfo.propertyName; + return node[propertyName]; + } else { + { + checkAttributeStringCoercion(expected, name); + } + if (propertyInfo.sanitizeURL) { + sanitizeURL("" + expected); + } + var attributeName = propertyInfo.attributeName; + var stringValue = null; + if (propertyInfo.type === OVERLOADED_BOOLEAN) { + if (node.hasAttribute(attributeName)) { + var value = node.getAttribute(attributeName); + if (value === "") { + return true; + } + if (shouldRemoveAttribute(name, expected, propertyInfo, false)) { + return value; + } + if (value === "" + expected) { + return expected; + } + return value; } + } else if (node.hasAttribute(attributeName)) { + if (shouldRemoveAttribute(name, expected, propertyInfo, false)) { + return node.getAttribute(attributeName); + } + if (propertyInfo.type === BOOLEAN) { + return expected; + } + stringValue = node.getAttribute(attributeName); + } + if (shouldRemoveAttribute(name, expected, propertyInfo, false)) { + return stringValue === null ? expected : stringValue; + } else if (stringValue === "" + expected) { + return expected; + } else { + return stringValue; } } - return object2; - }, - (knownGoodValue, newValue) => { - if (typeof newValue !== "object" || newValue === null) { - throw new ValidationError(`Expected object, got ${typeToString(newValue)}`); + } + } + function getValueForAttribute(node, name, expected, isCustomComponentTag) { + { + if (!isAttributeNameSafe(name)) { + return; } - let isDifferent = false; - for (const [key, validator] of Object.entries(config)) { - const prev = getOwnProperty(knownGoodValue, key); - const next = getOwnProperty(newValue, key); - if (Object.is(prev, next)) { - continue; - } - const checked = prefixError(key, () => { - const validatable = validator; - if (validatable.validateUsingKnownGoodVersion) { - return validatable.validateUsingKnownGoodVersion(prev, next); - } else { - return validatable.validate(next); + if (!node.hasAttribute(name)) { + return expected === void 0 ? void 0 : null; + } + var value = node.getAttribute(name); + { + checkAttributeStringCoercion(expected, name); + } + if (value === "" + expected) { + return expected; + } + return value; + } + } + function setValueForProperty(node, name, value, isCustomComponentTag) { + var propertyInfo = getPropertyInfo(name); + if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) { + return; + } + if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) { + value = null; + } + if (isCustomComponentTag || propertyInfo === null) { + if (isAttributeNameSafe(name)) { + var _attributeName = name; + if (value === null) { + node.removeAttribute(_attributeName); + } else { + { + checkAttributeStringCoercion(value, name); } - }); - if (!Object.is(checked, prev)) { - isDifferent = true; + node.setAttribute(_attributeName, "" + value); } } - if (!shouldAllowUnknownProperties) { - for (const key of Object.keys(newValue)) { - if (!hasOwnProperty$1(config, key)) { - throw new ValidationError(`Unexpected property`, [key]); + return; + } + var mustUseProperty = propertyInfo.mustUseProperty; + if (mustUseProperty) { + var propertyName = propertyInfo.propertyName; + if (value === null) { + var type = propertyInfo.type; + node[propertyName] = type === BOOLEAN ? false : ""; + } else { + node[propertyName] = value; + } + return; + } + var attributeName = propertyInfo.attributeName, attributeNamespace = propertyInfo.attributeNamespace; + if (value === null) { + node.removeAttribute(attributeName); + } else { + var _type = propertyInfo.type; + var attributeValue; + if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) { + attributeValue = ""; + } else { + { + { + checkAttributeStringCoercion(value, attributeName); } + attributeValue = "" + value; } - } - for (const key of Object.keys(knownGoodValue)) { - if (!hasOwnProperty$1(newValue, key)) { - isDifferent = true; - break; + if (propertyInfo.sanitizeURL) { + sanitizeURL(attributeValue.toString()); } } - return isDifferent ? newValue : knownGoodValue; + if (attributeNamespace) { + node.setAttributeNS(attributeNamespace, attributeName, attributeValue); + } else { + node.setAttribute(attributeName, attributeValue); + } + } + } + var REACT_ELEMENT_TYPE = Symbol.for("react.element"); + var REACT_PORTAL_TYPE = Symbol.for("react.portal"); + var REACT_FRAGMENT_TYPE = Symbol.for("react.fragment"); + var REACT_STRICT_MODE_TYPE = Symbol.for("react.strict_mode"); + var REACT_PROFILER_TYPE = Symbol.for("react.profiler"); + var REACT_PROVIDER_TYPE = Symbol.for("react.provider"); + var REACT_CONTEXT_TYPE = Symbol.for("react.context"); + var REACT_FORWARD_REF_TYPE = Symbol.for("react.forward_ref"); + var REACT_SUSPENSE_TYPE = Symbol.for("react.suspense"); + var REACT_SUSPENSE_LIST_TYPE = Symbol.for("react.suspense_list"); + var REACT_MEMO_TYPE = Symbol.for("react.memo"); + var REACT_LAZY_TYPE = Symbol.for("react.lazy"); + var REACT_SCOPE_TYPE = Symbol.for("react.scope"); + var REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for("react.debug_trace_mode"); + var REACT_OFFSCREEN_TYPE = Symbol.for("react.offscreen"); + var REACT_LEGACY_HIDDEN_TYPE = Symbol.for("react.legacy_hidden"); + var REACT_CACHE_TYPE = Symbol.for("react.cache"); + var REACT_TRACING_MARKER_TYPE = Symbol.for("react.tracing_marker"); + var MAYBE_ITERATOR_SYMBOL = Symbol.iterator; + var FAUX_ITERATOR_SYMBOL = "@@iterator"; + function getIteratorFn(maybeIterable) { + if (maybeIterable === null || typeof maybeIterable !== "object") { + return null; } - ); - this.config = config; - this.shouldAllowUnknownProperties = shouldAllowUnknownProperties; - } - allowUnknownProperties() { - return new ObjectValidator(this.config, true); - } - /** - * Extend an object validator by adding additional properties. - * - * @example - * - * ```ts - * const animalValidator = T.object({ - * name: T.string, - * }) - * const catValidator = animalValidator.extend({ - * meowVolume: T.number, - * }) - * ``` - */ - extend(extension) { - return new ObjectValidator({ ...this.config, ...extension }); - } -} -class UnionValidator extends Validator { - constructor(key, config, unknownValueValidation, useNumberKeys) { - super( - (input) => { - this.expectObject(input); - const { matchingSchema, variant } = this.getMatchingSchemaAndVariant(input); - if (matchingSchema === void 0) { - return this.unknownValueValidation(input, variant); + var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]; + if (typeof maybeIterator === "function") { + return maybeIterator; + } + return null; + } + var assign = Object.assign; + var disabledDepth = 0; + var prevLog; + var prevInfo; + var prevWarn; + var prevError; + var prevGroup; + var prevGroupCollapsed; + var prevGroupEnd; + function disabledLog() { + } + disabledLog.__reactDisabledLog = true; + function disableLogs() { + { + if (disabledDepth === 0) { + prevLog = console.log; + prevInfo = console.info; + prevWarn = console.warn; + prevError = console.error; + prevGroup = console.group; + prevGroupCollapsed = console.groupCollapsed; + prevGroupEnd = console.groupEnd; + var props = { + configurable: true, + enumerable: true, + value: disabledLog, + writable: true + }; + Object.defineProperties(console, { + info: props, + log: props, + warn: props, + error: props, + group: props, + groupCollapsed: props, + groupEnd: props + }); } - return prefixError(`(${key} = ${variant})`, () => matchingSchema.validate(input)); - }, - (prevValue, newValue) => { - this.expectObject(newValue); - this.expectObject(prevValue); - const { matchingSchema, variant } = this.getMatchingSchemaAndVariant(newValue); - if (matchingSchema === void 0) { - return this.unknownValueValidation(newValue, variant); + disabledDepth++; + } + } + function reenableLogs() { + { + disabledDepth--; + if (disabledDepth === 0) { + var props = { + configurable: true, + enumerable: true, + writable: true + }; + Object.defineProperties(console, { + log: assign({}, props, { + value: prevLog + }), + info: assign({}, props, { + value: prevInfo + }), + warn: assign({}, props, { + value: prevWarn + }), + error: assign({}, props, { + value: prevError + }), + group: assign({}, props, { + value: prevGroup + }), + groupCollapsed: assign({}, props, { + value: prevGroupCollapsed + }), + groupEnd: assign({}, props, { + value: prevGroupEnd + }) + }); } - if (getOwnProperty(prevValue, key) !== getOwnProperty(newValue, key)) { - return prefixError(`(${key} = ${variant})`, () => matchingSchema.validate(newValue)); + if (disabledDepth < 0) { + error("disabledDepth fell below zero. This is a bug in React. Please file an issue."); } - return prefixError(`(${key} = ${variant})`, () => { - if (matchingSchema.validateUsingKnownGoodVersion) { - return matchingSchema.validateUsingKnownGoodVersion(prevValue, newValue); - } else { - return matchingSchema.validate(newValue); + } + } + var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; + var prefix; + function describeBuiltInComponentFrame(name, source, ownerFn) { + { + if (prefix === void 0) { + try { + throw Error(); + } catch (x2) { + var match2 = x2.stack.trim().match(/\n( *(at )?)/); + prefix = match2 && match2[1] || ""; } - }); + } + return "\n" + prefix + name; } - ); - this.key = key; - this.config = config; - this.unknownValueValidation = unknownValueValidation; - this.useNumberKeys = useNumberKeys; - } - expectObject(value) { - if (typeof value !== "object" || value === null) { - throw new ValidationError(`Expected an object, got ${typeToString(value)}`, []); } - } - getMatchingSchemaAndVariant(object2) { - const variant = getOwnProperty(object2, this.key); - if (!this.useNumberKeys && typeof variant !== "string") { - throw new ValidationError( - `Expected a string for key "${this.key}", got ${typeToString(variant)}` - ); - } else if (this.useNumberKeys && !Number.isFinite(Number(variant))) { - throw new ValidationError(`Expected a number for key "${this.key}", got "${variant}"`); + var reentry = false; + var componentFrameCache; + { + var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map; + componentFrameCache = new PossiblyWeakMap(); } - const matchingSchema = hasOwnProperty$1(this.config, variant) ? this.config[variant] : void 0; - return { matchingSchema, variant }; - } - validateUnknownVariants(unknownValueValidation) { - return new UnionValidator(this.key, this.config, unknownValueValidation, this.useNumberKeys); - } -} -class DictValidator extends Validator { - constructor(keyValidator, valueValidator) { - super( - (object2) => { - if (typeof object2 !== "object" || object2 === null) { - throw new ValidationError(`Expected object, got ${typeToString(object2)}`); + function describeNativeComponentFrame(fn, construct2) { + if (!fn || reentry) { + return ""; + } + { + var frame2 = componentFrameCache.get(fn); + if (frame2 !== void 0) { + return frame2; } - for (const [key, value] of Object.entries(object2)) { - prefixError(key, () => { - keyValidator.validate(key); - valueValidator.validate(value); + } + var control; + reentry = true; + var previousPrepareStackTrace = Error.prepareStackTrace; + Error.prepareStackTrace = void 0; + var previousDispatcher; + { + previousDispatcher = ReactCurrentDispatcher.current; + ReactCurrentDispatcher.current = null; + disableLogs(); + } + try { + if (construct2) { + var Fake = function() { + throw Error(); + }; + Object.defineProperty(Fake.prototype, "props", { + set: function() { + throw Error(); + } }); - } - return object2; - }, - (knownGoodValue, newValue) => { - if (typeof newValue !== "object" || newValue === null) { - throw new ValidationError(`Expected object, got ${typeToString(newValue)}`); - } - let isDifferent = false; - for (const [key, value] of Object.entries(newValue)) { - if (!hasOwnProperty$1(knownGoodValue, key)) { - isDifferent = true; - prefixError(key, () => { - keyValidator.validate(key); - valueValidator.validate(value); - }); - continue; + if (typeof Reflect === "object" && Reflect.construct) { + try { + Reflect.construct(Fake, []); + } catch (x2) { + control = x2; + } + Reflect.construct(fn, [], Fake); + } else { + try { + Fake.call(); + } catch (x2) { + control = x2; + } + fn.call(Fake.prototype); } - const prev = getOwnProperty(knownGoodValue, key); - const next = value; - if (Object.is(prev, next)) { - continue; + } else { + try { + throw Error(); + } catch (x2) { + control = x2; } - const checked = prefixError(key, () => { - if (valueValidator.validateUsingKnownGoodVersion) { - return valueValidator.validateUsingKnownGoodVersion(prev, next); - } else { - return valueValidator.validate(next); + fn(); + } + } catch (sample) { + if (sample && control && typeof sample.stack === "string") { + var sampleLines = sample.stack.split("\n"); + var controlLines = control.stack.split("\n"); + var s2 = sampleLines.length - 1; + var c2 = controlLines.length - 1; + while (s2 >= 1 && c2 >= 0 && sampleLines[s2] !== controlLines[c2]) { + c2--; + } + for (; s2 >= 1 && c2 >= 0; s2--, c2--) { + if (sampleLines[s2] !== controlLines[c2]) { + if (s2 !== 1 || c2 !== 1) { + do { + s2--; + c2--; + if (c2 < 0 || sampleLines[s2] !== controlLines[c2]) { + var _frame = "\n" + sampleLines[s2].replace(" at new ", " at "); + if (fn.displayName && _frame.includes("")) { + _frame = _frame.replace("", fn.displayName); + } + { + if (typeof fn === "function") { + componentFrameCache.set(fn, _frame); + } + } + return _frame; + } + } while (s2 >= 1 && c2 >= 0); + } + break; } - }); - if (!Object.is(checked, prev)) { - isDifferent = true; } } - for (const key of Object.keys(knownGoodValue)) { - if (!hasOwnProperty$1(newValue, key)) { - isDifferent = true; - break; + } finally { + reentry = false; + { + ReactCurrentDispatcher.current = previousDispatcher; + reenableLogs(); + } + Error.prepareStackTrace = previousPrepareStackTrace; + } + var name = fn ? fn.displayName || fn.name : ""; + var syntheticFrame = name ? describeBuiltInComponentFrame(name) : ""; + { + if (typeof fn === "function") { + componentFrameCache.set(fn, syntheticFrame); + } + } + return syntheticFrame; + } + function describeClassComponentFrame(ctor, source, ownerFn) { + { + return describeNativeComponentFrame(ctor, true); + } + } + function describeFunctionComponentFrame(fn, source, ownerFn) { + { + return describeNativeComponentFrame(fn, false); + } + } + function shouldConstruct(Component) { + var prototype = Component.prototype; + return !!(prototype && prototype.isReactComponent); + } + function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) { + if (type == null) { + return ""; + } + if (typeof type === "function") { + { + return describeNativeComponentFrame(type, shouldConstruct(type)); + } + } + if (typeof type === "string") { + return describeBuiltInComponentFrame(type); + } + switch (type) { + case REACT_SUSPENSE_TYPE: + return describeBuiltInComponentFrame("Suspense"); + case REACT_SUSPENSE_LIST_TYPE: + return describeBuiltInComponentFrame("SuspenseList"); + } + if (typeof type === "object") { + switch (type.$$typeof) { + case REACT_FORWARD_REF_TYPE: + return describeFunctionComponentFrame(type.render); + case REACT_MEMO_TYPE: + return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn); + case REACT_LAZY_TYPE: { + var lazyComponent = type; + var payload = lazyComponent._payload; + var init = lazyComponent._init; + try { + return describeUnknownElementTypeFrameInDEV(init(payload), source, ownerFn); + } catch (x2) { + } } } - return isDifferent ? newValue : knownGoodValue; } - ); - this.keyValidator = keyValidator; - this.valueValidator = valueValidator; - } -} -function typeofValidator(type) { - return new Validator((value) => { - if (typeof value !== type) { - throw new ValidationError(`Expected ${type}, got ${typeToString(value)}`); + return ""; } - return value; - }); -} -const any = new Validator((value) => value); -const string = typeofValidator("string"); -const number = typeofValidator("number").check((number2) => { - if (Number.isNaN(number2)) { - throw new ValidationError("Expected a number, got NaN"); - } - if (!Number.isFinite(number2)) { - throw new ValidationError(`Expected a finite number, got ${number2}`); - } -}); -const positiveNumber = number.check((value) => { - if (value < 0) throw new ValidationError(`Expected a positive number, got ${value}`); -}); -const nonZeroNumber = number.check((value) => { - if (value <= 0) throw new ValidationError(`Expected a non-zero positive number, got ${value}`); -}); -const integer = number.check((value) => { - if (!Number.isInteger(value)) throw new ValidationError(`Expected an integer, got ${value}`); -}); -const positiveInteger = integer.check((value) => { - if (value < 0) throw new ValidationError(`Expected a positive integer, got ${value}`); -}); -const nonZeroInteger = integer.check((value) => { - if (value <= 0) throw new ValidationError(`Expected a non-zero positive integer, got ${value}`); -}); -const boolean = typeofValidator("boolean"); -function literal(expectedValue) { - return new Validator((actualValue) => { - if (actualValue !== expectedValue) { - throw new ValidationError(`Expected ${expectedValue}, got ${JSON.stringify(actualValue)}`); + function describeFiber(fiber) { + fiber._debugOwner ? fiber._debugOwner.type : null; + fiber._debugSource; + switch (fiber.tag) { + case HostComponent: + return describeBuiltInComponentFrame(fiber.type); + case LazyComponent: + return describeBuiltInComponentFrame("Lazy"); + case SuspenseComponent: + return describeBuiltInComponentFrame("Suspense"); + case SuspenseListComponent: + return describeBuiltInComponentFrame("SuspenseList"); + case FunctionComponent: + case IndeterminateComponent: + case SimpleMemoComponent: + return describeFunctionComponentFrame(fiber.type); + case ForwardRef: + return describeFunctionComponentFrame(fiber.type.render); + case ClassComponent: + return describeClassComponentFrame(fiber.type); + default: + return ""; + } } - return expectedValue; - }); -} -const array = new Validator((value) => { - if (!Array.isArray(value)) { - throw new ValidationError(`Expected an array, got ${typeToString(value)}`); - } - return value; -}); -function arrayOf(itemValidator) { - return new ArrayOfValidator(itemValidator); -} -function object(config) { - return new ObjectValidator(config); -} -function isPlainObject(value) { - return typeof value === "object" && value !== null && (Object.getPrototypeOf(value) === Object.prototype || Object.getPrototypeOf(value) === null || Object.getPrototypeOf(value) === STRUCTURED_CLONE_OBJECT_PROTOTYPE); -} -function isValidJson(value) { - if (value === null || typeof value === "number" || typeof value === "string" || typeof value === "boolean") { - return true; - } - if (Array.isArray(value)) { - return value.every(isValidJson); - } - if (isPlainObject(value)) { - return Object.values(value).every(isValidJson); - } - return false; -} -const jsonValue = new Validator( - (value) => { - if (isValidJson(value)) { - return value; + function getStackByFiberInDevAndProd(workInProgress2) { + try { + var info = ""; + var node = workInProgress2; + do { + info += describeFiber(node); + node = node.return; + } while (node); + return info; + } catch (x2) { + return "\nError generating stack: " + x2.message + "\n" + x2.stack; + } } - throw new ValidationError(`Expected json serializable value, got ${typeof value}`); - }, - (knownGoodValue, newValue) => { - if (Array.isArray(knownGoodValue) && Array.isArray(newValue)) { - let isDifferent = knownGoodValue.length !== newValue.length; - for (let i2 = 0; i2 < newValue.length; i2++) { - if (i2 >= knownGoodValue.length) { - isDifferent = true; - jsonValue.validate(newValue[i2]); - continue; + function getWrappedName(outerType, innerType, wrapperName) { + var displayName = outerType.displayName; + if (displayName) { + return displayName; + } + var functionName2 = innerType.displayName || innerType.name || ""; + return functionName2 !== "" ? wrapperName + "(" + functionName2 + ")" : wrapperName; + } + function getContextName(type) { + return type.displayName || "Context"; + } + function getComponentNameFromType(type) { + if (type == null) { + return null; + } + { + if (typeof type.tag === "number") { + error("Received an unexpected object in getComponentNameFromType(). This is likely a bug in React. Please file an issue."); + } + } + if (typeof type === "function") { + return type.displayName || type.name || null; + } + if (typeof type === "string") { + return type; + } + switch (type) { + case REACT_FRAGMENT_TYPE: + return "Fragment"; + case REACT_PORTAL_TYPE: + return "Portal"; + case REACT_PROFILER_TYPE: + return "Profiler"; + case REACT_STRICT_MODE_TYPE: + return "StrictMode"; + case REACT_SUSPENSE_TYPE: + return "Suspense"; + case REACT_SUSPENSE_LIST_TYPE: + return "SuspenseList"; + } + if (typeof type === "object") { + switch (type.$$typeof) { + case REACT_CONTEXT_TYPE: + var context = type; + return getContextName(context) + ".Consumer"; + case REACT_PROVIDER_TYPE: + var provider = type; + return getContextName(provider._context) + ".Provider"; + case REACT_FORWARD_REF_TYPE: + return getWrappedName(type, type.render, "ForwardRef"); + case REACT_MEMO_TYPE: + var outerName = type.displayName || null; + if (outerName !== null) { + return outerName; + } + return getComponentNameFromType(type.type) || "Memo"; + case REACT_LAZY_TYPE: { + var lazyComponent = type; + var payload = lazyComponent._payload; + var init = lazyComponent._init; + try { + return getComponentNameFromType(init(payload)); + } catch (x2) { + return null; + } + } } - const prev = knownGoodValue[i2]; - const next = newValue[i2]; - if (Object.is(prev, next)) { - continue; + } + return null; + } + function getWrappedName$1(outerType, innerType, wrapperName) { + var functionName2 = innerType.displayName || innerType.name || ""; + return outerType.displayName || (functionName2 !== "" ? wrapperName + "(" + functionName2 + ")" : wrapperName); + } + function getContextName$1(type) { + return type.displayName || "Context"; + } + function getComponentNameFromFiber(fiber) { + var tag = fiber.tag, type = fiber.type; + switch (tag) { + case CacheComponent: + return "Cache"; + case ContextConsumer: + var context = type; + return getContextName$1(context) + ".Consumer"; + case ContextProvider: + var provider = type; + return getContextName$1(provider._context) + ".Provider"; + case DehydratedFragment: + return "DehydratedFragment"; + case ForwardRef: + return getWrappedName$1(type, type.render, "ForwardRef"); + case Fragment: + return "Fragment"; + case HostComponent: + return type; + case HostPortal: + return "Portal"; + case HostRoot: + return "Root"; + case HostText: + return "Text"; + case LazyComponent: + return getComponentNameFromType(type); + case Mode: + if (type === REACT_STRICT_MODE_TYPE) { + return "StrictMode"; + } + return "Mode"; + case OffscreenComponent: + return "Offscreen"; + case Profiler: + return "Profiler"; + case ScopeComponent: + return "Scope"; + case SuspenseComponent: + return "Suspense"; + case SuspenseListComponent: + return "SuspenseList"; + case TracingMarkerComponent: + return "TracingMarker"; + case ClassComponent: + case FunctionComponent: + case IncompleteClassComponent: + case IndeterminateComponent: + case MemoComponent: + case SimpleMemoComponent: + if (typeof type === "function") { + return type.displayName || type.name || null; + } + if (typeof type === "string") { + return type; + } + break; + } + return null; + } + var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; + var current = null; + var isRendering = false; + function getCurrentFiberOwnerNameInDevOrNull() { + { + if (current === null) { + return null; } - const checked = jsonValue.validateUsingKnownGoodVersion(prev, next); - if (!Object.is(checked, prev)) { - isDifferent = true; + var owner = current._debugOwner; + if (owner !== null && typeof owner !== "undefined") { + return getComponentNameFromFiber(owner); } } - return isDifferent ? newValue : knownGoodValue; - } else if (isPlainObject(knownGoodValue) && isPlainObject(newValue)) { - let isDifferent = false; - for (const key of Object.keys(newValue)) { - if (!hasOwnProperty$1(knownGoodValue, key)) { - isDifferent = true; - jsonValue.validate(newValue[key]); - continue; + return null; + } + function getCurrentFiberStackInDev() { + { + if (current === null) { + return ""; } - const prev = knownGoodValue[key]; - const next = newValue[key]; - if (Object.is(prev, next)) { - continue; + return getStackByFiberInDevAndProd(current); + } + } + function resetCurrentFiber() { + { + ReactDebugCurrentFrame.getCurrentStack = null; + current = null; + isRendering = false; + } + } + function setCurrentFiber(fiber) { + { + ReactDebugCurrentFrame.getCurrentStack = fiber === null ? null : getCurrentFiberStackInDev; + current = fiber; + isRendering = false; + } + } + function getCurrentFiber() { + { + return current; + } + } + function setIsRendering(rendering) { + { + isRendering = rendering; + } + } + function toString3(value) { + return "" + value; + } + function getToStringValue(value) { + switch (typeof value) { + case "boolean": + case "number": + case "string": + case "undefined": + return value; + case "object": + { + checkFormFieldValueStringCoercion(value); + } + return value; + default: + return ""; + } + } + var hasReadOnlyValue = { + button: true, + checkbox: true, + image: true, + hidden: true, + radio: true, + reset: true, + submit: true + }; + function checkControlledValueProps(tagName, props) { + { + if (!(hasReadOnlyValue[props.type] || props.onChange || props.onInput || props.readOnly || props.disabled || props.value == null)) { + error("You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`."); } - const checked = jsonValue.validateUsingKnownGoodVersion(prev, next); - if (!Object.is(checked, prev)) { - isDifferent = true; + if (!(props.onChange || props.readOnly || props.disabled || props.checked == null)) { + error("You provided a `checked` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultChecked`. Otherwise, set either `onChange` or `readOnly`."); } } - for (const key of Object.keys(knownGoodValue)) { - if (!hasOwnProperty$1(newValue, key)) { - isDifferent = true; - break; - } + } + function isCheckable(elem) { + var type = elem.type; + var nodeName = elem.nodeName; + return nodeName && nodeName.toLowerCase() === "input" && (type === "checkbox" || type === "radio"); + } + function getTracker(node) { + return node._valueTracker; + } + function detachTracker(node) { + node._valueTracker = null; + } + function getValueFromNode(node) { + var value = ""; + if (!node) { + return value; } - return isDifferent ? newValue : knownGoodValue; - } else { - return jsonValue.validate(newValue); + if (isCheckable(node)) { + value = node.checked ? "true" : "false"; + } else { + value = node.value; + } + return value; } - } -); -function dict(keyValidator, valueValidator) { - return new DictValidator(keyValidator, valueValidator); -} -function union(key, config) { - return new UnionValidator( - key, - config, - (_unknownValue, unknownVariant) => { - throw new ValidationError( - `Expected one of ${Object.keys(config).map((key2) => JSON.stringify(key2)).join(" or ")}, got ${JSON.stringify(unknownVariant)}`, - [key] - ); - }, - false - ); -} -function numberUnion(key, config) { - return new UnionValidator( - key, - config, - (unknownValue, unknownVariant) => { - throw new ValidationError( - `Expected one of ${Object.keys(config).map((key2) => JSON.stringify(key2)).join(" or ")}, got ${JSON.stringify(unknownVariant)}`, - [key] - ); - }, - true - ); -} -function model(name, validator) { - return new Validator( - (value) => { - return prefixError(name, () => validator.validate(value)); - }, - (prevValue, newValue) => { - return prefixError(name, () => { - if (validator.validateUsingKnownGoodVersion) { - return validator.validateUsingKnownGoodVersion(prevValue, newValue); - } else { - return validator.validate(newValue); + function trackValueOnNode(node) { + var valueField = isCheckable(node) ? "checked" : "value"; + var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField); + { + checkFormFieldValueStringCoercion(node[valueField]); + } + var currentValue = "" + node[valueField]; + if (node.hasOwnProperty(valueField) || typeof descriptor === "undefined" || typeof descriptor.get !== "function" || typeof descriptor.set !== "function") { + return; + } + var get22 = descriptor.get, set22 = descriptor.set; + Object.defineProperty(node, valueField, { + configurable: true, + get: function() { + return get22.call(this); + }, + set: function(value) { + { + checkFormFieldValueStringCoercion(value); + } + currentValue = "" + value; + set22.call(this, value); } }); + Object.defineProperty(node, valueField, { + enumerable: descriptor.enumerable + }); + var tracker = { + getValue: function() { + return currentValue; + }, + setValue: function(value) { + { + checkFormFieldValueStringCoercion(value); + } + currentValue = "" + value; + }, + stopTracking: function() { + detachTracker(node); + delete node[valueField]; + } + }; + return tracker; } - ); -} -function setEnum(values) { - return new Validator((value) => { - if (!values.has(value)) { - const valuesString = Array.from(values, (value2) => JSON.stringify(value2)).join(" or "); - throw new ValidationError(`Expected ${valuesString}, got ${value}`); - } - return value; - }); -} -function optional(validator) { - return new Validator( - (value) => { - if (value === void 0) return void 0; - return validator.validate(value); - }, - (knownGoodValue, newValue) => { - if (knownGoodValue === void 0 && newValue === void 0) return void 0; - if (newValue === void 0) return void 0; - if (validator.validateUsingKnownGoodVersion && knownGoodValue !== void 0) { - return validator.validateUsingKnownGoodVersion(knownGoodValue, newValue); + function track2(node) { + if (getTracker(node)) { + return; } - return validator.validate(newValue); + node._valueTracker = trackValueOnNode(node); } - ); -} -function nullable(validator) { - return new Validator( - (value) => { - if (value === null) return null; - return validator.validate(value); - }, - (knownGoodValue, newValue) => { - if (newValue === null) return null; - if (validator.validateUsingKnownGoodVersion && knownGoodValue !== null) { - return validator.validateUsingKnownGoodVersion(knownGoodValue, newValue); + function updateValueIfChanged(node) { + if (!node) { + return false; } - return validator.validate(newValue); - } - ); -} -function literalEnum(...values) { - return setEnum(new Set(values)); -} -function parseUrl(str) { - try { - return new URL(str); - } catch { - if (str.startsWith("/") || str.startsWith("./")) { - try { - return new URL(str, "http://example.com"); - } catch { - throw new ValidationError(`Expected a valid url, got ${JSON.stringify(str)}`); + var tracker = getTracker(node); + if (!tracker) { + return true; + } + var lastValue = tracker.getValue(); + var nextValue = getValueFromNode(node); + if (nextValue !== lastValue) { + tracker.setValue(nextValue); + return true; } + return false; } - throw new ValidationError(`Expected a valid url, got ${JSON.stringify(str)}`); - } -} -const validLinkProtocols = /* @__PURE__ */ new Set(["http:", "https:", "mailto:"]); -const linkUrl = string.check((value) => { - if (value === "") return; - const url = parseUrl(value); - if (!validLinkProtocols.has(url.protocol.toLowerCase())) { - throw new ValidationError( - `Expected a valid url, got ${JSON.stringify(value)} (invalid protocol)` - ); - } -}); -const validSrcProtocols = /* @__PURE__ */ new Set(["http:", "https:", "data:", "asset:"]); -const srcUrl = string.check((value) => { - if (value === "") return; - const url = parseUrl(value); - if (!validSrcProtocols.has(url.protocol.toLowerCase())) { - throw new ValidationError( - `Expected a valid url, got ${JSON.stringify(value)} (invalid protocol)` - ); - } -}); -string.check((value) => { - if (value === "") return; - const url = parseUrl(value); - if (!url.protocol.toLowerCase().match(/^https?:$/)) { - throw new ValidationError( - `Expected a valid url, got ${JSON.stringify(value)} (invalid protocol)` - ); - } -}); -const indexKey = string.refine((key) => { - try { - validateIndexKey(key); - return key; - } catch { - throw new ValidationError(`Expected an index key, got ${JSON.stringify(key)}`); - } -}); -registerTldrawLibraryVersion( - "@tldraw/validate", - "3.4.1", - "esm" -); -function idValidator(prefix) { - return string.refine((id2) => { - if (!id2.startsWith(`${prefix}:`)) { - throw new Error(`${prefix} ID must start with "${prefix}:"`); + function getActiveElement(doc) { + doc = doc || (typeof document !== "undefined" ? document : void 0); + if (typeof doc === "undefined") { + return null; + } + try { + return doc.activeElement || doc.body; + } catch (e2) { + return doc.body; + } + } + var didWarnValueDefaultValue = false; + var didWarnCheckedDefaultChecked = false; + var didWarnControlledToUncontrolled = false; + var didWarnUncontrolledToControlled = false; + function isControlled(props) { + var usesChecked = props.type === "checkbox" || props.type === "radio"; + return usesChecked ? props.checked != null : props.value != null; + } + function getHostProps(element, props) { + var node = element; + var checked = props.checked; + var hostProps = assign({}, props, { + defaultChecked: void 0, + defaultValue: void 0, + value: void 0, + checked: checked != null ? checked : node._wrapperState.initialChecked + }); + return hostProps; } - return id2; - }); -} -const assetIdValidator = idValidator("asset"); -function createAssetValidator(type, props) { - return object({ - id: assetIdValidator, - typeName: literal("asset"), - type: literal(type), - props, - meta: jsonValue - }); -} -const vecModelValidator = object({ - x: number, - y: number, - z: number.optional() -}); -const boxModelValidator = object({ - x: number, - y: number, - w: number, - h: number -}); -const opacityValidator = number.check((n2) => { - if (n2 < 0 || n2 > 1) { - throw new ValidationError("Opacity must be between 0 and 1"); - } -}); -const parentIdValidator = string.refine((id2) => { - if (!id2.startsWith("page:") && !id2.startsWith("shape:")) { - throw new Error('Parent ID must start with "page:" or "shape:"'); - } - return id2; -}); -const shapeIdValidator = idValidator("shape"); -function createShapeValidator(type, props, meta) { - return object({ - id: shapeIdValidator, - typeName: literal("shape"), - x: number, - y: number, - rotation: number, - index: indexKey, - parentId: parentIdValidator, - type: literal(type), - isLocked: boolean, - opacity: opacityValidator, - props: props ? object(props) : jsonValue, - meta: meta ? object(meta) : jsonValue - }); -} -const bindingIdValidator = idValidator("binding"); -function createBindingValidator(type, props, meta) { - return object({ - id: bindingIdValidator, - typeName: literal("binding"), - type: literal(type), - fromId: shapeIdValidator, - toId: shapeIdValidator, - props: props ? object(props) : jsonValue, - meta: meta ? object(meta) : jsonValue - }); -} -createMigrationIds("com.tldraw.binding", {}); -createRecordMigrationSequence({ - sequenceId: "com.tldraw.binding", - recordType: "binding", - sequence: [] -}); -function createBindingId(id2) { - return `binding:${uniqueId()}`; -} -function createBindingPropsMigrationSequence(migrations) { - return migrations; -} -function createBindingRecordType(bindings) { - return createRecordType("binding", { - scope: "document", - validator: model( - "binding", - union( - "type", - mapObjectMapValues( - bindings, - (type, { props, meta }) => createBindingValidator(type, props, meta) - ) - ) - ) - }).withDefaultProperties(() => ({ - meta: {} - })); -} -class StyleProp { - /** @internal */ - constructor(id2, defaultValue, type) { - this.id = id2; - this.defaultValue = defaultValue; - this.type = type; - } - /** - * Define a new {@link StyleProp}. - * - * @param uniqueId - Each StyleProp must have a unique ID. We recommend you prefix this with - * your app/library name. - * @param options - - * - `defaultValue`: The default value for this style prop. - * - * - `type`: Optionally, describe what type of data you expect for this style prop. - * - * @example - * ```ts - * import {T} from '@tldraw/validate' - * import {StyleProp} from '@tldraw/tlschema' - * - * const MyLineWidthProp = StyleProp.define('myApp:lineWidth', { - * defaultValue: 1, - * type: T.number, - * }) - * ``` - * @public - */ - static define(uniqueId2, options) { - const { defaultValue, type = any } = options; - return new StyleProp(uniqueId2, defaultValue, type); - } - /** - * Define a new {@link StyleProp} as a list of possible values. - * - * @param uniqueId - Each StyleProp must have a unique ID. We recommend you prefix this with - * your app/library name. - * @param options - - * - `defaultValue`: The default value for this style prop. - * - * - `values`: An array of possible values of this style prop. - * - * @example - * ```ts - * import {StyleProp} from '@tldraw/tlschema' - * - * const MySizeProp = StyleProp.defineEnum('myApp:size', { - * defaultValue: 'medium', - * values: ['small', 'medium', 'large'], - * }) - * ``` - */ - static defineEnum(uniqueId2, options) { - const { defaultValue, values } = options; - return new EnumStyleProp(uniqueId2, defaultValue, values); - } - setDefaultValue(value) { - this.defaultValue = value; - } - validate(value) { - return this.type.validate(value); - } - validateUsingKnownGoodVersion(prevValue, newValue) { - if (this.type.validateUsingKnownGoodVersion) { - return this.type.validateUsingKnownGoodVersion(prevValue, newValue); - } else { - return this.validate(newValue); + function initWrapperState(element, props) { + { + checkControlledValueProps("input", props); + if (props.checked !== void 0 && props.defaultChecked !== void 0 && !didWarnCheckedDefaultChecked) { + error("%s contains an input of type %s with both checked and defaultChecked props. Input elements must be either controlled or uncontrolled (specify either the checked prop, or the defaultChecked prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props. More info: https://reactjs.org/link/controlled-components", getCurrentFiberOwnerNameInDevOrNull() || "A component", props.type); + didWarnCheckedDefaultChecked = true; + } + if (props.value !== void 0 && props.defaultValue !== void 0 && !didWarnValueDefaultValue) { + error("%s contains an input of type %s with both value and defaultValue props. Input elements must be either controlled or uncontrolled (specify either the value prop, or the defaultValue prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props. More info: https://reactjs.org/link/controlled-components", getCurrentFiberOwnerNameInDevOrNull() || "A component", props.type); + didWarnValueDefaultValue = true; + } + } + var node = element; + var defaultValue = props.defaultValue == null ? "" : props.defaultValue; + node._wrapperState = { + initialChecked: props.checked != null ? props.checked : props.defaultChecked, + initialValue: getToStringValue(props.value != null ? props.value : defaultValue), + controlled: isControlled(props) + }; } - } -} -class EnumStyleProp extends StyleProp { - /** @internal */ - constructor(id2, defaultValue, values) { - super(id2, defaultValue, literalEnum(...values)); - this.values = values; - } -} -const rootShapeVersions = createMigrationIds("com.tldraw.shape", { - AddIsLocked: 1, - HoistOpacity: 2, - AddMeta: 3, - AddWhite: 4 -}); -const rootShapeMigrations = createRecordMigrationSequence({ - sequenceId: "com.tldraw.shape", - recordType: "shape", - sequence: [ - { - id: rootShapeVersions.AddIsLocked, - up: (record) => { - record.isLocked = false; - }, - down: (record) => { - delete record.isLocked; + function updateChecked(element, props) { + var node = element; + var checked = props.checked; + if (checked != null) { + setValueForProperty(node, "checked", checked, false); } - }, - { - id: rootShapeVersions.HoistOpacity, - up: (record) => { - record.opacity = Number(record.props.opacity ?? "1"); - delete record.props.opacity; - }, - down: (record) => { - const opacity = record.opacity; - delete record.opacity; - record.props.opacity = opacity < 0.175 ? "0.1" : opacity < 0.375 ? "0.25" : opacity < 0.625 ? "0.5" : opacity < 0.875 ? "0.75" : "1"; + } + function updateWrapper(element, props) { + var node = element; + { + var controlled = isControlled(props); + if (!node._wrapperState.controlled && controlled && !didWarnUncontrolledToControlled) { + error("A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components"); + didWarnUncontrolledToControlled = true; + } + if (node._wrapperState.controlled && !controlled && !didWarnControlledToUncontrolled) { + error("A component is changing a controlled input to be uncontrolled. This is likely caused by the value changing from a defined to undefined, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components"); + didWarnControlledToUncontrolled = true; + } + } + updateChecked(element, props); + var value = getToStringValue(props.value); + var type = props.type; + if (value != null) { + if (type === "number") { + if (value === 0 && node.value === "" || // We explicitly want to coerce to number here if possible. + // eslint-disable-next-line + node.value != value) { + node.value = toString3(value); + } + } else if (node.value !== toString3(value)) { + node.value = toString3(value); + } + } else if (type === "submit" || type === "reset") { + node.removeAttribute("value"); + return; } - }, - { - id: rootShapeVersions.AddMeta, - up: (record) => { - record.meta = {}; + { + if (props.hasOwnProperty("value")) { + setDefaultValue(node, props.type, value); + } else if (props.hasOwnProperty("defaultValue")) { + setDefaultValue(node, props.type, getToStringValue(props.defaultValue)); + } } - }, - { - id: rootShapeVersions.AddWhite, - up: (_record) => { - }, - down: (record) => { - if (record.props.color === "white") { - record.props.color = "black"; + { + if (props.checked == null && props.defaultChecked != null) { + node.defaultChecked = !!props.defaultChecked; } } } - ] -}); -function isShape(record) { - if (!record) return false; - return record.typeName === "shape"; -} -function isShapeId(id2) { - if (!id2) return false; - return id2.startsWith("shape:"); -} -function createShapeId(id2) { - return `shape:${id2 ?? uniqueId()}`; -} -function getShapePropKeysByStyle(props) { - const propKeysByStyle = /* @__PURE__ */ new Map(); - for (const [key, prop] of Object.entries(props)) { - if (prop instanceof StyleProp) { - if (propKeysByStyle.has(prop)) { - throw new Error( - `Duplicate style prop ${prop.id}. Each style prop can only be used once within a shape.` - ); + function postMountWrapper(element, props, isHydrating2) { + var node = element; + if (props.hasOwnProperty("value") || props.hasOwnProperty("defaultValue")) { + var type = props.type; + var isButton = type === "submit" || type === "reset"; + if (isButton && (props.value === void 0 || props.value === null)) { + return; + } + var initialValue = toString3(node._wrapperState.initialValue); + if (!isHydrating2) { + { + if (initialValue !== node.value) { + node.value = initialValue; + } + } + } + { + node.defaultValue = initialValue; + } + } + var name = node.name; + if (name !== "") { + node.name = ""; + } + { + node.defaultChecked = !node.defaultChecked; + node.defaultChecked = !!node._wrapperState.initialChecked; + } + if (name !== "") { + node.name = name; } - propKeysByStyle.set(prop, key); } - } - return propKeysByStyle; -} -function createShapePropsMigrationSequence(migrations) { - return migrations; -} -function createShapePropsMigrationIds(shapeType, ids) { - return mapObjectMapValues(ids, (_k2, v2) => `com.tldraw.shape.${shapeType}/${v2}`); -} -function createShapeRecordType(shapes) { - return createRecordType("shape", { - scope: "document", - validator: model( - "shape", - union( - "type", - mapObjectMapValues( - shapes, - (type, { props, meta }) => createShapeValidator(type, props, meta) - ) - ) - ) - }).withDefaultProperties(() => ({ - x: 0, - y: 0, - rotation: 0, - isLocked: false, - opacity: 1, - meta: {} - })); -} -function processPropsMigrations(typeName, records) { - const result = []; - for (const [subType, { migrations }] of Object.entries(records)) { - const sequenceId = `com.tldraw.${typeName}.${subType}`; - if (!migrations) { - result.push( - createMigrationSequence({ - sequenceId, - retroactive: false, - sequence: [] - }) - ); - } else if ("sequenceId" in migrations) { - assert( - sequenceId === migrations.sequenceId, - `sequenceId mismatch for ${subType} ${RecordType} migrations. Expected '${sequenceId}', got '${migrations.sequenceId}'` - ); - result.push(migrations); - } else if ("sequence" in migrations) { - result.push( - createMigrationSequence({ - sequenceId, - retroactive: false, - sequence: migrations.sequence.map( - (m2) => "id" in m2 ? createPropsMigration(typeName, subType, m2) : m2 - ) - }) - ); - } else { - result.push( - createMigrationSequence({ - sequenceId, - retroactive: false, - sequence: Object.keys(migrations.migrators).map((k2) => Number(k2)).sort((a2, b2) => a2 - b2).map( - (version2) => ({ - id: `${sequenceId}/${version2}`, - scope: "record", - filter: (r2) => r2.typeName === typeName && r2.type === subType, - up: (record) => { - const result2 = migrations.migrators[version2].up(record); - if (result2) { - return result2; - } - }, - down: (record) => { - const result2 = migrations.migrators[version2].down(record); - if (result2) { - return result2; - } - } - }) - ) - }) - ); + function restoreControlledState(element, props) { + var node = element; + updateWrapper(node, props); + updateNamedCousins(node, props); } - } - return result; -} -function createPropsMigration(typeName, subType, m2) { - return { - id: m2.id, - dependsOn: m2.dependsOn, - scope: "record", - filter: (r2) => r2.typeName === typeName && r2.type === subType, - up: (record) => { - const result = m2.up(record.props); - if (result) { - record.props = result; + function updateNamedCousins(rootNode, props) { + var name = props.name; + if (props.type === "radio" && name != null) { + var queryRoot = rootNode; + while (queryRoot.parentNode) { + queryRoot = queryRoot.parentNode; + } + { + checkAttributeStringCoercion(name, "name"); + } + var group = queryRoot.querySelectorAll("input[name=" + JSON.stringify("" + name) + '][type="radio"]'); + for (var i2 = 0; i2 < group.length; i2++) { + var otherNode = group[i2]; + if (otherNode === rootNode || otherNode.form !== rootNode.form) { + continue; + } + var otherProps = getFiberCurrentPropsFromNode(otherNode); + if (!otherProps) { + throw new Error("ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported."); + } + updateValueIfChanged(otherNode); + updateWrapper(otherNode, otherProps); + } } - }, - down: typeof m2.down === "function" ? (record) => { - const result = m2.down(record.props); - if (result) { - record.props = result; + } + function setDefaultValue(node, type, value) { + if ( + // Focused number inputs synchronize on blur. See ChangeEventPlugin.js + type !== "number" || getActiveElement(node.ownerDocument) !== node + ) { + if (value == null) { + node.defaultValue = toString3(node._wrapperState.initialValue); + } else if (node.defaultValue !== toString3(value)) { + node.defaultValue = toString3(value); + } } - } : void 0 - }; -} -const defaultColorNames = [ - "black", - "grey", - "light-violet", - "violet", - "blue", - "light-blue", - "yellow", - "orange", - "green", - "light-green", - "light-red", - "red", - "white" -]; -const DefaultColorThemePalette = { - lightMode: { - id: "light", - text: "#000000", - background: "rgb(249, 250, 251)", - solid: "#fcfffe", - black: { - solid: "#1d1d1d", - fill: "#1d1d1d", - note: { - fill: "#FCE19C", - text: "#000000" - }, - semi: "#e8e8e8", - pattern: "#494949", - highlight: { - srgb: "#fddd00", - p3: "color(display-p3 0.972 0.8705 0.05)" + } + var didWarnSelectedSetOnOption = false; + var didWarnInvalidChild = false; + var didWarnInvalidInnerHTML = false; + function validateProps(element, props) { + { + if (props.value == null) { + if (typeof props.children === "object" && props.children !== null) { + React2.Children.forEach(props.children, function(child) { + if (child == null) { + return; + } + if (typeof child === "string" || typeof child === "number") { + return; + } + if (!didWarnInvalidChild) { + didWarnInvalidChild = true; + error("Cannot infer the option value of complex children. Pass a `value` prop or use a plain string as children to